Search code examples
rloopserror-handlingwarningsr-lavaan

How to tryCatch in R cfa of lavaan library (and inspect errors, but get variable)?


I do simulation research and create different datasets for different CFA models. During a series of simulations, I would like to handle errors resulting from e.g. randomization. Specifically - I would like to be able to repeat the sampling procedure in the case of lavaan::cfa errors, but in the case of just warnings, I would only mark them in the output data.

Additionally - the lavaan error breaks the loop, while the warning does not break the loop.

Unfortunately, the "normal" tryCatch procedure (probably) deletes the created variable in both cases, and returns NULL on also warnings. Please, look at my code:

# I do a simple procedure that just inherites lavaan:cfa
my_fit_function <- function(input_model,input_frame){
    tryCatch(
        {
        my_fit <- cfa(input_model, data=input_frame)
        return(my_fit)
        # and here should be some info about warnings
        }, warning = function(warning_condition) {
            message("warning; do i have output variable?:")
            message(exists("my_fit"))
            message(warning_condition)
        }, error=function(error_message) {
            message("error; do i have output variable?:")
            message(exists("my_fit"))
            message(error_message)
        }
    )
}

While execution on dataset that ends with a lavaan warning on the original procedure gives:

fit <- cfa(model, data=df)
(...) lavaan WARNING: covariance matrix of latent variables (...)
exists("fit")
> TRUE

I got my variable and everything seems OK, BUT when i use my procedure i got something like this:

fit <- my_fit_function(model, df)
> warning; do i have output variable?:
> FALSE
> 0
fit
> NULL

so the original function itself rather executes, but at the tryCatch level my_fit returns NULL to me.

What am I doing wrong, or I don't understand? I would be grateful for the tip.

EDIT: if someone want to replicate exact this mine problem with lavaan warning, heres the initial code:

library(simstudy)
model <- "f1 =~ q1 + q4 + q7 + q10\nf2 =~ q2 + q5 + q8\nf3 =~ q3 + q6 + q9"
mu<-rep(0,10)
df = genCorGen(1000, nvars = 10, params1 = mu, params2 = (mu+1), dist = "uniform", rho = .9, corstr = "cs", wide = TRUE)
df = as.data.frame(df[,-1])
colnames(df) <- do.call('paste0',expand.grid("q", c(1:10)))
my_fit <- cfa(model, data=df)
> lavaan WARNING: covariance matrix of latent variables

Note that not every simulation like this gives you warning, some of random models allow to fit data without warnings, you ned to paste this code several times.

What makes the problem is just an Heywood Case Example (mean correaltion around .9 and three factors): model is possible to execute (gives estimates and procedure ends with proper variable), but lavaan gives you warning about this possibility of model misspecification.


Solution

  • OK, to be honest, i'm still confused why lavaan object is making a mess with standard tryCatch function, but i found some solution ispired by code here

    The function that works for me goes like this:

    my_fit_function <- function(input_model,input_frame){
                       tryCatch(my_fit <-cfa(input_model, data=input_frame),
                       error = function(e) { 
                       cat(paste("Lavaan model not secified correctly -",e,sep="\n")) 
                       return(NULL) } )     
    }
    

    This results a NULL only when i got real error with data or model specification, at errors it still makes an model. Unfortunately, I cannot detect any warnings in this procedure, only an error. Hence, I cannot mark apart error OR warning in the output. But at least I don't have any bugs in functions preventing loop development - this form does not close the loop with error-break.

    Maybe it will be useful to someone.