Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

parcel allocation for higher order models

136 views
Skip to first unread message

Anna-Lena Jobmann

unread,
Mar 3, 2025, 1:27:54 PMMar 3
to lavaan
Hello, 

I'm trying to use parcel.allocate (semTools) for a higher order model (six first order factors, three correlated second order factors, with each two first order factors loading on each second order factor). 

Is there a way to estimate the model with parcel.allocate? I did not find any information on that question.

Parcel.allocate works when I only specify the (correlated) first order factor - unfortuonately that is theoretically not the best model for my data.

Thank you!
Lena

Terrence Jorgensen

unread,
Mar 3, 2025, 3:38:04 PMMar 3
to lavaan
I'm trying to use parcel.allocate (semTools)

parcelAllocation()

Please provide a reprex to demonstrate the problem.

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

Anna-Lena Jobmann

unread,
Mar 4, 2025, 6:54:18 AMMar 4
to lavaan
My Reprex:

This works fine: 
## Fit 2-factor CFA to simulated data. Each factor has 9 indicators.

## Specify the item-level model (if NO parcels were created)
item.syntax <- c(paste0("f1 =~ f1item", 1:9),
                 paste0("f2 =~ f2item", 1:9)
                 paste0("f3 =~ f3item", 1:9)
                 paste0("f4 =~ f4item", 1:9)
                 paste0("f5 =~ f5item", 1:9)
                 paste0("f6 =~ f6item", 1:9))
cat(item.syntax, sep = "\n")
## Below, we reduce the size of this same model by
## applying different parceling schemes


## 3-indicator parcels
mod.parcels <- '
f1 =~ par1 + par2 + par3
f2 =~ par4 + par5 + par6
f3 =~ par7 + par8 + par9
f4 =~ par10 + par11 + par12
f5 =~ par13 + par14 + par15
f6 =~ par16 + par17 + par18'

## names of parcels
(parcel.names <- paste0("par", 1:18))

## Not run:
## override default random-number generator to use parallel options
RNGkind("L'Ecuyer-CMRG")

parcelAllocation(mod.parcels, data = simParcel, nAlloc = 100,
                 parcel.names = parcel.names, item.syntax = item.syntax,
                 std.lv = TRUE,       # any addition lavaan arguments
                 parallel = "snow")   # parallel options

But I'm trying to use parcelAllocation for the following model:
mod.parcels <- '
f1 =~ par1 + par2 + par3
f2 =~ par4 + par5 + par6
f3 =~ par7 + par8 + par9
f4 =~ par10 + par11 + par12
f5 =~ par13 + par14 + par15
f6 =~ par16 + par17 + par18
hO1 =~ f1 + f2
hO2 =~ f3 + f4
hO3 =~ f5 + f6'

It does not work, the error message says (for my data): 'model' and 'item.syntax' arguments specify different factors.
'model' specifies: AG, DF, GR, hO1, hO2, hO3, KL, LW, TX 'item.syntax' specifies: AG, DF, GR, KL, LW, TX

Using only lavaan (without parcelAllocation) works fine.

Thank you very much. 

Terrence Jorgensen

unread,
Mar 4, 2025, 7:04:00 AMMar 4
to lavaan

My Reprex:

This is not a reproducible example.  An error occurs due to a missing comma almost right away:

