## ----setup, include=FALSE----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- knitr::opts_chunk$set( warning = FALSE, message = FALSE, tidy = FALSE, # figuren: leesbaar + responsive fig.width = 8, fig.height = 5, dpi = 150, fig.retina = 2, fig.align = "center", out.width = "100%", out.extra = 'style="height:auto;"' ) options(width = 200) ## ----results='hide', message=FALSE, warning=FALSE----------------------------------------------------------------------------------------------------------------------------------------------------- # To install restriktor in R: #if (!require("restriktor")) install.packages("restriktor") library(restriktor) # print docs in the help-tab to view arguments and explanations for the function #?goric # To install lavaan in R: # if (!require("lavaan")) install.packages("lavaan") library(lavaan) ## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # specify the model, using own labeling HS.model <- ' visual =~ lambda_v1*x1 + lambda_v2*x2 + lambda_v3*x3 textual =~ lambda_t1*x4 + lambda_t2*x5 + lambda_t3*x6 speed =~ lambda_s1*x7 + lambda_s2*x8 + lambda_s3*x9 ' ## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # Hypotheses H1_cfa <- ' abs(lambda_v1) > .6; abs(lambda_v2) > .6; abs(lambda_v3) > .6; abs(lambda_t1) > .6; abs(lambda_t2) > .6; abs(lambda_t3) > .6; abs(lambda_s1) > .6; abs(lambda_s2) > .6; abs(lambda_s3) > .6; ' # vs its complement (default) ## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # fit the model # fixing the variances of all the latent variables in a CFA model to unity (std.lv = TRUE; https://www.lavaan.ugent.be/tutorial/syntax2.html) fit_cfa <- cfa(HS.model, data = HolzingerSwineford1939, std.lv = TRUE) ## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # Calculate GORICA values and weights for H1_cfa and its complement. set.seed(100) # Needed for reproducibility & sensitivity check results_cfa <- goric(fit_cfa, hypotheses = list(H1_cfa = H1_cfa), standardized = TRUE) #summary(results_cfa) results_cfa ## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # specify the model HS.model_mgcfa <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 ' # configural invariance fit_ci <- cfa(HS.model_mgcfa, data = HolzingerSwineford1939, group = "school") # weak invariance fit_wi <- cfa(HS.model_mgcfa, data = HolzingerSwineford1939, group = "school", group.equal = "loadings") # strong invariance fit_si <- cfa(HS.model_mgcfa, data = HolzingerSwineford1939, group = "school", group.equal = c("intercepts", "loadings")) # strict invariance fit_strict <- cfa(HS.model_mgcfa, data = HolzingerSwineford1939, group = "school", group.equal = c("intercepts", "loadings", "residuals")) # model comparison with AIC AIC_meas.invar <- lavTestLRT(fit_ci, fit_wi, fit_si, fit_strict)$AIC hypo.names <- c("configural", "weak", "strong", "strict") AIC_weights <- calc_ICweights(AIC_meas.invar, hypo.names) #print(AIC_weights, use_scientific = FALSE, digits = 3) AIC_weights$ratio_IC_weights AIC_weights$ratio_IC_weights["weak",] ## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # specify the model, using own labeling (per group!) # Specify model, such that we obtain the latent means (and not differences w.r.t. a reference category). HS.model_mgcfa <- ' visual =~ x1 + x2 + x3 textual =~ x4 + x5 + x6 speed =~ x7 + x8 + x9 # latent variable intercepts; here: # the latent means visual ~ c(mean_v_P, mean_v_GW) * 1 textual ~ c(mean_t_P, mean_t_GW) * 1 speed ~ c(mean_s_P, mean_s_GW) * 1 ' # where below we ensure: # intercepts equal across groups $ # loadings equal across groups: # group.equal = c("intercepts", "loadings") # and # first intercept equal to 0: # marker.int.zero = TRUE # Hypotheses H1_mgcfa <- " abs(mean_v_P) > abs(mean_v_GW); abs(mean_t_P) > abs(mean_t_GW); abs(mean_s_P) > abs(mean_s_GW) " # vs its complement (default) # fit the model fit_mgcfa <- cfa(HS.model_mgcfa, data = HolzingerSwineford1939, group = "school", group.equal = c("intercepts", "loadings"), marker.int.zero = TRUE) # Calculate GORICA values and weights set.seed(100) # Needed for reproducibility & sensitivity check results_mgcfa <- goric(fit_mgcfa, hypotheses = list(H1_mgcfa = H1_mgcfa)) results_mgcfa # # # Alternative: # # In the case you want to extract the estimates and their covariance matrix yourself and use that as input for the goric function: # # # # Extract estimates and their covariance matrix # names_param <- c("mean_v_P", "mean_v_GW", "mean_t_P", "mean_t_GW", "mean_s_P", "mean_s_GW") # est <- coef(fit_mgcfa)[names_param] # VCOV <- vcov(fit_mgcfa)[names_param, names_param] # # # # Calculate GORICA values and weights # set.seed(100) # Needed for reproducibility & sensitivity check # results_mgcfa <- goric(est, VCOV = VCOV, # hypotheses = list(H1_mgcfa = H1_mgcfa)) # # # GORICA values and weights # #summary(results_mgcfa) # results_mgcfa ## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # specify the model, using own labeling model_sem <- ' # measurement model ind60 =~ x1 + x2 + x3 dem60 =~ y1 + y2 + y3 + y4 dem65 =~ y5 + y6 + y7 + y8 # regressions dem60 ~ ind60 dem65 ~ beta_dem65_ind60*ind60 + beta_dem65_dem60*dem60 # residual correlations y1 ~~ y5 y2 ~~ y4 + y6 y3 ~~ y7 y4 ~~ y8 y6 ~~ y8 ' # Hypotheses H1_sem <- " abs(beta_dem65_dem60) > abs(beta_dem65_ind60) " # vs its complement (default) # fit the model fit_sem <- sem(model_sem, data = PoliticalDemocracy) # Calculate GORICA values and weights set.seed(100) # Needed for reproducibility & sensitivity check results_sem <- goric(fit_sem, hypotheses = list(H1_sem = H1_sem), standardized = TRUE) #summary(results_sem) results_sem # Unrestricted & Order-restricted parameter estimates of interest # Note: Hypotheses should be specified before seeing the data. # Looking afterwards at the standardized estimates can give you more insight. # # Unrestricted parameter estimates of interest subset(standardizedSolution(fit_sem), op == "~" & lhs == "dem65") # # Order-restricted parameter estimates of interest; # that is, the estimates of interest under the restrictions in the hypotheses: results_sem$ormle ## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # specify the model, using own labeling model_msem <- ' level: 1 fw =~ y1 + y2 + y3 fw ~ beta_x1*x1 + beta_x2*x2 + beta_x3*x3 level: 2 fb =~ y1 + y2 + y3 fb ~ w1 + w2 ' # Hypotheses H1_msem <- " abs(beta_x1) > abs(beta_x2) > abs(beta_x3) " # vs its complement (default) # fit the model fit_msem <- sem(model = model_msem, data = Demo.twolevel, cluster = "cluster") # Calculate GORICA values and weights set.seed(100) # Needed for reproducibility & sensitivity check results_msem <- goric(fit_msem, hypotheses = list(H1_msem = H1_msem), standardized = TRUE) #summary(results_msem) results_msem ## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # specify the model, using own labeling # a linear growth model with a time-varying covariate model_growth <- ' # intercept and slope with fixed coefficients i =~ 1*t1 + 1*t2 + 1*t3 + 1*t4 s =~ 0*t1 + 1*t2 + 2*t3 + 3*t4 # regressions i ~ x1 + x2 s ~ s_1*x1 + s_2*x2 # time-varying covariates t1 ~ c1 t2 ~ c2 t3 ~ c3 t4 ~ c4 ## Extra: Label intercepts #i ~ intercept_i * 1 #s ~ intercept_s * 1 ' # Hypotheses H1_growth <- " abs(s_2) > abs(s_1) " # vs its complement (default) # fit the model fit_growth <- growth(model_growth, data = Demo.growth) # Calculate GORICA values and weights set.seed(100) # Needed for reproducibility & sensitivity check results_growth <- goric(fit_growth, hypotheses = list(H1_growth = H1_growth), standardized = TRUE) #summary(results_growth) results_growth ## ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- # Create data set.seed(1234) X <- rnorm(100) M <- 0.5*X + rnorm(100) Y <- 0.7*M + rnorm(100) Data <- data.frame(X = X, Y = Y, M = M) # specify the model, using own labeling model_med <- ' # direct effect Y ~ c*X # mediator M ~ a*X Y ~ b*M # indirect effect (a*b) indirect := a*b # direct effect (c) # Optional direct := c # Could leave this out and use c ' # Hypotheses H_part <- "abs(indirect) > 0.1; abs(direct) > 0.1" H_full <- "abs(indirect) > 0.1; -0.1 < direct < 0.1" # and unconstrained as failsafe (default) # fit the model fit_med <- sem(model_med, data = Data) #summary(fit_med, standardized = TRUE) # Calculate GORICA values and weights: # # 1. based on the object set.seed(100) # Needed for reproducibility & sensitivity check results_med <- goric(fit_med, hypotheses = list(H_part = H_part, H_full = H_full), standardized = TRUE) ## ----echo = TRUE, eval = TRUE------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #summary(results_med) results_med # # # Alternative: # # 2. based on extracted estimates # # Extract standardized estimates of the defined parameters and their covariance matrix # label_names <- c("direct", "indirect") # est <- as.vector(standardizedSolution(fit_med)['est.std'])$est.std # names(est) <- standardizedSolution(fit_med)$label # est <- est[label_names] # #est # VCOV <- lavInspect(fit_med, "vcov.def.std.all")[label_names, label_names] # # VCOV # covariance matrix of parameter estimates # # # # GORICA # set.seed(123) # for reproducibility & possibly sensitivity check # results_med <- goric(est, VCOV = VCOV, # hypotheses = list(H_part = H_part, H_full = H_full)) # #summary(results_med) # results_med