Objectives

1.) Understand how to perform the constrained baseline MIMIC model to test for DIF.

2.) From here, know how to identify an anchor item and then conduct a series of sequential free baseline models.

3.) Understand how lavaan computes these models, as well as the alternative MIMIC models that lavaan/semTools have that mayyyyy or may not be more useful…and quicker…and well, you know…more efficient……maybe.

Actual Homework Questions:

1.) Perform constrained baseline approach. Which items are flagged as DIF items and how did you decide the DIF items?

2.) Perform the sequential free baseline approach. Which item you choose for an anchor item? How did you decide the anchor item? Which items are flagged as DIF items and how did you decide the DIF items?

Getting our data imported and ready to go:

Step 1: Loading necessary packages

library(lavaan)
library(semTools)
library(psych)

Step 2: Import the tab-delimited text data file “MIMICrep1.dat”

  • This file contains 15 dichotomous items answered by 200 examinees from reference group and focal group each. First fifteen columns are responses to the 15 items and the last column is grouping (gender).
data<- read.table("MIMICrep1.dat", quote="\"", comment.char="")


To make it easy, let’s change item ‘V16’ to ‘Gender’ so we know what our grouping variable is in the data,

colnames(data)[colnames(data)=="V16"] <- "Gender" #changing variable 'V16' name to 'Gender'
names(data) #check to see if this worked correctly
##  [1] "V1"     "V2"     "V3"     "V4"     "V5"     "V6"     "V7"    
##  [8] "V8"     "V9"     "V10"    "V11"    "V12"    "V13"    "V14"   
## [15] "V15"    "Gender"


Creating a latent interaction term in Lavaan

Step 3: Create a proxy for the latent by group interaction term:

Although Lavaan does not have a direct way to create an interaction term for a latent variable, they do provide a way to create this interaction indirectly.

  • To do so, we simply use the ‘indProd’ function in ‘semTools’ to create product terms to be used as a proxy for our latent interaction between our factor and grouping variable (gender).
  • Below, we can name create a new dataset called ‘new.data,’ as this will contain our original variables, as well as their product interaction terms between each of the fifteen indicators and our grouping variable of interest (i.e., gender).
  • ‘paste0’ is a handy command when our variable names are ‘v’ or ‘x’ or something along those lines. The command in this context tells ‘indProd’ that our first variable should actually be string of 15 variables that correspond to our factor of interest which are labeled as “V1-V15” in our dataset. The paste command basically says you want to paste the letter “V” to numbers 1 through 15. Essentially, this is a quick tool instead of manually typing out “V1”, “V2”, “V3”, etc.
  • The second variable will be our grouping variable, in this case ‘Gender.’
  • This command has various arguements that can be modified, but for this purpose, this is all we need to specify. The default is to mean center the product terms.
new.data <- indProd(var1 = paste0("V", 1:15), var2 = "Gender", match = FALSE,
                   data = data[ , c("Gender", paste0("V", 1:15))] )


Now that we have our latent interaction variables ready, we can conduct our DIF detection procedures one of two ways. The first will be the two-step procedures of the constrained baseline approach followed by the sequential free baseline approach using lavaan/semTools. The second approach will be using semTools variation of MIMICfor identifying items that have both non-uniform and uniform DIF.




Constrained Baseline Approach

If we wanted to manually specify MIMIC models that are slightly tedious and require testing each individual item, we can do so if we are so inclined…

The first step is fitting a series of ‘constrained baseline models’ to detect DIF. Since these models are prone to type I errors, the idea is to test each item in this context in order to identify the best non-DIF item that will be used in the next step as an ‘anchor’ item.

  • To specify this type of MIMIC model, we will still use the product terms that we created earlier, but we will manually specify each of the models accordingly, and then compare model fit through the chi-square LR tests using the ‘anova’ command (specifically the sarotorra bentler method that corresponds to MLR estimation).

Specifying the baseline model

  • This will be our reference point for making comparisons when testing for DIF for each of our 15 items.
base.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender
'
fit.base <- cfa(model=base.mod, data = new.data, meanstructure=TRUE,
                std.lv=T, estimator="MLR")
