use of "update" in lavaan ?

689 views
Skip to first unread message

tpha...@gmail.com

unread,
Jun 22, 2016, 5:00:04 AM6/22/16
to lavaan
Hi, 

Can anyone help me with an example of how the "update" function is used in lavaan, and its syntax? 

I am developing a semi-complex model and am in the process of testing whether inclusion of various regressions among variables improve model fit. It is a bit tedious to repeat the full model code everytime i want to test an inclusion/exclusion, and thought that it may be a possibility to use the "summary/update" function. Hoever, I cannot find any examples of its use anywhere

In glm, the "update" function can be used for easy extension/reduction of the model - is the same possible in lavvan? and what would be the syntax for excluding/including regressions in lavaan?

Many thanks in advance from a beginner :-)

Terrence Jorgensen

unread,
Jun 22, 2016, 6:31:12 AM6/22/16
to lavaan
Can anyone help me with an example of how the "update" function is used in lavaan, and its syntax? ... It is a bit tedious to repeat the full model code everytime i want to test an inclusion/exclusion ... In glm, the "update" function can be used for easy extension/reduction of the model - is the same possible in lavaan?

Unfortunately not.  Because lavaan's model syntax is a character string, not a formula object, you can't use the cool tricks for updating a formula by specifying what to take out or leave in.  But there is a nice shortcut that lavaan's syntax parser allows.  Instead of specifying every parameter in a single character string, you can provide a vector of character strings that lavaanify() concatenates before it parsing it into a parameter table.  So if you have a "Core" model of parameters that will always be specified, you can specify that in one string, then specify a list of all the other additions you might make to that model:

coreModel <- '
  ## important shit
'
addList <- list(model1 = 'add stuff',
                model2 = 'add another
                          set of stuff',
                model3 = 'a third set
                          of additional parameters
                          that may or may not
                          include parameters in the
                          first two sets')

Then you can loop over the list of additional parameters to update the object with new syntax, saving each result in another list:

fit <- lavaan(coreModel, data)
## fit new models 
newFit <- lapply(addList, function(x) update(fit, model.syntax = c(coreModel, x)))
## inspect results for each new model 
sapply(newFit, fitMeasures)
sapply(newFit, coef) 


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

Thure Hauser

unread,
Jun 22, 2016, 11:26:55 AM6/22/16
to lav...@googlegroups.com
Thanks a lot, will try it out :-)

--
You received this message because you are subscribed to a topic in the Google Groups "lavaan" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/lavaan/thKIUdEjssw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to lavaan+un...@googlegroups.com.
To post to this group, send email to lav...@googlegroups.com.
Visit this group at https://groups.google.com/group/lavaan.
For more options, visit https://groups.google.com/d/optout.

tpha...@gmail.com

unread,
Jun 23, 2016, 2:11:20 AM6/23/16
to lavaan
Dear Terrence or others , 

I can't get your code to work - here it is with my own variables and dataset

