In general, the PLS-SEM framework and the pls() function assume that the model is fully standardized (i.e., all observed and latent variables have zero mean and unit variance). However, it is possible to get unstandardized estimates for your models using a post-estimation procedure. This can be done either by using the unstandardized_estimates() function or by passing unstandardized = TRUE to the summary() function. Here is an example using summary().

m <- '
  X =~ x1 + x2 + x3
  Z =~ z1 + z2 + z3
  Y =~ y1 + y2 + y3

  Y ~ X + Z + X:Z + X:X
'

fit <- pls(m, modsem::oneInt, bootstrap = TRUE, boot.R = 100)
summary(fit, unstandardized = TRUE)
#> plssem (0.1.3) ended normally after 3 iterations
#>   Estimator                                       PLSc
#>   Link                                          LINEAR
#>                                                       
#>   Number of observations                          2000
#>   Number of iterations                               3
#>   Number of latent variables                         3
#>   Number of observed variables                       9
#> 
#> Fit Measures:
#>   Chi-Square                                    56.757
#>   Degrees of Freedom                                24
#>   SRMR                                           0.006
#>   RMSEA                                          0.026
#> 
#> R-squared (indicators):
#>   x1                                             0.863
#>   x2                                             0.819
#>   x3                                             0.809
#>   z1                                             0.830
#>   z2                                             0.827
#>   z3                                             0.843
#>   y1                                             0.934
#>   y2                                             0.919
#>   y3                                             0.923
#> 
#> R-squared (latents):
#>   Y                                              0.604
#> 
#> Latent Variables:
#>                  Estimate  Std.Error  z.value  P(>|z|)   Unstd
#>   X =~          
#>     x1              0.929      0.012   74.998    0.000   1.000
#>     x2              0.905      0.014   64.498    0.000   0.814
#>     x3              0.899      0.014   62.912    0.000   0.900
#>   Z =~          
#>     z1              0.911      0.011   81.213    0.000   1.000
#>     z2              0.909      0.015   62.449    0.000   0.835
#>     z3              0.918      0.013   70.602    0.000   0.902
#>   Y =~          
#>     y1              0.966      0.006  164.717    0.000   1.000
#>     y2              0.959      0.007  128.299    0.000   0.804
#>     y3              0.961      0.007  143.274    0.000   0.901
#> 
#> Regressions:
#>                  Estimate  Std.Error  z.value  P(>|z|)   Unstd
#>   Y ~           
#>     X               0.423      0.018   23.128    0.000   0.670
#>     Z               0.361      0.017   21.144    0.000   0.572
#>     X:Z             0.454      0.020   23.065    0.000   0.726
#>     X:X            -0.005      0.018   -0.293    0.769  -0.008
#> 
#> Covariances:
#>                  Estimate  Std.Error  z.value  P(>|z|)   Unstd
#>   X ~~          
#>     Z               0.201      0.024    8.446    0.000   0.197
#>     X:Z             0.018      0.038    0.479    0.632   0.018
#>     X:X             0.030      0.075    0.399    0.690   0.029
#>   Z ~~          
#>     X:Z             0.060      0.046    1.315    0.189   0.059
#>     X:X             0.018      0.038    0.479    0.632   0.018
#>   X:Z ~~        
#>     X:X             0.372      0.064    5.812    0.000   0.360
#> 
#> Variances:
#>                  Estimate  Std.Error  z.value  P(>|z|)   Unstd
#>     X               1.000      0.025   40.602    0.000   0.985
#>     Z               1.000      0.034   29.823    0.000   0.983
#>    .Y               0.396      0.016   24.101    0.000   0.980
#>     X:Z             1.013      0.068   14.818    0.000   0.980
#>     X:X             1.740      0.172   10.129    0.000   1.687
#>    .x1              0.137      0.023    5.969    0.000   0.157
#>    .x2              0.181      0.025    7.120    0.000   0.144
#>    .x3              0.191      0.026    7.432    0.000   0.188
#>    .z1              0.170      0.021    8.313    0.000   0.202
#>    .z2              0.173      0.026    6.535    0.000   0.143
#>    .z3              0.157      0.024    6.564    0.000   0.149
#>    .y1              0.066      0.011    5.829    0.000   0.175
#>    .y2              0.081      0.014    5.677    0.000   0.141
#>    .y3              0.077      0.013    5.999    0.000   0.168

To get more detailed results, including standard errors, we can use the unstandardized_estimates() function directly.

