Skip to contents

A generic interface for parametric and non-parametric bootstrap procedures for structural equation models estimated with the modsem ecosystem. The function dispatches on the class of model; currently dedicated methods exist for modsem_pi (product‑indicator approach) and modsem_da (distributional‑analytic approach).

Usage

bootstrap_modsem(model = modsem, FUN, ...)

# S3 method for class 'modsem_pi'
bootstrap_modsem(model, FUN, ...)

# S3 method for class 'modsem_da'
bootstrap_modsem(
  model,
  FUN = "coef",
  R = 1000L,
  P.max = 1e+05,
  type = c("nonparametric", "parameteric"),
  verbose = interactive(),
  calc.se = FALSE,
  optimize = FALSE,
  ...
)

# S3 method for class '`function`'
bootstrap_modsem(
  model = modsem,
  FUN = "coef",
  data,
  R = 1000L,
  verbose = interactive(),
  FUN.args = list(),
  ...
)

Arguments

model

A fitted modsem object, or a function to be bootstrapped (e.g., modsem, modsem_da and modsem_pi)

FUN

A function that returns the statistic of interest when applied to a fitted model. The function must accept a single argument, the model object, and should ideally return a numeric vector; see Value.

...

Additional arguments forwarded to lavaan::bootstrapLavaan for modsem_pi objects, or modsem_da for modsem_da objects.

R

number of bootstrap replicates.

P.max

ceiling for the simulated population size.

type

Bootstrap flavour, see Details.

verbose

Should progress information be printed to the console?

calc.se

Should standard errors for each replicate. Defaults to FALSE.

optimize

Should starting values be re-optimized for each replicate. Defaults to FALSE.

data

Dataset to be resampled.

FUN.args

Arguments passed to FUN

Value

Depending on the return type of FUN either

numeric

A matrix with R rows (bootstrap replicates) and as many columns as length(FUN(model)).

other

A list of length R; each element is the raw output of FUN. NOTE: Only applies for modsem_da objects

Details

A thin wrapper around lavaan::bootstrapLavaan() that performs the necessary book‑keeping so that FUN receives a fully‑featured modsem_pi object—rather than a bare lavaan fit—at every iteration.

The function internally resamples the observed data (non-parametric case) or simulates from the estimated parameter table (parametric case), feeds the sample to modsem_da, evaluates FUN on the refitted object and finally collates the results.

This is a more general version of boostrap_modsem for bootstrapping modsem functions, not modsem objects. model is now a function to be boostrapped, and ... are now passed to the function (model), not FUN. To pass arguments to FUN use FUN.args.

Methods (by class)

  • bootstrap_modsem(modsem_pi): Bootstrap a modsem_pi model by delegating to bootstrapLavaan.

  • bootstrap_modsem(modsem_da): Parametric or non-parametric bootstrap for modsem_da models.

  • bootstrap_modsem(`function`): Non-parametric bootstrap of modsem functions

Examples


m1 <- '
  X =~ x1 + x2
  Z =~ z1 + z2
  Y =~ y1 + y2

  Y ~ X + Z + X:Z
'

