This document shows the usage of function multiDIF() to implement the method proposed by Battauz (2025). It could be used to analyze:

  • the effect of covariates at the within-group item level on the item parameters (e.g. item position),
  • the differences in the item parameters across groups.

1 Example of covariate effects: the item position

Load the package equateMultiple and the data.

library("equateMultiple")
data("timss19")

Estimate the item parameters separately for each booklet using the R package mirt.

library(mirt)
est.mods <- list()
for (i in 1:14)
  est.mods[[i]] <- mirt(timss19$data[[i]][, -(1:3)], 1, itemtype = "2PL", SE = TRUE)

Extract item parameter estimates and covariance matrices.

mods <- modIRT(est.mods = est.mods, names = names(timss19$data))

For comparison, the equating coefficients are also estimated ignoring the item position effect using the independent likelihood method

eqINDLIK <- multiec(mods = mods, method = "indlik") 
## Computation of equating coefficients . . . . 
## Computation of standard errors  .  .  .  .
summary(eqINDLIK)
## Equating coefficients:
##  EQ Form  Estimate   StdErr
##   A  B01  1.000000 0.000000
##   A  B02  1.139006 0.066084
##   A  B03  1.113649 0.080523
##   A  B04  1.166446 0.095008
##   A  B05  1.234758 0.112863
##   A  B06  1.190822 0.115680
##   A  B07  1.110032 0.112139
##   A  B08  1.298161 0.136019
##   A  B09  1.203730 0.125301
##   A  B10  1.238845 0.126821
##   A  B11  1.092513 0.103599
##   A  B12  1.080780 0.095692
##   A  B13  1.062426 0.082717
##   A  B14  1.047323 0.066737
##   B  B01  0.000000 0.000000
##   B  B02 -0.086055 0.069640
##   B  B03 -0.102984 0.080656
##   B  B04 -0.017841 0.088400
##   B  B05  0.099983 0.098940
##   B  B06  0.054661 0.101803
##   B  B07  0.062404 0.103489
##   B  B08 -0.245597 0.104302
##   B  B09 -0.114392 0.098608
##   B  B10 -0.410851 0.099436
##   B  B11 -0.239027 0.089833
##   B  B12 -0.192837 0.083833
##   B  B13 -0.157509 0.074701
##   B  B14 -0.227277 0.067235

Estimation of position effects on the item parameters

dif_positions <- multiDIF(mods = mods, se = TRUE, X.DIF = timss19$positions)
summary(dif_positions)
## Equating coefficients:
##  EQ Form  Estimate   StdErr
##   A  B01  1.000000 0.000000
##   A  B02  1.136281 0.067585
##   A  B03  1.119967 0.082346
##   A  B04  1.143324 0.093699
##   A  B05  1.201282 0.109795
##   A  B06  1.122213 0.107318
##   A  B07  1.044953 0.103248
##   A  B08  1.184687 0.118952
##   A  B09  1.089984 0.108433
##   A  B10  1.131496 0.111650
##   A  B11  1.031696 0.097081
##   A  B12  1.043902 0.093451
##   A  B13  1.051416 0.084189
##   A  B14  1.041656 0.068839
##   B  B01  0.000000 0.000000
##   B  B02 -0.060140 0.068841
##   B  B03 -0.072065 0.077360
##   B  B04  0.002503 0.082879
##   B  B05  0.115260 0.090590
##   B  B06  0.072752 0.090938
##   B  B07  0.102325 0.091765
##   B  B08 -0.181192 0.093642
##   B  B09 -0.046502 0.089732
##   B  B10 -0.294805 0.089308
##   B  B11 -0.144426 0.082196
##   B  B12 -0.130864 0.078426
##   B  B13 -0.106588 0.072262
##   B  B14 -0.193562 0.065686
## 
## Covariate effects:
##                     Estimate     StdErr
## Dscrmn.position   0.00721635 0.00510279
## Dscrmn.position2  0.00017022 0.00019982
## Dffclt.position  -0.00617364 0.00299907
## Dffclt.position2  0.00071115 0.00012022

Comparison of the log-likelihood without and with DIF effects

logLik(eqINDLIK)
## 'log Lik.' -665.1837 (df=26)
logLik(dif_positions)
## 'log Lik.' -425.0873 (df=30)

2 DIF effects across groups

Load the data from the equateIRT package.

data("dataDIF", package = "equateIRT")
data1 <- dataDIF[dataDIF$group == 1, 1:20]
data2 <- dataDIF[dataDIF$group == 2, 1:20]
data3 <- dataDIF[dataDIF$group == 3, 1:20]