summary(fit.base, stand = TRUE)
## lavaan 0.6-3 ended normally after 162 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                        110
## 
##   Number of observations                           400
## 
##   Estimator                                         ML      Robust
##   Model Fit Test Statistic                     703.225     577.267
##   Degrees of freedom                               417         417
##   P-value (Chi-square)                           0.000       0.000
##   Scaling correction factor                                  1.218
##     for the Yuan-Bentler correction (Mplus variant)
## 
## Parameter Estimates:
## 
##   Information                                 Observed
##   Observed information based on                Hessian
##   Standard Errors                   Robust.huber.white
## 
## Latent Variables:
##                      Estimate  Std.Err  z-value      P(>|z|)   Std.lv
##   f1 =~                                                              
##     V1                  0.373    0.014       26.228    0.000    0.373
##     V2                  0.167    0.026        6.366    0.000    0.167
##     V3                  0.322    0.018       18.161    0.000    0.322
##     V4                  0.285    0.020       14.149    0.000    0.285
##     V5                  0.315    0.018       17.299    0.000    0.315
##     V6                  0.200    0.026        7.711    0.000    0.200
##     V7                  0.211    0.022        9.458    0.000    0.211
##     V8                  0.332    0.017       19.806    0.000    0.332
##     V9                  0.332    0.017       19.298    0.000    0.332
##     V10                 0.250    0.022       11.430    0.000    0.250
##     V11                 0.318    0.019       16.828    0.000    0.318
##     V12                 0.339    0.018       19.387    0.000    0.339
##     V13                 0.333    0.017       20.075    0.000    0.333
##     V14                 0.380    0.014       27.037    0.000    0.380
##     V15                 0.287    0.020       14.211    0.000    0.287
##   Group =~                                                           
##     Gender              0.500    0.000 19103682.960    0.000    0.500
##   Gender.by.theta =~                                                 
##     V1.Gender           0.187    0.007       26.171    0.000    0.187
##     V2.Gender           0.084    0.013        6.434    0.000    0.084
##     V3.Gender           0.160    0.009       17.835    0.000    0.160
##     V4.Gender           0.144    0.010       14.594    0.000    0.144
##     V5.Gender           0.157    0.009       17.141    0.000    0.157
##     V6.Gender           0.099    0.013        7.548    0.000    0.099
##     V7.Gender           0.105    0.011        9.348    0.000    0.105
##     V8.Gender           0.165    0.008       19.534    0.000    0.165
##     V9.Gender           0.165    0.009       18.930    0.000    0.165
##     V10.Gender          0.124    0.011       11.177    0.000    0.124
##     V11.Gender          0.160    0.009       17.154    0.000    0.160
##     V12.Gender          0.169    0.009       19.331    0.000    0.169
##     V13.Gender          0.166    0.008       19.919    0.000    0.166
##     V14.Gender          0.190    0.007       27.185    0.000    0.190
##     V15.Gender          0.143    0.010       14.106    0.000    0.143
##   Std.all
##          
##     0.765
##     0.334
##     0.677
##     0.569
##     0.659
##     0.406
##     0.454
##     0.665
##     0.691
##     0.513
##     0.643
##     0.695
##     0.667
##     0.758
##     0.581
##          
##     1.000
##          
##     0.765
##     0.337
##     0.675
##     0.578
##     0.658
##     0.403
##     0.451
##     0.663
##     0.689
##     0.511
##     0.646
##     0.695
##     0.666
##     0.758
##     0.580
## 
## Covariances:
##                    Estimate  Std.Err  z-value      P(>|z|)   Std.lv
##  .V1 ~~                                                            
##    .V1.Gender         0.003    0.005        0.575    0.565    0.003
##  .V2 ~~                                                            
##    .V2.Gender         0.014    0.007        1.917    0.055    0.014
##  .V3 ~~                                                            
##    .V3.Gender         0.008    0.006        1.363    0.173    0.008
##  .V4 ~~                                                            
##    .V4.Gender         0.002    0.007        0.260    0.795    0.002
##  .V5 ~~                                                            
##    .V5.Gender         0.003    0.006        0.443    0.658    0.003
##  .V6 ~~                                                            
##    .V6.Gender         0.031    0.008        3.948    0.000    0.031
##  .V7 ~~                                                            
##    .V7.Gender         0.006    0.007        0.857    0.391    0.006
##  .V8 ~~                                                            
##    .V8.Gender         0.006    0.006        0.927    0.354    0.006
##  .V9 ~~                                                            
##    .V9.Gender         0.005    0.006        0.910    0.363    0.005
##  .V10 ~~                                                           
##    .V10.Gender        0.026    0.007        3.807    0.000    0.026
##  .V11 ~~                                                           
##    .V11.Gender       -0.010    0.006       -1.541    0.123   -0.010
##  .V12 ~~                                                           
##    .V12.Gender       -0.003    0.006       -0.565    0.572   -0.003
##  .V13 ~~                                                           
##    .V13.Gender        0.002    0.006        0.382    0.702    0.002
##  .V14 ~~                                                           
##    .V14.Gender       -0.011    0.006       -1.897    0.058   -0.011
##  .V15 ~~                                                           
##    .V15.Gender        0.016    0.007        2.344    0.019    0.016
##   f1 ~~                                                            
##     Group            -0.060    0.053       -1.135    0.256   -0.060
##     Gender.by.thet   -0.053    0.071       -0.751    0.453   -0.053
##   Group ~~                                                         
##     Gender.by.thet    0.005    0.053        0.087    0.930    0.005
##   Std.all
##          
##     0.061
##          
##     0.126
##          
##     0.126
##          
##     0.021
##          
##     0.041
##          
##     0.301
##          
##     0.065
##          
##     0.083
##          
##     0.088
##          
##     0.299
##          
##    -0.139
##          
##    -0.055
##          
##     0.034
##          
##    -0.198
##          
##     0.196
##          
##    -0.060
##    -0.053
##          
##     0.005
## 
## Intercepts:
##                    Estimate  Std.Err  z-value      P(>|z|)   Std.lv
##    .V1                0.608    0.024       24.882    0.000    0.608
##    .V2                0.562    0.025       22.678    0.000    0.562
##    .V3                0.655    0.024       27.558    0.000    0.655
##    .V4                0.512    0.025       20.506    0.000    0.512
##    .V5                0.645    0.024       26.958    0.000    0.645
##    .V6                0.647    0.024       27.106    0.000    0.647
##    .V7                0.682    0.023       29.323    0.000    0.682
##    .V8                0.522    0.025       20.921    0.000    0.522
##    .V9                0.635    0.024       26.380    0.000    0.635
##    .V10               0.657    0.024       27.711    0.000    0.657
##    .V11               0.593    0.025       24.116    0.000    0.593
##    .V12               0.613    0.024       25.145    0.000    0.613
##    .V13               0.492    0.025       19.702    0.000    0.492
##    .V14               0.562    0.025       22.678    0.000    0.562
##    .V15               0.600    0.024       24.495    0.000    0.600
##    .Gender            1.500    0.025       60.000    0.000    1.500
##    .V1.Gender        -0.000    0.012       -0.000    1.000   -0.000
##    .V2.Gender         0.000    0.012        0.000    1.000    0.000
##    .V3.Gender        -0.000    0.012       -0.000    1.000   -0.000
##    .V4.Gender         0.000    0.012        0.000    1.000    0.000
##    .V5.Gender         0.000    0.012        0.000    1.000    0.000
##    .V6.Gender        -0.000    0.012       -0.000    1.000   -0.000
##    .V7.Gender         0.000    0.012        0.000    1.000    0.000
##    .V8.Gender        -0.000    0.012       -0.000    1.000   -0.000
##    .V9.Gender         0.000    0.012        0.000    1.000    0.000
##    .V10.Gender       -0.000    0.012       -0.000    1.000   -0.000
##    .V11.Gender        0.000    0.012        0.000    1.000    0.000
##    .V12.Gender       -0.000    0.012       -0.000    1.000   -0.000
##    .V13.Gender        0.000    0.012        0.000    1.000    0.000
##    .V14.Gender       -0.000    0.012       -0.000    1.000   -0.000
##    .V15.Gender        0.000    0.012        0.000    1.000    0.000
##     f1                0.000                                   0.000
##     Group             0.000                                   0.000
##     Gender.by.thet    0.000                                   0.000
##   Std.all
##     1.245
##     1.126
##     1.379
##     1.025
##     1.349
##     1.313
##     1.466
##     1.045
##     1.320
##     1.353
##     1.198
##     1.255
##     0.985
##     1.121
##     1.213
##     3.000
##    -0.000
##     0.000
##    -0.000
##     0.000
##     0.000
##    -0.000
##     0.000
##    -0.000
##     0.000
##    -0.000
##     0.000
##    -0.000
##     0.000
##    -0.000
##     0.000
##     0.000
##     0.000
##     0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value      P(>|z|)   Std.lv
##    .V1                0.099    0.010        9.984    0.000    0.099
##    .V2                0.222    0.008       27.387    0.000    0.222
##    .V3                0.122    0.010       11.805    0.000    0.122
##    .V4                0.169    0.011       14.698    0.000    0.169
##    .V5                0.129    0.011       11.977    0.000    0.129
##    .V6                0.203    0.010       21.292    0.000    0.203
##    .V7                0.172    0.010       16.579    0.000    0.172
##    .V8                0.139    0.011       12.280    0.000    0.139
##    .V9                0.121    0.011       11.264    0.000    0.121
##    .V10               0.174    0.011       16.392    0.000    0.174
##    .V11               0.143    0.011       12.483    0.000    0.143
##    .V12               0.123    0.011       11.125    0.000    0.123
##    .V13               0.139    0.011       12.586    0.000    0.139
##    .V14               0.107    0.010       10.572    0.000    0.107
##    .V15               0.162    0.011       14.137    0.000    0.162
##    .Gender            0.000                                   0.000
##    .V1.Gender         0.025    0.002        9.978    0.000    0.025
##    .V2.Gender         0.055    0.002       26.922    0.000    0.055
##    .V3.Gender         0.030    0.003       11.910    0.000    0.030
##    .V4.Gender         0.041    0.003       14.565    0.000    0.041
##    .V5.Gender         0.032    0.003       11.990    0.000    0.032
##    .V6.Gender         0.051    0.002       21.633    0.000    0.051
##    .V7.Gender         0.043    0.003       16.575    0.000    0.043
##    .V8.Gender         0.035    0.003       12.254    0.000    0.035
##    .V9.Gender         0.030    0.003       11.256    0.000    0.030
##    .V10.Gender        0.043    0.003       16.688    0.000    0.043
##    .V11.Gender        0.036    0.003       12.537    0.000    0.036
##    .V12.Gender        0.031    0.003       11.110    0.000    0.031
##    .V13.Gender        0.035    0.003       12.595    0.000    0.035
##    .V14.Gender        0.027    0.003       10.540    0.000    0.027
##    .V15.Gender        0.041    0.003       14.110    0.000    0.041
##     f1                1.000                                   1.000
##     Group             1.000                                   1.000
##     Gender.by.thet    1.000                                   1.000
##   Std.all
##     0.414
##     0.888
##     0.542
##     0.676
##     0.565
##     0.835
##     0.794
##     0.558
##     0.523
##     0.737
##     0.586
##     0.517
##     0.555
##     0.426
##     0.663
##     0.000
##     0.414
##     0.887
##     0.544
##     0.666
##     0.567
##     0.837
##     0.796
##     0.560
##     0.525
##     0.739
##     0.583
##     0.517
##     0.557
##     0.425
##     0.663
##     1.000
##     1.000
##     1.000