fit_pi <- modsem(m1, oneInt)
bootstrap_modsem(fit_pi, FUN = coef, R = 10L)
#>           X=~x2     Z=~z2     Y=~y2       Y~X       Y~Z      Y~XZ  XZ=~x2z1
#>  [1,] 0.8884237 0.8262879 0.7797705 0.7407114 0.5918870 0.6707317 0.8246330
#>  [2,] 0.8347994 0.8233353 0.8025760 0.6824978 0.6016801 0.6865373 0.8116811
#>  [3,] 0.8206546 0.8518766 0.8007877 0.6971329 0.5362172 0.6820370 0.8238181
#>  [4,] 0.8189006 0.8113157 0.8325491 0.6869278 0.5782950 0.7256083 0.7789803
#>  [5,] 0.7947128 0.8558326 0.7924540 0.7333650 0.6106507 0.7282757 0.8221329
#>  [6,] 0.8254009 0.8749817 0.7929519 0.6579637 0.6131392 0.7361599 0.8396432
#>  [7,] 0.8332576 0.7692559 0.8131625 0.7067837 0.5708261 0.7091723 0.8355242
#>  [8,] 0.8619048 0.8171167 0.7882294 0.7320317 0.6299300 0.7734579 0.8497304
#>  [9,] 0.8272198 0.8581544 0.8065377 0.7420436 0.5475846 0.7715898 0.7902094
#> [10,] 0.8325728 0.8515355 0.8051629 0.6431409 0.6255022 0.7367125 0.8150739
#>        XZ=~x1z2  XZ=~x2z2 x1z1~~x1z2 x1z1~~x2z1 x1z2~~x2z2 x2z1~~x2z2    x1~~x1
#>  [1,] 0.7706057 0.6378158  0.1321030 0.12470048 0.13859185  0.1236854 0.2695500
#>  [2,] 0.7620211 0.6213905  0.1510716 0.08864615 0.15350198  0.1165963 0.2064331
#>  [3,] 0.8140617 0.6704431  0.1392288 0.12953526 0.12479679  0.1391153 0.2037414
#>  [4,] 0.7923717 0.6249382  0.1028956 0.14624920 0.13305408  0.1534371 0.2024947
#>  [5,] 0.8138680 0.6766186  0.1016855 0.17156133 0.13094839  0.1542808 0.1466010
#>  [6,] 0.7600386 0.6436328  0.1071415 0.07537641 0.17072580  0.1236519 0.1713316
#>  [7,] 0.7848949 0.6607577  0.1366991 0.11834861 0.13430508  0.1109281 0.2181188
#>  [8,] 0.8331755 0.7173464  0.1227065 0.15731268 0.08557116  0.1282096 0.2078369
#>  [9,] 0.8248556 0.6578495  0.1125763 0.16228584 0.10511858  0.1216584 0.2034808
#> [10,] 0.8145436 0.6751385  0.1228619 0.15560824 0.12230915  0.1129503 0.1708143
#>          x2~~x2    z1~~z1    z2~~z2    y1~~y1    y2~~y2 x1z1~~x1z1 x2z1~~x2z1
#>  [1,] 0.1068363 0.2120969 0.1364207 0.1522135 0.1715433  0.3467576  0.2808781
#>  [2,] 0.1326718 0.1849395 0.1475439 0.1745294 0.1382708  0.3035680  0.2380796
#>  [3,] 0.1548883 0.1971554 0.1424606 0.1466531 0.1517053  0.3601218  0.2922566
#>  [4,] 0.1458213 0.1939336 0.1492024 0.1856174 0.1279031  0.3284856  0.3442310
#>  [5,] 0.1768187 0.2159352 0.1325914 0.1723244 0.1427089  0.3648349  0.3440650
#>  [6,] 0.1504944 0.2341332 0.1190925 0.1613587 0.1484900  0.2417272  0.2421190
#>  [7,] 0.1401831 0.1358201 0.1775705 0.1744732 0.1359542  0.3335131  0.2663161
#>  [8,] 0.1369614 0.2094457 0.1333073 0.1566526 0.1512443  0.3620863  0.3218547
#>  [9,] 0.1455015 0.2406770 0.1118286 0.2188779 0.1184675  0.3601850  0.3186712
#> [10,] 0.1532201 0.2130209 0.1350956 0.1946312 0.1367605  0.3495799  0.2831961
#>       x1z2~~x1z2 x2z2~~x2z2      X~~X      Z~~Z      Y~~Y    XZ~~XZ      X~~Z
#>  [1,]  0.3058370  0.2433937 0.9250376 0.9509946 1.0404153 0.9839416 0.1510574
#>  [2,]  0.3521438  0.2414933 0.9325914 1.0209942 0.9759887 1.1139648 0.1684377
#>  [3,]  0.3048880  0.2515079 0.9511693 0.9631768 0.9344947 1.1739524 0.1752234
#>  [4,]  0.2790108  0.2581793 0.9726406 1.0246144 0.9579877 1.1140874 0.1988152
#>  [5,]  0.2749447  0.2623786 1.0739408 0.9043633 0.9671002 0.9805299 0.1828608
#>  [6,]  0.3181851  0.2738636 0.9577705 0.9431554 0.9825834 1.0354563 0.1617813
#>  [7,]  0.3089064  0.2212350 0.8914256 1.0704986 0.9203757 0.9886425 0.1810837
#>  [8,]  0.2373762  0.1982495 0.8862861 1.0080460 0.9482141 0.8543592 0.2248769
#>  [9,]  0.2559218  0.2049166 0.9444809 0.9177360 0.9206756 0.9224049 0.1949300
#> [10,]  0.2906092  0.2260151 0.9269864 0.9611296 0.9645808 0.8736839 0.1970902
#>               X~~XZ      Z~~XZ
#>  [1,]  0.0045452923 0.06431493
#>  [2,] -0.0094172460 0.08608002
#>  [3,]  0.0412521613 0.13538289
#>  [4,] -0.0004327796 0.06455298
#>  [5,] -0.0391503620 0.04776190
#>  [6,]  0.0258802984 0.03401701
#>  [7,]  0.0028456548 0.05461465
#>  [8,]  0.0450855234 0.02570986
#>  [9,] -0.0242799280 0.04269811
#> [10,]  0.0395353338 0.04479171
#> attr(,"error.idx")
#> integer(0)
#> attr(,"nonadmissible")
#> integer(0)
#> attr(,"seed")
#> [1] 80750137