> ## Fit 2-factor CFA to simulated data. Each factor has 9 indicators.
>
> ## Specify the item-level model (if NO parcels were created)
> item.syntax <- c(paste0("f1 =~ f1item", 1:9),
+                  paste0("f2 =~ f2item", 1:9)
+                  paste0("f3 =~ f3item", 1:9)

Error: unexpected symbol in:

"                 paste0("f2 =~ f2item", 1:9)
                 paste0"



But your error message tells you the problem:

'model' and 'item.syntax' arguments specify different factors.
'model'       specifies: AG, DF, GR, hO1, hO2, hO3, KL, LW, TX 
'item.syntax' specifies: AG, DF, GR,                KL, LW, TX

The only difference between the item.syntax= and parcel level model= should be that some indicators in the former are used to create parcels in the latter.  So if you add the h01-3 factors to item.syntax=, it should work fine.

If you want to just create a set of random parcel allocations, then fit different models to the same allocations, then you can set the argument do.fit=FALSE to save the list of data sets.

Anna-Lena Jobmann

unread,
Mar 4, 2025, 11:12:17 AMMar 4
to lavaan

Sorry for my mistake and thank you for your help! To provide a reproducible example, I added a higher order factor to the example from the function (see below). I also tried to add the factors to the item.syntax (as I understood it), but it still does not work. The error message says:

lavaan->lav_lavaan_step01_ovnames_checklv(): 

   some latent variable names collide with observed variable names: f1 f2

What did I do wrong?

Thank you for your advice using the data sets; that will help (and I will use it if necessary), but I would rather try to use the more comfortable function ParcelAllocation.

library(lavaan)

library(semTools)

## Specify the item-level model (if NO parcels were created)

item.syntax <- c(paste0("f1 =~ f1item", 1:9),

                 paste0("f2 =~ f2item", 1:9),

                 paste0("f3 =~ f1"),

                 paste0("f3 =~ f2"))

cat(item.syntax, sep = "\n")

## Below, we reduce the size of this same model by

## applying different parceling schemes

 

 

## 3-indicator parcels

mod.parcels <- '

f1 =~ par1 + par2 + par3

f2 =~ par4 + par5 + par6

f3 =~ f1 + f2

'

## names of parcels

(parcel.names <- paste0("par", 1:6))

 

## Not run:

## override default random-number generator to use parallel options

RNGkind("L'Ecuyer-CMRG")

 

parcelAllocation(mod.parcels, data = simParcel, nAlloc = 100,

                 parcel.names = parcel.names, item.syntax = item.syntax,

                 std.lv = TRUE,       # any addition lavaan arguments

                 parallel = "snow")   # parallel options


Anna-Lena Jobmann

unread,
Mar 4, 2025, 11:12:18 AMMar 4
to lavaan
Sorry for the mistake and thank you for your help. To make it reproducable, I used the code from the example and added a higher order factor:

library(lavaan)
library(semTools)

## Specify the item-level model (if NO parcels were created)
item.syntax <- c(paste0("f1 =~ f1item", 1:9),
                 paste0("f2 =~ f2item", 1:9),
                 paste0("f3 =~ f1"),
                 paste0("f3 =~ f2"))
cat(item.syntax, sep = "\n")
## Below, we reduce the size of this same model by
## applying different parceling schemes


## 3-indicator parcels
mod.parcels <- '
f1 =~ par1 + par2 + par3
f2 =~ par4 + par5 + par6
f3 =~ f1 + f2
'
## names of parcels
(parcel.names <- paste0("par", 1:6))

I've tried what you said (or what I understod you said, see above), but it does not work. What did I do wrong? Error says:  error: lavaan->lav_lavaan_step01_ovnames_checklv(): some latent variable names collide with observed variable names: f1 f2

Thank you for the alternative though; that might help to fit my model to each randomly drawn parcel set...

Lena
Terrence Jorgensen schrieb am Dienstag, 4. März 2025 um 13:04:00 UTC+1:

Terrence Jorgensen

unread,
Mar 5, 2025, 4:45:25 AMMar 5
to lavaan
What did I do wrong? Error says:  error: lavaan->lav_lavaan_step01_ovnames_checklv(): some latent variable names collide with observed variable names: f1 f2

Hmm, it seems I didn't plan for higher-order factors.  Early in the function, the syntax objects are parsed into parameter tables, to match observed-variable names and parcel names that measure the same factor.  I updated the syntax to remove any latent-variable names (i.e., variables ever appearing on the left-hand side of the =~ operator) from either list.  This should suffice to:
  1. distinguish parcels from latent variables on the right-hand side of the =~ operator 
  2. only create parcels from observed variables.
You can install the updated semTools from GitHub:

remotes::install_github("simsem/semTools/semTools")


After which, this reprex works fine:

library(semTools) # already loads lavaan

item.syntax <- c(paste0("f1 =~ f1item", 1:9),
                 paste0("f2 =~ f2item", 1:9),
                 paste0("f3 =~ f1 + f2"))

## 3-indicator parcels
mod.parcels <- '
  f1 =~ par1 + par2 + par3
  f2 =~ par4 + par5 + par6
  f3 =~ L1*f1 + L1*f2 # constrain loadings to equality, so model is identified

'
## names of parcels
(parcel.names <- paste0("par", 1:6))

parcelAllocation(mod.parcels, data = simParcel, nAlloc = 5,

                 parcel.names = parcel.names, item.syntax = item.syntax,
                 std.lv = TRUE)


Thank you for the alternative though; that might help to fit my model to each randomly drawn parcel set...

Indeed, that would work without installing the updated semTools.

Anna-Lena Jobmann

unread,
Mar 5, 2025, 6:29:28 AMMar 5
to lavaan
Thanks a lot, that works perfectly. :)
Reply all
Reply to author
Forward
0 new messages