Any work-around for inability to get "casewise" residuals in lavaan?

548 views
Skip to first unread message

janetmor...@gmail.com

unread,
Jul 26, 2016, 4:33:28 PM7/26/16
to lavaan
Hi all,

Currently, lavaan will not provide casewise residuals from residuals(,"casewise") for an sem that does not have latent variables (see open issue #44).
Instead, it returns values of 0 in all cases. Until this capability is added, does anyone have a way to work-around the problem?
I want to make a dataframe of the sem residuals, and would do it like this if "casewise" worked:

ModelFit <- sem(Model, data=DATA1, meanstructure = T)
ModelRes <- as.data.frame(residuals(ModelFit, "casewise"))

Many thanks for your help!

Janet Morrison


Terrence Jorgensen

unread,
Jul 29, 2016, 4:11:26 AM7/29/16
to lavaan
Currently, lavaan will not provide casewise residuals from residuals(,"casewise") for an sem that does not have latent variables (see open issue #44). Until this capability is added, does anyone have a way to work-around the problem?

So this is just a path analysis?  Then you can just calculate residuals manually the way you would for regression models (assuming you didn't use R's convenience functions for an lm() object).  A casewise residual for person i is the difference between that person's observed and predicted values.  To calculate predicted values for a multivariate regression, just save the matrix of predictor variables and the matrix of regression coefficients, then calculate the predicted values by matrix multiplication and subtract them from the observed values.  For example, if your model is X -> M -> Y, then the outcomes are M and Y, and the predictors are X and M.

predictors <- c("X","M")
outcomes <- c("M","Y")
X <- as.matrix(DATA1[predictors])
X <- cbind(intercept = 1,  X)
Y <- as.matrix(DATA1[outcomes])
B <- lavInspect(ModelFit, "coef")$beta[outcomes, predictors]
int <- lavInspect(ModelFit, "coef")$alpha[outcomes, "intercept"]
B <- t(cbind(intercept = int, B))
Y.hat <- X %*% B # regression equation
E <- Y - Y.hat   # casewise residuals

If you want them back in your data.frame...
 
DATA1$M.resid <- E[ , "M"]
DATA1$Y.resid <- E[ , "Y"]

Terrence D. Jorgensen
Postdoctoral Researcher, Methods and Statistics
Research Institute for Child Development and Education, the University of Amsterdam

Myriam

unread,
Jul 27, 2020, 11:16:04 AM7/27/20
to lavaan

Hello, 

 

Thank you for this! I also performed a path analysis in lavaan based on observed variables. This code was exactly what I needed to calculate my casewise model residuals! 

 

It seems that the following adaptation to my data and model was successful. I was able to run it and obtained a residual data matrix. (Note to other beginners like me: I had to make sure that all my variables were as.numeric. I also created a subset data frame with only my model variables and in the exact order in which they appear below - but maybe that was overkill).

 

I have two questions to obtain additional information through this procedure.

Would it be possible to know how to adapt the syntax to obtain standardized residuals? 

Also, is there a way to obtain Cook values through this easy procedure? I am not really familiar with matrix algebra and I only recently started using R and lavaan.

 

Here is the adapted code:

 

In my model, I have 2 exogenous variables, 3 mediators, and 2 outcomes (1 is binary, so I used WLSMV).  So: X1, X2, M1, M2, M3, Y1, Y2

 

predictors <- c("X1", "X2","M1", "M2", "M3")

outcomes <- c("M1", "M2", "M3","Y1", "Y2")

X <- as.matrix(mydata[predictors])

X <- cbind(intercept = 1,  X)

Y <- as.matrix(mydata[outcomes])

B <- lavInspect(mymodelfit, "coef")$beta[outcomes, predictors]

int <- lavInspect(mymodelfit, "coef")$alpha[outcomes, "intercept"]

B <- t(cbind(intercept = int, B))

Y.hat <- X %*% B # regression equation

E <- Y - Y.hat   # casewise residuals

 

Thank you again!

Myriam



Myriam

unread,
Jul 27, 2020, 11:41:04 AM7/27/20
to lavaan
Update on my previous post: 

I realized that obtaining standardized residuals was just a matter of basic stats : (Residuals - Mean of residuals)/SD of residuals. Here is my code for other beginners like me. (Now that I think about it, I could have used a standardize function.)

#inputing residuals back into data frame

mydata$M1.resid <- E[ , "M1"]


#standardizing residuals

mydata$M1.zres <- as.numeric(

              (mydata$M1.resid-mean(mydata$M1.resid))

                /sd(mydata$M1.resid))


Remaining question:
I am still wondering if there is a way to obtain Cook's distance. 

I will look back at my stat textbooks, but if someone has an easy way to obtain them, I would be super grateful.

Thank you!
Myriam

Patrick (Malone Quantitative)

unread,
Jul 27, 2020, 12:04:08 PM7/27/20
to lav...@googlegroups.com
Just a thought--for casewise residuals, wouldn't the SD of the original data make more sense for standardizing?

--
You received this message because you are subscribed to the Google Groups "lavaan" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lavaan+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/lavaan/a951aa54-0345-4654-8f3b-b8c244bda55fo%40googlegroups.com.


--
Patrick S. Malone, Ph.D., Malone Quantitative
NEW Service Models: http://malonequantitative.com

He/Him/His
Reply all
Reply to author
Forward
0 new messages