Now, we can specify additional models to test for DIF on each item using the constrained baseline approach that involves regressing each individual item on the grouping variable and the interaction term.

For item ‘v1’ the code would look as so:

V1.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group=~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

#here we introduce V1 being regressed on Group(gender) and interaction of theta x gender
V1 ~ Group + Gender.by.theta 


V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

V1 <- cfa(V1.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")

We now can compare this model to our baseline model using a chi-square LR test. Because we specified our estimator to be MLR, R knows to default to the correct chi-square test (i.e., satorra.bentler 2001 method).

anova(V1, fit.base) #testing DIF for item 1 
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)
## V1       415 5146.8 5593.8 702.60                              
## fit.base 417 5143.4 5582.4 703.22    0.81202       2     0.6663

Results imply that item 1 should NOT be flagged as DIF



We repeat this process for items 2-15. Again, for item 2, we would use the same code as above, just simply change ‘V1’ to ‘V2’ in the appropriate places like so:

V2.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group=~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

#here we introduce V1 being regressed on Group(gender) and interaction of theta x gender
V2 ~ Group + Gender.by.theta 


V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

V2 <- cfa(V2.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")

Again, let’s compare model ‘V2’ to our baseline model and see if there is a significant difference.

anova(V2, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)    
## V2       415 5132.2 5579.2 688.01                                  
## fit.base 417 5143.4 5582.4 703.22         14       2  0.0009117 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Results suggest that this item SHOULD be flagged as having DIF (p<.001)

In this framework, we continue repeating the same process for ALL items and then evaluate which item has the highest factor loading and is also non-DIF to use as an anchor item for the sequential free baseline MIMIC approach.


The model syntax for all remaining items (V2-V15) is pasted in the below chunk:

#item 3
V3.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

#here we introduce V1 being regressed on Group(gender) and interaction of theta x gender
V3 ~ Group + Gender.by.theta 


V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

#item 4
V4.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 


V4 ~ Group + Gender.by.theta 


V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

#item 5
V5.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 


V5 ~ Group + Gender.by.theta 


V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

#item 6
V6.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 


V6 ~ Group + Gender.by.theta 


V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

#item 7
V7.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 


V7 ~ Group + Gender.by.theta 


V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'


#item 8
V8.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

V8 ~ Group + Gender.by.theta 

V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

#item 9
V9.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

V9 ~ Group + Gender.by.theta 

V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'


#item 10
V10.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

V10 ~ Group + Gender.by.theta 

V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

#item 11
V11.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

V11 ~ Group + Gender.by.theta 

V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

#item 12
V12.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

V12 ~ Group + Gender.by.theta 

V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

#item 13
V13.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

V13 ~ Group + Gender.by.theta 

V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

#item 14
V14.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

V14 ~ Group + Gender.by.theta 

V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'


#item 15
V15.mod<-'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

Group =~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

V15 ~ Group + Gender.by.theta 

V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

Now all models (testing item V3-V15) are quickly ran (no output is displayed though to condense space).

  • Remember to use ‘new.data’ which has our product terms that we need!!!
V3 <- cfa(V3.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V4 <- cfa(V4.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V5 <- cfa(V5.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V6 <- cfa(V6.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V7 <- cfa(V7.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V8 <- cfa(V8.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V9 <- cfa(V9.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V10 <- cfa(V10.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V11 <- cfa(V11.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V12 <- cfa(V12.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V13 <- cfa(V13.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V14 <- cfa(V14.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")
V15 <- cfa(V15.mod, data = new.data, meanstructure = TRUE, std.lv=T, estimator="MLR")

Now we can see which items are flagged as DIF again as well:

anova(V3, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)
## V3       415 5145.8 5592.8 701.62                              
## fit.base 417 5143.4 5582.4 703.22      1.783       2       0.41
anova(V4, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)  
## V4       415 5139.9 5586.9 695.74                                
## fit.base 417 5143.4 5582.4 703.22     8.2258       2    0.01636 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(V5, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)
## V5       415 5146.8 5593.8 702.61                              
## fit.base 417 5143.4 5582.4 703.22    0.69015       2     0.7082
anova(V6, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)    
## V6       415 5110.8 5557.8 666.65                                  
## fit.base 417 5143.4 5582.4 703.22     39.101       2  3.231e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(V7, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)
## V7       415 5146.8 5593.9 702.67                              
## fit.base 417 5143.4 5582.4 703.22    0.54183       2     0.7627
anova(V8, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)
## V8       415 5145.7 5592.7 701.51                              
## fit.base 417 5143.4 5582.4 703.22     1.9719       2     0.3731
anova(V9, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)
## V9       415 5145.6 5592.6 701.41                              
## fit.base 417 5143.4 5582.4 703.22     2.0538       2     0.3581
anova(V10, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)    
## V10      415 5131.3 5578.3 687.11                                  
## fit.base 417 5143.4 5582.4 703.22     16.119       2  0.0003161 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(V11, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)  
## V11      415 5140.5 5587.5 696.34                                
## fit.base 417 5143.4 5582.4 703.22     8.0973       2    0.01745 *
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(V12, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)
## V12      415 5144.9 5591.9 700.73                              
## fit.base 417 5143.4 5582.4 703.22     2.7491       2     0.2529
anova(V13, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)
## V13      415 5147.2 5594.2 703.04                              
## fit.base 417 5143.4 5582.4 703.22    0.21887       2     0.8963
anova(V14, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)   
## V14      415 5138.8 5585.8 694.64                                 
## fit.base 417 5143.4 5582.4 703.22     11.012       2   0.004063 **
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
anova(V15, fit.base)
## Scaled Chi Square Difference Test (method = "satorra.bentler.2001")
## 
##           Df    AIC    BIC  Chisq Chisq diff Df diff Pr(>Chisq)  
## V15      415 5142.1 5589.2 697.96                                
## fit.base 417 5143.4 5582.4 703.22     5.7506       2     0.0564 .
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Results suggest that items V2,V4,V6,V10,V11,V14 & V15 potentially have DIF.

As a reminder though, this method often has a higher type I error rate, so we now move to the sequential baseline model.

The sequential free baseline approach requires identifying at least one anchor item. Again, we want to find a non-DIF item that is discriminating (i.e., has a high factor loading).

  • Let’s check the loadings from our original baseline model.
lavInspect(fit.base, what="std")$lambda
##               f1 Group Gndr..
## V1         0.765     0  0.000
## V2         0.334     0  0.000
## V3         0.677     0  0.000
## V4         0.569     0  0.000
## V5         0.659     0  0.000
## V6         0.406     0  0.000
## V7         0.454     0  0.000
## V8         0.665     0  0.000
## V9         0.691     0  0.000
## V10        0.513     0  0.000
## V11        0.643     0  0.000
## V12        0.695     0  0.000
## V13        0.667     0  0.000
## V14        0.758     0  0.000
## V15        0.581     0  0.000
## Gender     0.000     1  0.000
## V1.Gender  0.000     0  0.765
## V2.Gender  0.000     0  0.337
## V3.Gender  0.000     0  0.675
## V4.Gender  0.000     0  0.578
## V5.Gender  0.000     0  0.658
## V6.Gender  0.000     0  0.403
## V7.Gender  0.000     0  0.451
## V8.Gender  0.000     0  0.663
## V9.Gender  0.000     0  0.689
## V10.Gender 0.000     0  0.511
## V11.Gender 0.000     0  0.646
## V12.Gender 0.000     0  0.695
## V13.Gender 0.000     0  0.666
## V14.Gender 0.000     0  0.758
## V15.Gender 0.000     0  0.580
  • Item 1 has the highest loading and does not show evidence of having bias. Thus, we select ‘V1’ to be our anchor item for the following analyses.




Sequential Free Basline Approach to MIMIC

Now that we have identified our anchor item, we can use the semTools package to fairly efficiently perform a series of these models. We will be using the “permuteMeasEq” command in semTools, which allows us to flexibily specify our MIMIC model and when specified correctly, follows the same logic as the sequential free baseline approach.

Important arguements to specify when using permuteMeasEq:

  • nPermute = #
    • this is essentially the number of iterations. For this example, it was set to 50 to save computational time, but usually want > 1000 permutations to reduce sampling variability of our estimated p-values.
  • modelType = “mimic”
  • con = “name of mimic model”
    • when modelType = “mimic”, ‘con’ is a user specified MIMIC model in which the co-variate (in this case Gender) predicts the latent construct, but not the indicators (i.e., the baseline model - code is below).
con.mimic<- 'f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15

f1 ~ Gender

Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 


V1 ~~ V1.Gender
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender'

mim.con <- cfa(con.mimic, data = new.data, meanstructure = TRUE, std.lv=T)
  • ‘param = x’
    • When modelType = “mimic”, ‘param’ must be a vector of individual parameters or a list of character strings to be passed one-at-a-time to lavTestScore(object = con, add = param[i]), indicating which (sets of) regression paths are fixed to zero in ‘con’ (our previous user specified model) that the user wants to consider freeing in order to test for DIF (exclude anchor items).
    • Since we know our anchor item is ‘V1,’ we would leave this out of the ‘param’ list. (Code is below but may not make sense at first, but this specifically corresponds with our ‘con’ model syntax from above that is labeled ‘mim.con.’
    param <- as.list(paste0("Group + Gender.by.theta =~ V", 1:15)) 
    names(param) <- paste0("V", 1:15)
    #can also specify like param <- as.list(paste0("V", 1:15, " ~ Gender + Gender.by.theta")) 
  • ‘freeParam = x’
    • freeParam allows you to specify your anchor item (i.e., the item that WILL NOT be tested for DIF). If you specify the variable name here, it does not matter whether or not the variable name is included in your ‘param’ list or not.
  • ‘covariates = x’
    • List the variable or variables that will be covariates in the model. Should correspond to a name or set of columns in the dataset.
  • ‘AFIs =’
    • Optional, but can define a list of extra fit indices if you like (code also included below). This will allow you to obtain additional fit indices that wouldn’t normally be calculated.
  • Define fit indices of interest for multiparameter omnibus test:
myAFIs <- c("chisq","cfi","rmsea","mfi","aic")
  • ‘datafun’
    • ‘datafun’ is useful when using the MIMIC method to allow for tests of non-uniform DIF (metric/weak invariance) by using the product indicators as a proxy for the latent interaction, in which case the product indicators we created earlier would need to be re-calculated after each permutation of the covariate. Thus, we create a function called datafun to feed into this argument (code is below).
## function to recalculate interaction terms after permuting the covariate
datafun <- function(data) {
  d <- data[, !names(data) %in% paste0("V", 1:15, ".Gender")]
  indProd(var1 = paste0("V", 1:15), var2 = "Gender", match = FALSE, data = d)
}
  • Additional commands here can also be specified. See ‘?permuteMeasEq’ for more info.


Let’s now actually run the sequential free baseline models to test for DIF using ‘V1’ as an anchor item:

Sequential.mimic<- permuteMeasEq(nPermute=50, # num of iterations
                               modelType = "mimic", 
                              con=mim.con, #previously defined model
                              param = param, #list of parameters we are testing for DIF
                              freeParam = "V1", #anchor item
                              covariates = "Gender", #grouping vbl in dataset
                              AFIs = myAFIs, #list of fit indices we want
                              datafun= datafun, #function that was defined above
                              showProgress = FALSE) #usually true - but didn't want it to                                show up in rmarkdown

Extract results:

summary(Sequential.mimic) #exract summary
## Omnibus p value based on parametric chi-squared difference test:
## 
## Chisq diff    Df diff Pr(>Chisq) 
##    704.162    419.000      0.000 
## 
## 
## Omnibus p values based on nonparametric permutation method: 
## 
##       AFI.Difference p.value
## chisq        704.162       0
## cfi            0.934       0
## rmsea          0.041       0
## mfi            0.700       0
## aic         4555.680       1
## 
## 
##  Modification indices for equality constrained parameter estimates,
##  with unadjusted 'p.value' based on chi-squared distribution and
##  adjusted 'tukey.p.value' based on permutation distribution of the
##  maximum modification index per iteration: 
## 
##      test     X2 df p.value tukey.p.value flag
## V1  score  0.080  2   0.961          1.00     
## V2  score 14.152  2   0.001          0.00 *   
## V3  score  0.024  2   0.988          1.00     
## V4  score  0.004  2   0.998          1.00     
## V5  score  0.376  2   0.828          1.00     
## V6  score 34.345  2   0.000          0.00 *   
## V7  score  0.010  2   0.995          1.00     
## V8  score  0.180  2   0.914          1.00     
## V9  score  0.237  2   0.888          1.00     
## V10 score 14.835  2   0.001          0.00 *   
## V11 score  4.265  2   0.119          0.24     
## V12 score  2.145  2   0.342          0.72     
## V13 score  0.000  2   1.000          1.00     
## V14 score  6.633  2   0.036          0.08     
## V15 score  5.455  2   0.065          0.10

Results:

  • Results suggest that items V2, V4, V10, & V14 should be flagged as ‘DIF.’





Alternative MIMIC Approach (RFA) using Lavaan & semTools

In semTools/Lavaan, the default for MIMIC is based on a ‘Restricted Factor Analysis (RFA)’ model, which is equivalent to MIMIC, but differs in that the factor co-varies with the covariate instead of being regressed on it. The covariate in this case defines a single-indicator construct, and the double-mean-centered products of the indicators define a latent interaction between the factor and the covariate.

  • Put differently, MIMIC models specify direct effects of the co-variate on an indicator (usually one at a time), whereas in the RFA framework, DIF can be tested more efficiently by specifying free loadings of an indicator on the co-variate’s construct (uniform DIF, scalar invariance) and the interaction construct (nonuniform DIF, metric invariance).


To specify the RFA version of MIMIC, we simply define our latent variable as normal (f1), define the grouping variable (i.e., Gender) as an actual latent variable, and then also define a new latent variable called ‘Gender.by.theta’ by all the product terms that we saved in our new dataset called ‘new.data.’ Finally, we allow the residuals of each specific indicator to correlate with the residuals of the product interaction term using the ‘~~’

Specifying the RFA MIMIC model syntax:

mod.mimic <- '
f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 + V10 + V11 + V12 + V13 + V14 + V15

Group=~ Gender #define the grouping variable as an actual LV


#list all product indicators and specify them on their own factor
Gender.by.theta =~ V1.Gender + V2.Gender  + V3.Gender  + V4.Gender  + V5.Gender 
+ V6.Gender  + V7.Gender + V8.Gender + V9.Gender + V10.Gender +
V11.Gender + V12.Gender  + V13.Gender + V14.Gender + V15.Gender 

#correlate residuals for original item and product interaction term

V1 ~~ V1.Gender 
V2~~ V2.Gender
V3 ~~ V3.Gender
V4 ~~ V4.Gender
V5 ~~ V5.Gender
V6  ~~ V6.Gender
V7 ~~ V7.Gender
V8 ~~ V8.Gender
V9 ~~ V9.Gender
V10 ~~ V10.Gender
V11 ~~ V11.Gender
V12 ~~ V12.Gender
V13 ~~ V13.Gender
V14 ~~ V14.Gender
V15 ~~ V15.Gender
'

Now that our model is specified above, we can go ahead and fit our MIMIC model and extract the DIF information we are interested in.

Fiting the model:

  • This should look similar to prior Lavaan cfa commands, with the exception of the ‘meanstucture’ arguement being included.
  • Again, make sure you are using ‘new.data’ which includes our product terms for testing non-uniform DIF.
fit.mimic <- cfa(mod.mimic, data = new.data, meanstructure = TRUE, std.lv=T)
summary(fit.mimic, stand = TRUE)
## lavaan 0.6-3 ended normally after 162 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                        110
## 
##   Number of observations                           400
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                     703.225
##   Degrees of freedom                               417
##   P-value (Chi-square)                           0.000
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                      Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   f1 =~                                                                   
##     V1                  0.373    0.021   17.620    0.000    0.373    0.765
##     V2                  0.167    0.025    6.637    0.000    0.167    0.334
##     V3                  0.322    0.022   14.950    0.000    0.322    0.677
##     V4                  0.285    0.024   11.964    0.000    0.285    0.569
##     V5                  0.315    0.022   14.372    0.000    0.315    0.659
##     V6                  0.200    0.024    8.481    0.000    0.200    0.406
##     V7                  0.211    0.023    9.207    0.000    0.211    0.454
##     V8                  0.332    0.023   14.554    0.000    0.332    0.665
##     V9                  0.332    0.022   15.310    0.000    0.332    0.691
##     V10                 0.250    0.023   10.995    0.000    0.250    0.513
##     V11                 0.318    0.023   14.011    0.000    0.318    0.643
##     V12                 0.339    0.022   15.422    0.000    0.339    0.695
##     V13                 0.333    0.023   14.583    0.000    0.333    0.667
##     V14                 0.380    0.022   17.529    0.000    0.380    0.758
##     V15                 0.287    0.023   12.434    0.000    0.287    0.581
##   Group =~                                                                
##     Gender              0.500    0.018   28.284    0.000    0.500    1.000
##   Gender.by.theta =~                                                      
##     V1.Gender           0.187    0.011   17.619    0.000    0.187    0.765
##     V2.Gender           0.084    0.013    6.691    0.000    0.084    0.337
##     V3.Gender           0.160    0.011   14.906    0.000    0.160    0.675
##     V4.Gender           0.144    0.012   12.189    0.000    0.144    0.578
##     V5.Gender           0.157    0.011   14.337    0.000    0.157    0.658
##     V6.Gender           0.099    0.012    8.419    0.000    0.099    0.403
##     V7.Gender           0.105    0.011    9.153    0.000    0.105    0.451
##     V8.Gender           0.165    0.011   14.506    0.000    0.165    0.663
##     V9.Gender           0.165    0.011   15.262    0.000    0.165    0.689
##     V10.Gender          0.124    0.011   10.937    0.000    0.124    0.511
##     V11.Gender          0.160    0.011   14.086    0.000    0.160    0.646
##     V12.Gender          0.169    0.011   15.407    0.000    0.169    0.695
##     V13.Gender          0.166    0.011   14.550    0.000    0.166    0.666
##     V14.Gender          0.190    0.011   17.556    0.000    0.190    0.758
##     V15.Gender          0.143    0.012   12.420    0.000    0.143    0.580
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##  .V1 ~~                                                                 
##    .V1.Gender         0.003    0.003    1.069    0.285    0.003    0.061
##  .V2 ~~                                                                 
##    .V2.Gender         0.014    0.006    2.469    0.014    0.014    0.126
##  .V3 ~~                                                                 
##    .V3.Gender         0.008    0.003    2.326    0.020    0.008    0.126
##  .V4 ~~                                                                 
##    .V4.Gender         0.002    0.004    0.395    0.693    0.002    0.021
##  .V5 ~~                                                                 
##    .V5.Gender         0.003    0.003    0.765    0.444    0.003    0.041
##  .V6 ~~                                                                 
##    .V6.Gender         0.031    0.005    5.679    0.000    0.031    0.301
##  .V7 ~~                                                                 
##    .V7.Gender         0.006    0.004    1.272    0.204    0.006    0.065
##  .V8 ~~                                                                 
##    .V8.Gender         0.006    0.004    1.551    0.121    0.006    0.083
##  .V9 ~~                                                                 
##    .V9.Gender         0.005    0.003    1.617    0.106    0.005    0.088
##  .V10 ~~                                                                
##    .V10.Gender        0.026    0.005    5.571    0.000    0.026    0.299
##  .V11 ~~                                                                
##    .V11.Gender       -0.010    0.004   -2.587    0.010   -0.010   -0.139
##  .V12 ~~                                                                
##    .V12.Gender       -0.003    0.003   -1.013    0.311   -0.003   -0.055
##  .V13 ~~                                                                
##    .V13.Gender        0.002    0.004    0.629    0.529    0.002    0.034
##  .V14 ~~                                                                
##    .V14.Gender       -0.011    0.003   -3.441    0.001   -0.011   -0.198
##  .V15 ~~                                                                
##    .V15.Gender        0.016    0.004    3.687    0.000    0.016    0.196
##   f1 ~~                                                                 
##     Group            -0.060    0.052   -1.146    0.252   -0.060   -0.060
##     Gender.by.thet   -0.053    0.055   -0.971    0.332   -0.053   -0.053
##   Group ~~                                                              
##     Gender.by.thet    0.005    0.052    0.088    0.930    0.005    0.005
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .V1                0.608    0.024   24.895    0.000    0.608    1.245
##    .V2                0.562    0.025   22.518    0.000    0.562    1.126
##    .V3                0.655    0.024   27.576    0.000    0.655    1.379
##    .V4                0.512    0.025   20.506    0.000    0.512    1.025
##    .V5                0.645    0.024   26.976    0.000    0.645    1.349
##    .V6                0.647    0.025   26.260    0.000    0.647    1.313
##    .V7                0.682    0.023   29.328    0.000    0.682    1.466
##    .V8                0.522    0.025   20.908    0.000    0.522    1.045
##    .V9                0.635    0.024   26.410    0.000    0.635    1.320
##    .V10               0.657    0.024   27.052    0.000    0.657    1.353
##    .V11               0.593    0.025   23.952    0.000    0.593    1.198
##    .V12               0.613    0.024   25.096    0.000    0.613    1.255
##    .V13               0.492    0.025   19.703    0.000    0.492    0.985
##    .V14               0.562    0.025   22.411    0.000    0.562    1.121
##    .V15               0.600    0.025   24.253    0.000    0.600    1.213
##    .Gender            1.500    0.025   60.000    0.000    1.500    3.000
##    .V1.Gender        -0.000    0.012   -0.000    1.000   -0.000   -0.000
##    .V2.Gender         0.000    0.012    0.000    1.000    0.000    0.000
##    .V3.Gender        -0.000    0.012   -0.000    1.000   -0.000   -0.000
##    .V4.Gender         0.000    0.012    0.000    1.000    0.000    0.000
##    .V5.Gender         0.000    0.012    0.000    1.000    0.000    0.000
##    .V6.Gender        -0.000    0.012   -0.000    1.000   -0.000   -0.000
##    .V7.Gender         0.000    0.012    0.000    1.000    0.000    0.000
##    .V8.Gender        -0.000    0.012   -0.000    1.000   -0.000   -0.000
##    .V9.Gender         0.000    0.012    0.000    1.000    0.000    0.000
##    .V10.Gender       -0.000    0.012   -0.000    1.000   -0.000   -0.000
##    .V11.Gender        0.000    0.012    0.000    1.000    0.000    0.000
##    .V12.Gender       -0.000    0.012   -0.000    1.000   -0.000   -0.000
##    .V13.Gender        0.000    0.012    0.000    1.000    0.000    0.000
##    .V14.Gender       -0.000    0.013   -0.000    1.000   -0.000   -0.000
##    .V15.Gender        0.000    0.012    0.000    1.000    0.000    0.000
##     f1                0.000                               0.000    0.000
##     Group             0.000                               0.000    0.000
##     Gender.by.thet    0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .V1                0.099    0.008   12.252    0.000    0.099    0.414
##    .V2                0.222    0.016   13.975    0.000    0.222    0.888
##    .V3                0.122    0.009   13.013    0.000    0.122    0.542
##    .V4                0.169    0.013   13.503    0.000    0.169    0.676
##    .V5                0.129    0.010   13.116    0.000    0.129    0.565
##    .V6                0.203    0.015   13.881    0.000    0.203    0.835
##    .V7                0.172    0.012   13.797    0.000    0.172    0.794
##    .V8                0.139    0.011   13.086    0.000    0.139    0.558
##    .V9                0.121    0.009   12.924    0.000    0.121    0.523
##    .V10               0.174    0.013   13.668    0.000    0.174    0.737
##    .V11               0.143    0.011   13.200    0.000    0.143    0.586
##    .V12               0.123    0.010   12.892    0.000    0.123    0.517
##    .V13               0.139    0.011   13.074    0.000    0.139    0.555
##    .V14               0.107    0.009   12.331    0.000    0.107    0.426
##    .V15               0.162    0.012   13.465    0.000    0.162    0.663
##    .Gender            0.000                               0.000    0.000
##    .V1.Gender         0.025    0.002   12.250    0.000    0.025    0.414
##    .V2.Gender         0.055    0.004   13.972    0.000    0.055    0.887
##    .V3.Gender         0.030    0.002   13.021    0.000    0.030    0.544
##    .V4.Gender         0.041    0.003   13.472    0.000    0.041    0.666
##    .V5.Gender         0.032    0.002   13.122    0.000    0.032    0.567
##    .V6.Gender         0.051    0.004   13.885    0.000    0.051    0.837
##    .V7.Gender         0.043    0.003   13.801    0.000    0.043    0.796
##    .V8.Gender         0.035    0.003   13.094    0.000    0.035    0.560
##    .V9.Gender         0.030    0.002   12.934    0.000    0.030    0.525
##    .V10.Gender        0.043    0.003   13.673    0.000    0.043    0.739
##    .V11.Gender        0.036    0.003   13.185    0.000    0.036    0.583
##    .V12.Gender        0.031    0.002   12.894    0.000    0.031    0.517
##    .V13.Gender        0.035    0.003   13.080    0.000    0.035    0.557
##    .V14.Gender        0.027    0.002   12.320    0.000    0.027    0.425
##    .V15.Gender        0.041    0.003   13.466    0.000    0.041    0.663
##     f1                1.000                               1.000    1.000
##     Group             1.000                               1.000    1.000
##     Gender.by.thet    1.000                               1.000    1.000

Extracting the DIF Information

To test for both uniform/non-uniform DIF simultaneously, we can use the code below:

  • ‘param’ is defined earlier from when we specified the sequential free baseline model.
do.call(rbind, lapply(param, function(x) lavTestScore(fit.mimic, add = x)$test))
## 
## total score test:
## 
##      test     X2 df p.value
## V1  score  0.620  2   0.733
## V2  score 14.909  2   0.001
## V3  score  1.604  2   0.449
## V4  score  7.408  2   0.025
## V5  score  0.613  2   0.736
## V6  score 34.865  2   0.000
## V7  score  0.550  2   0.760
## V8  score  1.709  2   0.425
## V9  score  1.805  2   0.406
## V10 score 15.769  2   0.000
## V11 score  6.759  2   0.034
## V12 score  2.472  2   0.291
## V13 score  0.183  2   0.912
## V14 score  8.336  2   0.015
## V15 score  5.203  2   0.074
  • Using a cut-off of p<.01, items that would be identified as exhibiting ‘DIF’ would be items V2, V6, V10, & V14
  • If we used a cut-off of p<.05, we would likely identify some items that are likely type I errors, such as item 4,11, & 15.

If we want to test each parameter individually for both kinds of DIF, we can also use this command below:

lavTestScore(fit.mimic, add = as.character(param))
## $test
## 
## total score test:
## 
##    test     X2 df p.value
## 1 score 98.571 30       0
## 
## $uni
## 
## univariate score tests:
## 
##                     lhs op rhs     X2 df p.value
## 1             Group=~V1 ==   0  0.463  1   0.496
## 2   Gender.by.theta=~V1 ==   0  0.158  1   0.691
## 3             Group=~V2 ==   0  0.949  1   0.330
## 4   Gender.by.theta=~V2 ==   0 13.952  1   0.000
## 5             Group=~V3 ==   0  1.544  1   0.214
## 6   Gender.by.theta=~V3 ==   0  0.059  1   0.808
## 7             Group=~V4 ==   0  7.408  1   0.006
## 8   Gender.by.theta=~V4 ==   0  0.000  1   0.999
## 9             Group=~V5 ==   0  0.125  1   0.723
## 10  Gender.by.theta=~V5 ==   0  0.487  1   0.485
## 11            Group=~V6 ==   0  0.913  1   0.339
## 12  Gender.by.theta=~V6 ==   0 33.964  1   0.000
## 13            Group=~V7 ==   0  0.528  1   0.467
## 14  Gender.by.theta=~V7 ==   0  0.021  1   0.885
## 15            Group=~V8 ==   0  1.592  1   0.207
## 16  Gender.by.theta=~V8 ==   0  0.118  1   0.732
## 17            Group=~V9 ==   0  1.471  1   0.225
## 18  Gender.by.theta=~V9 ==   0  0.333  1   0.564
## 19           Group=~V10 ==   0  1.308  1   0.253
## 20 Gender.by.theta=~V10 ==   0 14.471  1   0.000
## 21           Group=~V11 ==   0  2.122  1   0.145
## 22 Gender.by.theta=~V11 ==   0  4.643  1   0.031
## 23           Group=~V12 ==   0  0.026  1   0.872
## 24 Gender.by.theta=~V12 ==   0  2.447  1   0.118
## 25           Group=~V13 ==   0  0.178  1   0.673
## 26 Gender.by.theta=~V13 ==   0  0.005  1   0.943
## 27           Group=~V14 ==   0  0.999  1   0.318
## 28 Gender.by.theta=~V14 ==   0  7.341  1   0.007
## 29           Group=~V15 ==   0  0.016  1   0.900
## 30 Gender.by.theta=~V15 ==   0  5.186  1   0.023
  • Results are fairly similar to the sequential free baseline results, but are not corrected for multiple comparisons like the output from the sequential free baseline model.



Comparing MIMIC Results to Typical Multigroup MI Testing to detect for levels of invariance as well as DIF

Recall back to previous homeworks of how to test different levels of measurement invariance using Lavaan and semTools.
To review: we can specify a configural, metric, and scalar model that will test for measurement invariance at the various levels through chi-square LR tests as well as change in other fit indices.

  • However, we can use this method in conjunction with the introduced command ‘permuteMeasEq’


First, we specify the configural model that simply consists of our one factor defined by its 15 indicators:

mod.config <- '
f1 =~ V1 + V2 + V3 + V4 + V5 + V6 + V7 + V8 + V9 
+ V10 + V11 + V12 + V13 + V14 + V15'

Next, we physically run this model not using the ‘cfa’ function, but instead use ‘measurementInvariance’ and specify the grouping variable with the ‘group’ arguement.

miout <- measurementInvariance(model = mod.config, data = data, std.lv = TRUE,
                               group = "Gender")

From here, we save specific information from each of the levels of invariance from the ‘measurementInvariance’ function above to use later on.

fit.config <- miout[["fit.configural"]]
fit.metric <- miout[["fit.loadings"]]
fit.scalar <- miout[["fit.intercepts"]]


Applying Permutations to test for DIF with above MI output:

We will now use the above measurement invariance model that was fit to examine what items specifically show item bias (either non-uniform or uniform DIF).

Testing configural metric invariance

##for this purpose only using 50 permutations but would want 500-1000+ in practice. 
out.config <- permuteMeasEq(nPermute = 50, con = fit.config, showProgress = FALSE)
## No AFIs were selected, so only chi-squared will be permuted.

Print results:

out.config
## Omnibus p value based on parametric chi-squared difference test:
## 
## Chisq diff    Df diff Pr(>Chisq) 
##    258.061    180.000      0.000 
## 
## 
## Omnibus p values based on nonparametric permutation method: 
## 
##       AFI.Difference p.value
## chisq        258.061    0.46


Testing metric invariance (non-uniform DIF)

out.metric <- permuteMeasEq(nPermute = 50, uncon = fit.config, con = fit.metric,
                            param = "loadings", 
                            AFIs = myAFIs #these were defined earlier
                            , showProgress = FALSE)

Print results:

summary(out.metric, nd = 10)
## Omnibus p value based on parametric chi-squared difference test:
## 
## Chisq diff    Df diff Pr(>Chisq) 
##   84.22693   14.00000    0.00000 
## 
## 
## Omnibus p values based on nonparametric permutation method: 
## 
##       AFI.Difference p.value
## chisq    84.22692820       0
## cfi      -0.03232223       0
## rmsea     0.01525547       0
## mfi      -0.07622796       0
## aic      56.22692820       0
## 
## 
##  Modification indices for equality constrained parameter estimates,
##  with unadjusted 'p.value' based on chi-squared distribution and
##  adjusted 'tukey.p.value' based on permutation distribution of the
##  maximum modification index per iteration: 
## 
##      lhs op   rhs           X2 df      p.value tukey.p.value   flag
## 1   .p1. == .p48. 1.551049e-01  1 0.6937039467          1.00       
## 2   .p2. == .p49. 1.413267e+01  1 0.0001703588          0.00 *  -->
## 3   .p3. == .p50. 5.888629e-02  1 0.8082649461          1.00       
## 4   .p4. == .p51. 3.617540e-05  1 0.9952010724          1.00       
## 5   .p5. == .p52. 4.856101e-01  1 0.4858921205          1.00       
## 6   .p6. == .p53. 3.471350e+01  1 0.0000000038          0.00 *  -->
## 7   .p7. == .p54. 2.072454e-02  1 0.8855318953          1.00       
## 8   .p8. == .p55. 1.208272e-01  1 0.7281390089          1.00       
## 9   .p9. == .p56. 3.352515e-01  1 0.5625830773          1.00       
## 10 .p10. == .p57. 1.482390e+01  1 0.0001180302          0.00 *  -->
## 11 .p11. == .p58. 4.659465e+00  1 0.0308828042          0.32       
## 12 .p12. == .p59. 2.447067e+00  1 0.1177447054          0.76       
## 13 .p13. == .p60. 4.717869e-03  1 0.9452389704          1.00       
## 14 .p14. == .p61. 7.373047e+00  1 0.0066208671          0.00 *  -->
## 15 .p15. == .p62. 5.283781e+00  1 0.0215249511          0.10       
##    parameter group.lhs group.rhs
## 1     f1=~V1         1         2
## 2     f1=~V2         1         2
## 3     f1=~V3         1         2
## 4     f1=~V4         1         2
## 5     f1=~V5         1         2
## 6     f1=~V6         1         2
## 7     f1=~V7         1         2
## 8     f1=~V8         1         2
## 9     f1=~V9         1         2
## 10   f1=~V10         1         2
## 11   f1=~V11         1         2
## 12   f1=~V12         1         2
## 13   f1=~V13         1         2
## 14   f1=~V14         1         2
## 15   f1=~V15         1         2
## 
## 
## The following equality constraints were flagged as significant:
## 
## Parameter 'f1=~V2' may differ between Groups '1' and '2'.
## Parameter 'f1=~V6' may differ between Groups '1' and '2'.
## Parameter 'f1=~V10' may differ between Groups '1' and '2'.
## Parameter 'f1=~V14' may differ between Groups '1' and '2'.
## 
## Use lavTestScore(..., epc = TRUE) on your constrained model to display expected parameter changes for these equality constraints
  • With just testing for non-uniform DIF, we identified item 2, 6, and 10 as having DIF.

Testing scalar invaiance (uniform DIF + non-uniform DIF)

out.scalar <- permuteMeasEq(nPermute = 50, uncon = fit.config, con = fit.metric,
                            param = c("intercepts","loadings"),
                            AFIs = myAFIs,#these were defined earlier
                            showProgress = FALSE)

Print results:

summary(out.scalar, nd = 10)
## Omnibus p value based on parametric chi-squared difference test:
## 
## Chisq diff    Df diff Pr(>Chisq) 
##   84.22693   14.00000    0.00000 
## 
## 
## Omnibus p values based on nonparametric permutation method: 
## 
##       AFI.Difference p.value
## chisq    84.22692820       0
## cfi      -0.03232223       0
## rmsea     0.01525547       0
## mfi      -0.07622796       0
## aic      56.22692820       0
## 
## 
##  Modification indices for equality constrained parameter estimates,
##  with unadjusted 'p.value' based on chi-squared distribution and
##  adjusted 'tukey.p.value' based on permutation distribution of the
##  maximum modification index per iteration: 
## 
##      lhs op   rhs           X2 df      p.value tukey.p.value   flag
## 1   .p1. == .p48. 1.551049e-01  1 0.6937039467          1.00       
## 2   .p2. == .p49. 1.413267e+01  1 0.0001703588          0.00 *  -->
## 3   .p3. == .p50. 5.888629e-02  1 0.8082649461          1.00       
## 4   .p4. == .p51. 3.617540e-05  1 0.9952010724          1.00       
## 5   .p5. == .p52. 4.856101e-01  1 0.4858921205          0.98       
## 6   .p6. == .p53. 3.471350e+01  1 0.0000000038          0.00 *  -->
## 7   .p7. == .p54. 2.072454e-02  1 0.8855318953          1.00       
## 8   .p8. == .p55. 1.208272e-01  1 0.7281390089          1.00       
## 9   .p9. == .p56. 3.352515e-01  1 0.5625830773          1.00       
## 10 .p10. == .p57. 1.482390e+01  1 0.0001180302          0.00 *  -->
## 11 .p11. == .p58. 4.659465e+00  1 0.0308828042          0.18       
## 12 .p12. == .p59. 2.447067e+00  1 0.1177447054          0.54       
## 13 .p13. == .p60. 4.717869e-03  1 0.9452389704          1.00       
## 14 .p14. == .p61. 7.373047e+00  1 0.0066208671          0.02 *  -->
## 15 .p15. == .p62. 5.283781e+00  1 0.0215249511          0.08       
##    parameter group.lhs group.rhs
## 1     f1=~V1         1         2
## 2     f1=~V2         1         2
## 3     f1=~V3         1         2
## 4     f1=~V4         1         2
## 5     f1=~V5         1         2
## 6     f1=~V6         1         2
## 7     f1=~V7         1         2
## 8     f1=~V8         1         2
## 9     f1=~V9         1         2
## 10   f1=~V10         1         2
## 11   f1=~V11         1         2
## 12   f1=~V12         1         2
## 13   f1=~V13         1         2
## 14   f1=~V14         1         2
## 15   f1=~V15         1         2
## 
## 
## The following equality constraints were flagged as significant:
## 
## Parameter 'f1=~V2' may differ between Groups '1' and '2'.
## Parameter 'f1=~V6' may differ between Groups '1' and '2'.
## Parameter 'f1=~V10' may differ between Groups '1' and '2'.
## Parameter 'f1=~V14' may differ between Groups '1' and '2'.
## 
## Use lavTestScore(..., epc = TRUE) on your constrained model to display expected parameter changes for these equality constraints

Testing for BOTH uniform and non-uniform DIF, our results suggest that item 2, 6, 10, & 14 should be flagged for DIF.

  • These results are identical to the sequential free baseline model.