Estimate the item parameters separately for each group.

mod1 <- mirt(data1, SE = TRUE)
mod2 <- mirt(data2, SE = TRUE)
mod3 <- mirt(data3, SE = TRUE)
mods <- list(mod1, mod2, mod3)

Extract item parameter estimates and covariance matrices.

mods_extract <- modIRT(mods)

Estimate the equating coefficients (without accounting for DIF)

eqINDLIK <- multiec(mods_extract, method = "indlik")
## Computation of equating coefficients . . . . 
## Computation of standard errors  .  .  .  .
summary(eqINDLIK)
## Equating coefficients:
##  EQ Form Estimate   StdErr
##   A   T1  1.00000 0.000000
##   A   T2  1.14674 0.049193
##   A   T3  1.12120 0.051094
##   B   T1  0.00000 0.000000
##   B   T2  0.46127 0.056858
##   B   T3 -0.40303 0.056539

For fixed values of the tuning parameter \(\lambda\) estimate DIF effects and equating coefficients.

lambda <- seq(1, 100, by = 0.5)
out <- list()
for (i in 1:length(lambda))
{
  dif_lambda <- multiDIF(mods = mods_extract, start = eqINDLIK, 
    itempar.DIF = TRUE, lambda_mcp = lambda[i])
  out[[i]] <- dif_lambda
}

Select the tuning parameter \(\lambda\) on the basis of BIC

bic <- lapply(out, function(x) x$BIC)
sel_bic <- which.min(bic)
dif_param <- out[[sel_bic]]
summary(dif_param)
## Equating coefficients:
##  EQ Form Estimate StdErr
##   A   T1  1.00000     NA
##   A   T2  1.15141     NA
##   A   T3  1.14598     NA
##   B   T1  0.00000     NA
##   B   T2  0.48096     NA
##   B   T3 -0.49493     NA
## 
## Item-level DIF effects:
## Discrimination parameters
##                T1    T2 T3
## Dscrmn.I01 -0.901 -1.43  0
## Dscrmn.I02  0.000  0.00  0
## Dscrmn.I03  0.000  0.00  0
## Dscrmn.I04  0.000  0.00  0
## Dscrmn.I05  0.000  0.00  0
## Dscrmn.I06  0.000  0.00  0
## Dscrmn.I07  0.000  0.00  0
## Dscrmn.I08  0.000  0.00  0
## Dscrmn.I09  0.000  0.00  0
## Dscrmn.I10  0.000  0.00  0
## Dscrmn.I11  0.000  0.00  0
## Dscrmn.I12  0.000  0.00  0
## Dscrmn.I13  0.000  0.00  0
## Dscrmn.I14  0.000  0.00  0
## Dscrmn.I15  0.000  0.00  0
## Dscrmn.I16  0.000  0.00  0
## Dscrmn.I17  0.000  0.00  0
## Dscrmn.I18  0.000  0.00  0
## Dscrmn.I19  0.000  0.00  0
## Dscrmn.I20  0.000  0.00  0
## 
## Difficulty parameters
##            T1  T2    T3
## Dffclt.I01  0 0.6 -0.73
## Dffclt.I02  0 0.0  0.00
## Dffclt.I03  0 0.0  0.00
## Dffclt.I04  0 0.0  0.00
## Dffclt.I05  0 0.0  0.00
## Dffclt.I06  0 0.0  0.00
## Dffclt.I07  0 0.0  0.00
## Dffclt.I08  0 0.0  0.00
## Dffclt.I09  0 0.0  0.00
## Dffclt.I10  0 0.0  0.00
## Dffclt.I11  0 0.0  0.00
## Dffclt.I12  0 0.0  0.00
## Dffclt.I13  0 0.0  0.00
## Dffclt.I14  0 0.0  0.00
## Dffclt.I15  0 0.0  0.00
## Dffclt.I16  0 0.0  0.00
## Dffclt.I17  0 0.0  0.00
## Dffclt.I18  0 0.0  0.00
## Dffclt.I19  0 0.0  0.00
## Dffclt.I20  0 0.0  0.00

Only the first item shows DIF in both the difficulty and discrimination parameters.

References

Battauz, Michela. 2025. “Differential Item Functioning Detection Across Multiple Groups.” British Journal of Mathematical and Statistical Psychology, 1–19. https://doi.org/10.1111/bmsp.70023.