lagrange: Lagrange test for freeing parameters

View source: R/lagrange.R

lagrangeR Documentation

Lagrange test for freeing parameters

Description

Lagrange (i.e., score) test to test whether parameters should be freed from a more constrained baseline model.

Usage

lagrange(mod, parnum, SE.type = "Oakes", type = "Richardson", ...)

Arguments

mod

an estimated model

parnum

a vector, or list of vectors, containing one or more parameter locations/sets of locations to be tested. See objects returned from mod2values for the locations

SE.type

type of information matrix estimator to use. See mirt for further details

type

type of numerical algorithm passed to numerical_deriv to obtain the gradient terms

...

additional arguments to pass to mirt

Author(s)

Phil Chalmers rphilip.chalmers@gmail.com

References

Chalmers, R. P. (2012). mirt: A Multidimensional Item Response Theory Package for the R Environment. Journal of Statistical Software, 48(6), 1-29. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.18637/jss.v048.i06")}

See Also

wald

Examples



dat <- expand.table(LSAT7)
mod <- mirt(dat, 1, 'Rasch')
(values <- mod2values(mod))

# test all fixed slopes individually
parnum <- values$parnum[values$name == 'a1']
lagrange(mod, parnum)

# compare to LR test for first two slopes
mod2 <- mirt(dat, 'F = 1-5
                   FREE = (1, a1)', 'Rasch')
coef(mod2, simplify=TRUE)$items
anova(mod, mod2)

mod2 <- mirt(dat, 'F = 1-5
                   FREE = (2, a1)', 'Rasch')
coef(mod2, simplify=TRUE)$items
anova(mod, mod2)

mod2 <- mirt(dat, 'F = 1-5
                   FREE = (3, a1)', 'Rasch')
coef(mod2, simplify=TRUE)$items
anova(mod, mod2)

# test slopes first two slopes and last three slopes jointly
lagrange(mod, list(parnum[1:2], parnum[3:5]))

# test all 5 slopes and first + last jointly
lagrange(mod, list(parnum[1:5], parnum[c(1, 5)]))

######
## DIF using score (Lagrange) test example

n <- 10
N <- 500

# generate 2PL data with DIF on Item_1's intercept in the focal group
a  <- matrix(rep(1, n), ncol = 1)
d1 <- matrix(rnorm(n), ncol = 1)
d2 <- d1
d2[1, 1] <- d1[1, 1] + 1          # shift Item_1's difficulty for the focal group

dat1 <- simdata(a, d1, N, itemtype = '2PL')
dat2 <- simdata(a, d2, N, itemtype = '2PL')
dat  <- rbind(dat1, dat2)
colnames(dat) <- paste0('Item_', 1:n)
group <- c(rep('Reference', N), rep('Focal', N))

# fully equality-constrained (no-DIF) baseline: all a1/d equated across
# groups, with the latent mean/variance freed in the focal group for
# identification (standard mirt DIF baseline)
mod_baseline <- multipleGroup(dat, model = 1, itemtype = '2PL', group = group,
                              invariance = c(colnames(dat), 'free_means', 'free_var'),
                              SE = TRUE)

values <- mod2values(mod_baseline)
(i1 <- values[values$item == 'Item_1', ])     # inspect parnum for this item

parnum_a1 <- i1$parnum[i1$name == 'a1' & i1$group == 'Focal']
parnum_d  <- i1$parnum[i1$name == 'd'& i1$group == 'Focal']

# joint 2-df score test: does freeing both a1 and d for Item_1 in the
# focal group improve fit relative to the constrained baseline?
lagrange(mod_baseline, list(c(parnum_a1, parnum_d)))

# compare to LR and Wald tests
mod_nest <- multipleGroup(dat, model = 1, itemtype = '2PL', group = group,
                              invariance = c(colnames(dat)[-1], 'free_means', 'free_var'),
                              SE = TRUE)
anova(mod_baseline, mod_nest)
wald(mod_nest)
wald(mod_nest, c('a1.1 = a1.43', 'd.2 = d.44'))

# separate 1-df tests: slope-only DIF vs. intercept-only DIF
lagrange(mod_baseline, list(parnum_a1, parnum_d))



mirt documentation built on Aug. 22, 2026, 9:07 a.m.