m1 <- '
  X =~ x1 + x2
  Z =~ z1 + z2
  Y =~ y1 + y2

  Y ~ X + Z + X:Z
'

# \dontrun{
fit_lms <- modsem(m1, oneInt, method = "lms")
bootstrap_modsem(fit_lms, FUN = coef, R = 10L)
#>           X=~x2     Z=~z2     Y=~y2     x1~1     x2~1      z1~1     z2~1
#>  [1,] 0.8144249 0.7994558 0.8106055 1.005050 1.208416 0.9601928 1.168434
#>  [2,] 0.8306618 0.8110611 0.8213023 1.077158 1.277789 1.0247542 1.200896
#>  [3,] 0.8411607 0.7972488 0.8095984 1.013350 1.206820 1.0068561 1.196302
#>  [4,] 0.8191819 0.8223422 0.8043713 1.014464 1.217126 1.0274982 1.221347
#>  [5,] 0.8011285 0.8277382 0.8095597 1.025258 1.219122 0.9861196 1.175388
#>  [6,] 0.8372476 0.8234276 0.8009580 1.004623 1.207068 1.0231868 1.218734
#>  [7,] 0.8122819 0.8009942 0.8140702 1.035939 1.228986 1.0025992 1.198659
#>  [8,] 0.8045314 0.7979068 0.8106893 1.046972 1.211095 0.9939626 1.212647
#>  [9,] 0.8055473 0.8456199 0.8017031 1.028694 1.226362 1.0127911 1.214436
#> [10,] 0.8061172 0.7877519 0.8109209 1.023713 1.218222 1.0122960 1.217087
#>            y1~1     y2~1    x1~~x1    x2~~x2    z1~~z1    z2~~z2    y1~~y1
#>  [1,] 0.9662349 1.159700 0.1789629 0.1396592 0.1693207 0.1540739 0.1973072
#>  [2,] 1.0668095 1.262117 0.1729039 0.1387757 0.1809208 0.1425726 0.2013929
#>  [3,] 1.0491994 1.227669 0.1944130 0.1300357 0.1562650 0.1580442 0.1853396
#>  [4,] 1.0685017 1.248043 0.1668592 0.1415672 0.1662921 0.1502297 0.1882442
#>  [5,] 1.0197621 1.208855 0.1595008 0.1521806 0.1821325 0.1523385 0.1896113
#>  [6,] 0.9945248 1.189701 0.1984813 0.1467717 0.1709734 0.1434117 0.1892290
#>  [7,] 1.0245044 1.201537 0.1655852 0.1523672 0.1585768 0.1625813 0.1793059
#>  [8,] 1.0631284 1.237800 0.1936810 0.1342058 0.1665919 0.1675431 0.2023190
#>  [9,] 1.0516512 1.234766 0.1761351 0.1558178 0.1800263 0.1431118 0.1806793
#> [10,] 1.0207796 1.201399 0.1564162 0.1631285 0.1551158 0.1531997 0.2128208
#>          y2~~y2      X~~X      X~~Z      Z~~Z      Y~~Y       Y~X       Y~Z
#>  [1,] 0.1451890 0.9903107 0.2199216 1.0517475 0.9875343 0.6443155 0.5405837
#>  [2,] 0.1330980 0.9294362 0.1841670 1.0740669 0.9077634 0.7407449 0.5662418
#>  [3,] 0.1310587 0.9244601 0.1959024 1.0873494 0.9554678 0.6641158 0.5610568
#>  [4,] 0.1336907 0.9683357 0.1974863 0.9777329 0.9537110 0.6623360 0.6202128
#>  [5,] 0.1346769 0.9632715 0.2142341 1.0401253 0.9412764 0.6207919 0.5884689
#>  [6,] 0.1425606 0.9218639 0.1639074 0.9894723 0.9250406 0.6770013 0.5763097
#>  [7,] 0.1349305 0.9799755 0.2209489 1.0331289 0.9255412 0.6396911 0.5747478
#>  [8,] 0.1234008 0.9786263 0.2422323 1.0435471 0.9970825 0.6748976 0.5782958
#>  [9,] 0.1445198 0.9671834 0.2444986 1.0410502 0.9124814 0.6250333 0.6097863
#> [10,] 0.1174835 1.0174541 0.2237963 1.0503501 0.9801075 0.6446188 0.5908044
#>           Y~X:Z
#>  [1,] 0.7504803
#>  [2,] 0.7323244
#>  [3,] 0.7465220
#>  [4,] 0.7605423
#>  [5,] 0.7708292
#>  [6,] 0.7081364
#>  [7,] 0.7297743
#>  [8,] 0.7173830
#>  [9,] 0.7245055
#> [10,] 0.6588931
# }

