--- title: "Package 'SEMsens'" author: "Walter Leite (University of Florida) & Zuchao Shen (University of Florida)" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Package 'SEMsens'} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- An analysis based on structural equation modeling may suffer from the impact of a potential missing confounder that may change its conclusions (Harring, McNeish, & Hancock, 2017). This package is a tool to evaluate the sensitivity of structural equation models to potential missing confounders using the Ant Colony Optimization (ACO; Colorni, Dorigo, & Maniezzo, 1992; Dorigo & Stützle, 2004; Socha & Dorigo, 2008) algorithm. The reference for the current package is: Leite, W., Shen, Z., Marcoulides, K., Fish, C., & Harring, J. (2022). Using ant colony optimization for sensitivity analysis in structural equation modeling. Structural Equation Modeling: A Multidisciplinary Journal, 29 (1), 47-56. The current version includes three main functions and they are - *gen.sens.pars* function: This function generates a set of required sensitivity parameters according to the rank of object function, with which the method has been developed by Socha & Dorigo (2008). - *sa.aco* function: This function automatically performs the search for an omitted confounder in structural equation modeling using the ACO algorithm - *sens.table* function: This function provides five summary tables of results produced in the *sa.aco* function. Next, we use an example to illustrate how to perform sensitivity analysis in structural equation modeling. ## 1. Function *sa.aco* Given a data set (or variance covariance matrix) and an analytic model, this function searches an omitted confounder to optimize the objective function. *sa.aco* function calls *gen.sens.pars* function to perform the algorithm together. We need the following information/arguments to perform the search - data: The data set used for an analysis. If there is no data available, use covariance matrix instead. - sample.cov: Covariance matrix. - sample.nobs: Number of observations for covariance matrix. - model: The analytic model of interest. - sens.model: Sensitivity analysis model template for structural equation modeling with a phantom variable. This is the model of interest with a phantom variable and sensitivity parameters added. See the example provided. - opt.fun: Customized or preset object function for optimization. - ...... To see more arguments, please run ?sa.aco in R or RStudio. ### An exmaple The example is from: Kim, Y. S. G., & Schatschneider, C. (2017). Expanding the developmental models of writing: A direct and indirect effects model of developmental writing (DIEW). Journal of Educational psychology, 109(1), 35-50. ```{r, message=FALSE, warning=FALSE} # Load lavaan and SEMsens packages require(lavaan) require(SEMsens) set.seed(1) ``` ```{r} # STEP 1: Prepare data: # Lower diagonal correlation matrix in the study by Kim & Schatschneider (2017) lower = ' 1.00 .40 1.00 .40 .64 1.00 .41 .66 .61 1.00 .42 .52 .53 .61 1.00 .34 .50 .46 .53 .48 1.00 .42 .47 .41 .43 .47 .55 1.00 .39 .46 .39 .30 .21 .30 .37 1.00 .24 .31 .30 .31 .26 .32 .27 .56 1.00 .33 .35 .35 .40 .31 .25 .35 .51 .42 1.00 .30 .42 .36 .32 .24 .37 .43 .44 .37 .49 1.00' # Convert to full covariance matrix sample.cov = getCov(lower, sds = c(5.64,14.68,6.57,6.07,3.39,10.16,6.11,4.91,15.59,0.96,0.99), names = c("Working_memory", "Vocabulary", "Grammar", "Inference", "ToM", "TNL", "Expository", "Spelling", "Sentence_copying", "One_day", "Castle")) # STEP 2: Set up analytic model and sensitivity anaysis model # The original analytic model model <-'Vocabulary~Working_memory Grammar~Working_memory Inference~Vocabulary+Grammar+Working_memory ToM~Vocabulary+Grammar+Working_memory Spelling~Working_memory Sentence_copying~Working_memory Discourse~Inference+ToM+Vocabulary+Grammar+Working_memory Writing~Spelling+Sentence_copying+Discourse Discourse=~TNL+Expository Writing=~One_day+Castle Vocabulary~~Grammar Grammar~~Sentence_copying Vocabulary~~Sentence_copying Grammar~~Spelling Vocabulary~~Spelling Inference~~ToM Discourse~~Sentence_copying Discourse~~Spelling Spelling~~Sentence_copying' # A sensitivity analysis model template, which additionally includes paths # from a phantom variable to a set of variables (= number of sensitivity parameters) # in the analytic model. sens.model <- 'Vocabulary~Working_memory Grammar~Working_memory Inference~Vocabulary+Grammar+Working_memory ToM~Vocabulary+Grammar+Working_memory Spelling~Working_memory Sentence_copying~Working_memory Discourse~Inference+ToM+Vocabulary+Grammar+Working_memory Writing~Spelling+Sentence_copying+Discourse Discourse=~TNL+Expository Writing=~One_day+Castle Vocabulary~~Grammar Grammar~~Sentence_copying Vocabulary~~Sentence_copying Grammar~~Spelling Vocabulary~~Spelling Inference~~ToM Discourse~~Sentence_copying Discourse~~Spelling Spelling~~Sentence_copying Working_memory ~ phantom1*phantom Grammar ~ phantom2*phantom Vocabulary ~ phantom3*phantom ToM ~ phantom4*phantom Inference ~ phantom5*phantom Spelling ~ phantom6*phantom Sentence_copying ~ phantom7*phantom Discourse ~ phantom8*phantom Writing ~ phantom9*phantom phantom =~ 0 # added for mean of zero phantom ~~ 1*phantom' # STEP 3: Set up the paths of interest to be evaluated in sensitivity analysis. paths <- 'Vocabulary~Working_memory Grammar~Working_memory Inference~Vocabulary+Grammar+Working_memory ToM~Vocabulary+Grammar+Working_memory Spelling~Working_memory Sentence_copying~Working_memory Discourse~Inference+ToM+Vocabulary+Grammar+Working_memory Writing~Spelling+Sentence_copying+Discourse' # STEP 4: Perform sensitivity analysis. my.sa <-sa.aco(model = model, sens.model = sens.model, sample.cov = sample.cov, sample.nobs = 193, k = 50, max.value= 2000, max.iter = 100, opt.fun = 4, ## from significant to just significant paths = paths, seed = 1, verbose = FALSE) # We set up a max iteration of 100 and solution archive length of 50 for # illustration purpose. Please specify a larger number of iteration (e.g., 1000), # and a larger k (e.g., 100). ``` ## 2. Function *sens.tables* *sens.tables* function can help summarize the sensitivity analysis results. Beyond this function, investigators always can summarize the results by accessing to the results in *sa.aco* function. ```{r} my.table <- sens.tables(my.sa) # Table 1: Summary of the sensitivity analysis for each path my.table[[1]] # Table 2: Summary of the sensitivity parameters my.table[[2]] # Table 3: The sensitivity parameters lead to the minimum coefficient for each my.table[[3]] # Table 4: The sensitivity parameters lead to the maximum coefficient for each path my.table[[4]] # Table 5: The sensitivity parameters lead to change in significance for each path my.table[[5]] ```