unstandardized_estimates(fit)
#>    lhs op rhs    est    se      z pvalue ci.lower ci.upper
#> 1    X =~  x1  1.000    NA     NA     NA       NA       NA
#> 2    X =~  x2  0.814 0.020 41.424  0.000    0.776    0.853
#> 3    X =~  x3  0.900 0.022 41.468  0.000    0.857    0.943
#> 4    Z =~  z1  1.000    NA     NA     NA       NA       NA
#> 5    Z =~  z2  0.835 0.020 42.562  0.000    0.796    0.873
#> 6    Z =~  z3  0.902 0.019 46.359  0.000    0.864    0.940
#> 7    Y =~  y1  1.000    NA     NA     NA       NA       NA
#> 8    Y =~  y2  0.804 0.009 87.075  0.000    0.786    0.822
#> 9    Y =~  y3  0.901 0.010 94.096  0.000    0.882    0.920
#> 10   Y  ~   X  0.670 0.031 21.953  0.000    0.610    0.730
#> 11   Y  ~   Z  0.572 0.028 20.429  0.000    0.517    0.627
#> 12   Y  ~ X:Z  0.726 0.037 19.778  0.000    0.654    0.798
#> 13   Y  ~ X:X -0.008 0.029 -0.293  0.769   -0.064    0.048
#> 14   X ~~   X  0.985 0.038 25.710  0.000    0.910    1.060
#> 15   X ~~   Z  0.197 0.024  8.222  0.000    0.150    0.244
#> 16   X ~~ X:Z  0.018 0.037  0.480  0.632   -0.054    0.090
#> 17   X ~~ X:X  0.029 0.073  0.400  0.689   -0.113    0.172
#> 18   Z ~~   Z  0.983 0.044 22.401  0.000    0.897    1.069
#> 19   Z ~~ X:Z  0.059 0.045  1.306  0.192   -0.029    0.147
#> 20   Z ~~ X:X  0.018 0.037  0.480  0.632   -0.054    0.090
#> 21   Y ~~   Y  0.980 0.042 23.131  0.000    0.897    1.063
#> 22 X:Z ~~ X:Z  0.980 0.075 13.040  0.000    0.833    1.128
#> 23 X:Z ~~ X:X  0.360 0.063  5.765  0.000    0.238    0.483
#> 24 X:X ~~ X:X  1.687 0.193  8.754  0.000    1.309    2.065
#> 25  x1 ~~  x1  0.157 0.026  5.969  0.000    0.105    0.208
#> 26  x2 ~~  x2  0.144 0.020  7.120  0.000    0.105    0.184
#> 27  x3 ~~  x3  0.188 0.025  7.432  0.000    0.139    0.238
#> 28  z1 ~~  z1  0.202 0.024  8.313  0.000    0.154    0.250
#> 29  z2 ~~  z2  0.143 0.022  6.535  0.000    0.100    0.186
#> 30  z3 ~~  z3  0.149 0.023  6.564  0.000    0.105    0.194
#> 31  y1 ~~  y1  0.175 0.030  5.829  0.000    0.116    0.234
#> 32  y2 ~~  y2  0.141 0.025  5.677  0.000    0.092    0.190
#> 33  y3 ~~  y3  0.168 0.028  5.999  0.000    0.113    0.223

It is also possible to pass a vector of variable names, detailing which variables should be unstandardized. The rules for different variables are as follows:

  • Observed Continuous Variables are rescaled to their original standard deviations in the input data.
  • Latent Variables get rescaled by fixing their first factor loadings to 1.
  • Composite Variables are rescaled by fixing their first weight to 1.
  • Observed Ordinal Variables have their residual variance constrained to 1. If they do not have a residual variance (e.g., if they belong to a composite), they remain standardized.

Note that the observed and latent variables can be standardized separately. This has implications for latent variables. Since we unstandardize latent/composite variables by fixing the first loading/weight to 1, their scale is inherited from the first indicator. That means that we will get a different result depending on whether the first indicator gets unstandardized or not.

Here, for example, we can see that we get different results if we do not unstandardize x1 when unstandardizing X.

# x1 is unstandardized
subset(
  unstandardized_estimates(fit, unstandardized = c("x1", "X")),
  lhs == "X" | rhs == "X"
)
#>    lhs op rhs   est    se      z pvalue ci.lower ci.upper
#> 1    X =~  x1 1.000    NA     NA     NA       NA       NA
#> 2    X =~  x2 0.912 0.022 41.424  0.000    0.869    0.955
#> 3    X =~  x3 0.906 0.022 41.468  0.000    0.864    0.949
#> 10   Y  ~   X 0.426 0.019 22.104  0.000    0.388    0.464
#> 14   X ~~   X 0.985 0.038 25.710  0.000    0.910    1.060
#> 15   X ~~   Z 0.199 0.024  8.297  0.000    0.152    0.246
#> 16   X ~~ X:Z 0.018 0.037  0.480  0.632   -0.055    0.090
#> 17   X ~~ X:X 0.029 0.073  0.400  0.689   -0.113    0.172

# x1 is standardized
subset(
  unstandardized_estimates(fit, unstandardized = "X"),
  lhs == "X" | rhs == "X"
)
#>    lhs op rhs   est    se      z pvalue ci.lower ci.upper
#> 1    X =~  x1 1.000    NA     NA     NA       NA       NA
#> 2    X =~  x2 0.974 0.024 41.424  0.000    0.928    1.020
#> 3    X =~  x3 0.968 0.023 41.468  0.000    0.923    1.014
#> 10   Y  ~   X 0.455 0.021 22.104  0.000    0.415    0.495
#> 14   X ~~   X 0.863 0.034 25.710  0.000    0.797    0.928
#> 15   X ~~   Z 0.186 0.022  8.297  0.000    0.142    0.230
#> 16   X ~~ X:Z 0.016 0.032  0.480  0.632   -0.048    0.079
#> 17   X ~~ X:X 0.024 0.060  0.400  0.689   -0.093    0.141