tpb <- "
# Outer Model (Based on Hagger et al., 2007)
  ATT =~ att1 + att2 + att3 + att4 + att5
  SN =~ sn1 + sn2
  PBC =~ pbc1 + pbc2 + pbc3
  INT =~ int1 + int2 + int3
  BEH =~ b1 + b2

# Inner Model (Based on Steinmetz et al., 2011)
  INT ~ ATT + SN + PBC
  BEH ~ INT + PBC + INT:PBC
"

# \dontrun{
boot <- bootstrap_modsem(model = modsem,
                         model.syntax = tpb, data = TPB,
                         method = "dblcent", rcs = TRUE,
                         rcs.scale.corrected = TRUE,
                         FUN = "coef", R = 50L)
coef <- apply(boot, MARGIN = 2, FUN = mean, na.rm = TRUE)
se   <- apply(boot, MARGIN = 2, FUN = sd, na.rm = TRUE)

cat("Parameter Estimates:\n")
#> Parameter Estimates:
print(coef)
#>        INT~ATT         INT~SN        INT~PBC        BEH~INT        BEH~PBC 
#>     0.21064177     0.17371320     0.21826009     0.19047476     0.22884408 
#>     BEH~INTPBC       ATT~~ATT         SN~~SN       PBC~~PBC       INT~~INT 
#>     0.20029927     1.00077490     0.98767221     0.95575485     0.48684160 
#>       BEH~~BEH INTPBC~~INTPBC        ATT~~SN       ATT~~PBC    ATT~~INTPBC 
#>     0.45493022     0.98187014     0.62834518     0.67576214     0.08174600 
#>        SN~~PBC     SN~~INTPBC    PBC~~INTPBC 
#>     0.67174267     0.05357099     0.08065211 

cat("Standard Errors: \n")
#> Standard Errors: 
print(se)
#>        INT~ATT         INT~SN        INT~PBC        BEH~INT        BEH~PBC 
#>     0.02179516     0.02874696     0.03060897     0.02590732     0.01933352 
#>     BEH~INTPBC       ATT~~ATT         SN~~SN       PBC~~PBC       INT~~INT 
#>     0.02245272     0.03847476     0.04044220     0.03699584     0.01935323 
#>       BEH~~BEH INTPBC~~INTPBC        ATT~~SN       ATT~~PBC    ATT~~INTPBC 
#>     0.02626266     0.07504883     0.02947911     0.02879307     0.03194062 
#>        SN~~PBC     SN~~INTPBC    PBC~~INTPBC 
#>     0.03039619     0.03055908     0.03852186 

# }