> coreModel <- '
+ AcSympt=~a*Ac11.TN
+ AcSympt=~b*Ac12.TN
+ AcSympt=~c*Ac24.TN
+ #
+ AcSympt ~ d*AcS3.TN
+ '
> addList <- list(model1 =  'MineSympt =~ e*Mine11.TN 
+                 MineSympt =~ f*Mine22.TN 
+                 MineSympt ~ g*PnS.TN
+                 ',
+                 model2 = 'HulSympt=~h*Hul11.TN 
+                 HulSympt =~ i*Hul12.TN 
+                 HulSympt =~ j*Hul13.TN 
+                 HulSympt ~ k*PnS.TN
+                 ')
> fit <- sem(coreModel, data=modelData)
> newFit <- lapply(addList, function(x) update(fit, model.syntax = c(coreModel, x)))
 
 Error in lavaan::lavaan(model = coreModel, data = modelData, model.type = "sem",  : 
  unused argument (model.syntax = ..1)



Any idea what goes wrong? 

Many many thanks for your help in advance :-)

Thure

Terrence Jorgensen

unread,
Jun 23, 2016, 4:29:07 AM6/23/16
to lavaan
> newFit <- lapply(addList, function(x) update(fit, model.syntax = c(coreModel, x)))
 
 Error in lavaan::lavaan(model = coreModel, data = modelData, model.type = "sem",  : 
  unused argument (model.syntax = ..1)

Yeah, I get the same error message.  The help page class?lavaan says the argument is model.syntax, but the lavaan functions all have model as their first argument.  I wonder if the help page is mistaken or there is a bug.  But when you call that argument model in the update() function, this reproducible example works:

coreModel <- '
  visual  =~ x1 + x2 + x3
  textual =~ x4 + x5 + x6
  speed   =~ x7 + x8 + x9
'
addList <- list(model1 = 'x1~~x4',
                model2 = 'x1~~x7',
                model3 = 'x1~~x4 ; x4~~x7')

fit <- cfa(coreModel, data=HolzingerSwineford1939)
newFit <- lapply(addList, function(x) update(fit, model = c(coreModel, x)))

Yves Rosseel

unread,
Jul 11, 2016, 7:58:48 AM7/11/16
to lav...@googlegroups.com
> Yeah, I get the same error message. The help pageclass?lavaan says the
> argument ismodel.syntax, but the lavaan functions all have model as their
> first argument. I wonder if the help page is mistaken

Indeed. It should be 'model'. (model.syntax was the old argument name).
I will fix the man page.

Yves.

John Williams

unread,
Nov 15, 2016, 9:33:56 PM11/15/16
to lavaan
You could ignore the update method entirely, and just use string manipulation functions to change the model specification, which is just a string. So, for example if you want to drop a term just search for it and replace with nothing. Say you have "LV ~ MV1 + MV2 + MV3", just use (for example) model_string <- stringr::str_replace(model_string, " \\+ MV2", "")

Thure Hauser

unread,
Nov 21, 2016, 9:03:46 AM11/21/16
to lav...@googlegroups.com
Thanks a lot for the suggestion, John. So something like this: 

> mstr<- "LV ~ MV1 + MV2 + MV3"
> mstr
[1] "LV ~ MV1 + MV2 + MV3"
> mstr2 <- stringr::str_replace(mstr, "\\+ MV2", "")
> mstr2
[1] "LV ~ MV1  + MV3"
> mstr3<- "+ MV4"
> mstr4 <- paste(mstr2, mstr3)
> mstr4
[1] "LV ~ MV1  + MV3 + MV4"


Or is there a simpler way to add a variable to the string?

Thure



--
You received this message because you are subscribed to a topic in the Google Groups "lavaan" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/lavaan/thKIUdEjssw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to lavaan+unsubscribe@googlegroups.com.

kma...@aol.com

unread,
Nov 21, 2016, 10:27:46 PM11/21/16
to lavaan, thure....@gmail.com
Thure,
Editing model syntax strings seems to be the more popular approach on this list.  However, in my view it is much simpler and less error prone to instead edit the parameter table and fit the model using the parameter table in place of the model syntax.


mstr<- "LV ~ MV1 + MV2 + MV3"
mstr
mptbl <- lavaanify(mstr)
mptbl
mptbl$rhs[2] <- 'MV4'
mptbl

Keith
---------------------------
Keith A. Markus
John Jay College of Criminal Justice, CUNY
http://jjcweb.jjay.cuny.edu/kmarkus
Frontiers of Test Validity Theory: Measurement, Causation and Meaning.
http://www.routledge.com/books/details/9781841692203/


Thure Hauser

unread,
Nov 22, 2016, 5:52:10 AM11/22/16
to lav...@googlegroups.com
Thanks, Keith, 

With the parameter table, how do you add or delete variables from the model? Your example replaces one right-hand-side value for another, but doesn't change all the places the variable is included in the model... so it seems to be more complex than working with the text string ?

Thure

kma...@aol.com

unread,
Nov 22, 2016, 10:52:27 PM11/22/16
to lavaan, thure....@gmail.com
Thure,
There are probably prettier ways to accomplish some of these but here is one way.  Note that lavaan does not require all the columns.  So, you can simplify by deleting unnecessary columns rather than editing them.  However, here I illustrate with all columns intact.


mstr<- "LV ~ MV1 + MV2 + MV3"
mstr
mptbl <- lavaanify(mstr, auto.var=TRUE)
mptbl

# Swap MV4 for MV2
mptbl2 <- mptbl
mptbl2[mptbl=='MV2'] <- 'MV4'
mptbl2

# Remove MV2
mptbl3 <- mptbl[!(mptbl$lhs=='MV2' | mptbl$rhs=='MV2'),]
mptbl3

# Add MV2 back
mptbl4 <- mptbl3[c(1,1,2,3,4,4,5,5,5,6),]
mptbl4$lhs <- rep(c('LV',paste0('MV',1:3)), times=4:1) # perhaps a bit heavy handed given unecessary replacements
mptbl4$rhs <- c('LV',paste0('MV',1:3))[c(2,3,4,1,2,3,4,3,4,4)]
mptbl4$id <- as.integer(1:10)
mptbl4$plabel <- paste0('.p',1:10,'.')
mptbl4$free[2] <- 2
mptbl4
mptbl==mptbl4 #check against original

None of these are typical use cases for me.  I more typically want to change parameter start values or free status within a fixed model structure drawing values from another R object.

Keith

Thure Hauser

unread,
Nov 23, 2016, 2:46:11 AM11/23/16
to lav...@googlegroups.com
Thanks a lot, will try it out :-)

Thure

Yves Rosseel

unread,
Nov 23, 2016, 3:00:42 AM11/23/16
to lav...@googlegroups.com
Perhaps this is good place to mention this:

If you specify a model by providing a parameter table, you do not need
(any longer, since 0.5-20?) to provide the 'full' parameter table,
containing all the columns. In particular, there is no need to provide
the 'id' and 'plabel' column.

In fact, the only required columns are 'lhs', 'op' and 'rhs'. In this
case, all parameters are considered free. If some are non-free, then you
must provide a free column, where 0 indicates fixed, and 1 (or any other
non-zero value) indicates free.

If a parameter is fixed, we assume it is fixed to zero. If you need to
fix a parameter to another value (say, 1), then you need to also add the
'ustart' column, which usually contains NA values, except for those
non-free parameters that are fixed to a non-zero constant.

Internally, lavaan uses the (public) function lav_partable_complete(),
to add the 'remaining' columns (which may change over versions).

Yves.

On 11/23/2016 08:46 AM, Thure Hauser wrote:
> Thanks a lot, will try it out :-)
>
> Thure
>
> On 23 November 2016 at 04:52, kmarkus via lavaan
> <https://groups.google.com/d/topic/lavaan/thKIUdEjssw/unsubscribe>.
> To unsubscribe from this group and all its topics, send an email to
> lavaan+un...@googlegroups.com
> <mailto:lavaan+un...@googlegroups.com>.
> To post to this group, send email to lav...@googlegroups.com
> <mailto:lav...@googlegroups.com>.
> <https://groups.google.com/group/lavaan>.
> For more options, visit https://groups.google.com/d/optout
> <https://groups.google.com/d/optout>.
>
>
> --
> 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
> <mailto:lavaan+un...@googlegroups.com>.
> To post to this group, send email to lav...@googlegroups.com
> <mailto:lav...@googlegroups.com>.
Reply all
Reply to author
Forward
0 new messages