Skip to content

Commit 65bf5bc

Browse files
committed
expose function
1 parent f0fa18e commit 65bf5bc

File tree

5 files changed

+209
-1
lines changed

5 files changed

+209
-1
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: mirt
2-
Version: 1.45.5
2+
Version: 1.45.6
33
Type: Package
44
Title: Multidimensional Item Response Theory
55
Authors@R: c( person("Phil", family="Chalmers", email =

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export(itemstats)
4949
export(key2binary)
5050
export(lagrange)
5151
export(likert2int)
52+
export(marginal_moments)
5253
export(marginal_rxx)
5354
export(mdirt)
5455
export(mirt)

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changes in mirt 1.46
22

3+
- Exposed `marginal_moments()` function to compute marginal item/bundle moment
4+
information for the scoring functions
5+
36
- Added `itemtype = 'monospline'` for the monotonic spline model
47

58
- `RCI()` gains logical argument `expected.scores` to convert factor scores into metric

R/marginal_moments.R

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#' Function to calculate the marginal moments for items and bundles fit via IRT models
2+
#'
3+
#' Given an estimated model and a prior density function, compute the marginal moments for either
4+
#' and item or a bundle of items. Currently limited to unidimensional IRT models.
5+
#'
6+
#' @param mod an object of class \code{'SingleGroupClass'} or \code{'MultipleGroupClass'}
7+
#' @param which.items vector indicating which items to use in the computation of the expected values.
8+
#' Default (\code{NULL}) uses all available items
9+
#' @param bundle logical; given \code{which.items}, should the composite of the response functions be used
10+
#' as a collective bundle? If \code{TRUE} then \code{\link{expected.test}} will be used, otherwise
11+
#' \code{\link{expected.item}} will be used
12+
#' @param group optional indicator to return only specific group information for multiple group models.
13+
#' Default compute moments for each group, returning a \code{list}
14+
#' @param density a density function to use for integration. Default assumes the latent traits are from a
15+
#' normal (Gaussian) distribution. Function definition must be of the form \code{function(quadrature, mean, sd)}
16+
#' as the values of the mean/variance are extracted and passed from the supplied model
17+
#' @param Theta_lim range of integration grid to use when forming expectations
18+
#' @param quadpts number of discrete quadrature to use in the computations
19+
#' @param ... additional arguments passed to the density function
20+
#'
21+
#' @author Phil Chalmers \email{rphilip.chalmers@@gmail.com}
22+
#' @references
23+
#' Chalmers, R., P. (2012). mirt: A Multidimensional Item Response Theory
24+
#' Package for the R Environment. \emph{Journal of Statistical Software, 48}(6), 1-29.
25+
#' \doi{10.18637/jss.v048.i06}
26+
#'
27+
#' @export
28+
#' @seealso \code{\link{expected.item}}, \code{\link{expected.test}}
29+
#' @examples
30+
#'
31+
#' \donttest{
32+
#'
33+
#' # single group
34+
#' dat <- expand.table(deAyala)
35+
#' mod <- mirt(dat)
36+
#' TS <- rowSums(dat)
37+
#'
38+
#' # expected moments of total scores given model
39+
#' marginal_moments(mod)
40+
#' c(mean=mean(TS), var=var(TS)) # first two moments of data
41+
#'
42+
#' # same, however focusing on individual items
43+
#' marginal_moments(mod, bundle = FALSE)
44+
#' cbind(mean=colMeans(dat), var=apply(dat, 2, var)) # first two moments of data
45+
#'
46+
#' ############################################
47+
#' ## same as above, however with multiple group model
48+
#'
49+
#' set.seed(1234)
50+
#' group <- sample(c('G1', 'G2'), nrow(dat), replace=TRUE)
51+
#' modMG <- multipleGroup(dat, group=group,
52+
#' invariance=c(colnames(dat), 'free_mean', 'free_var'))
53+
#' coef(modMG, simplify=TRUE)
54+
#'
55+
#' # expected moments of total scores given model
56+
#' marginal_moments(modMG)
57+
#' marginal_moments(modMG, group = 'G1') # specific group only
58+
#'
59+
#' # same, however focusing on individual items
60+
#' marginal_moments(modMG, bundle = FALSE)
61+
#'
62+
#'
63+
#' }
64+
marginal_moments <- function(mod, which.items = NULL, group = NULL, bundle = TRUE,
65+
density = NULL, Theta_lim = c(-6,6), quadpts = 121, ...){
66+
stopifnot(extract.mirt(mod, 'nfact') == 1L)
67+
if(!is.null(group))
68+
mod <- extract.group(mod, group=group)
69+
stopifnot(extract.mirt(mod, 'nfact') == 1) ## TODO: can make into a grid
70+
if(is(mod, 'MultipleGroupClass') && is.null(group)){
71+
grp <- extract.mirt(mod, 'groupNames')
72+
out <- lapply(grp, \(g)
73+
marginal_moments(mod=mod, which.items=which.items, group=g,
74+
bundle=bundle, density=density, Theta_lim=Theta_lim,
75+
quadpts=quadpts, ...))
76+
names(out) <- grp
77+
return(out)
78+
}
79+
stopifnot(is(mod, 'SingleGroupClass'))
80+
if(is.null(which.items))
81+
which.items <- 1:extract.mirt(mod, 'nitems')
82+
Theta <- matrix(seq(Theta_lim[1], Theta_lim[2], length.out=quadpts))
83+
if(is.null(density))
84+
density <- function(theta, mean, sd)
85+
dnorm(theta, mean=mean, sd=sd)
86+
cfs <- coef(mod, simplify=TRUE)
87+
den <- density(Theta, mean=cfs$means[1], sd=sqrt(cfs$cov[1,1]))
88+
den <- den / sum(den)
89+
if(bundle){
90+
Eitem <- expected.test(mod, Theta=Theta, which.items=which.items)
91+
E <- sum(Eitem * den)
92+
VAR <- sum((Eitem - E)^2 * den)
93+
SKEW <- sum((Eitem - E)^3 * den) / VAR^(3/2)
94+
KURT <- sum((Eitem - E)^4 * den) / VAR^2
95+
ret <- data.frame(MEAN=E, VAR=VAR, SKEW=SKEW, KURT=KURT)
96+
} else {
97+
ret <- as.data.frame(matrix(NA, ncol=4, nrow=length(which.items)))
98+
rownames(ret) <- extract.mirt(mod, 'itemnames')[which.items]
99+
for(i in 1:length(which.items)){
100+
pick <- which.items[i]
101+
ii <- extract.item(mod, item=pick)
102+
Eitem <- expected.item(ii, Theta=Theta)
103+
E <- sum(Eitem * den)
104+
VAR <- sum((Eitem - E)^2 * den)
105+
SKEW <- sum((Eitem - E)^3 * den) / VAR^(3/2)
106+
KURT <- sum((Eitem - E)^4 * den) / VAR^2
107+
ret[pick, ] <- c(E, VAR, SKEW, KURT)
108+
}
109+
}
110+
ret <- as.mirt_df(ret)
111+
colnames(ret) <- c('MEAN', 'VAR', 'SKEW', 'KURT')
112+
ret
113+
}

man/marginal_moments.Rd

Lines changed: 91 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)