| grmforest | R Documentation |
This function implements a forest of graded response model trees (GRM Forest) using bootstrap aggregation (bagging) or random subsampling to enhance the detection and analysis of differential item functioning (DIF) in polytomous items. The GRM Forest approach combines the strengths of multiple GRMTrees to provide more robust and stable DIF detection, particularly for complex datasets with high-dimensional covariates or subtle DIF patterns.
grmforest(
formula,
data,
control = grmforest.control(),
tree_fun = grmtree,
tree_args = list(),
...
)
formula |
A formula specifying the model structure with the response
matrix on the left and partitioning variables on the right (e.g.,
|
data |
A data frame containing the response matrix and partitioning variables. The response matrix should contain polytomous items coded as ordered factors. |
control |
A control object created by |
tree_fun |
The tree-fitting function grown at each resample. Defaults to
|
tree_args |
A named list of extra arguments passed on to |
... |
Additional arguments passed to the tree-fitting function
( |
Each tree is grown by grmtree() on a resample of the rows of data. Rows
not selected form that tree's out-of-bag (OOB) sample, which is used by
varimp() and never enters that tree's fitting.
Setting mtry in grmforest.control() offers a fresh random subset of
partitioning variables at every node, decorrelating the trees. Leaving
mtry = NULL grows a bagged ensemble in which every tree sees every
variable at every node; such trees are highly correlated, which limits the
variance reduction the ensemble can deliver and can make importance scores
harder to interpret when partitioning variables are themselves correlated.
Out-of-bag membership is stored as row indices rather than as copies of the
data, which keeps the fitted object small and lets forests grown separately
be combined with c.grmforest().
Key advantages of the GRM Forest approach include:
Enhanced stability in DIF detection across different sampling variations
Robust variable importance measures that quantify the relative contribution of each covariate to DIF patterns
Reduced false positive rates through consensus-based detection
Ability to handle high-dimensional covariate spaces effectively
Internal validation through out-of-bag error estimation
The forest implementation supports both bootstrap aggregation (where samples are drawn with replacement) and subsampling (without replacement), allowing flexibility for different data characteristics and research objectives.
An object of class grmforest, a list with components:
trees |
List of fitted |
oob_indices |
List of integer vectors giving, for each tree, the row
positions of |
in_indices |
List of integer vectors giving the rows used to fit each tree. |
formula |
The model formula. |
data |
The original data frame. |
control |
The control object used. |
call |
The matched call. |
Model-based recursive partitioning selects each split point by refitting the
node model at every admissible cut point on the selected variable. For
continuous covariates with many distinct values this dominates run time, and
cost grows with the number of items and response categories. Practical
levers, roughly in order of effect: bin continuous partitioning variables to
a manageable number of candidate cut points before fitting; raise
minbucket; set mtry; and increase n_cores.
grmtree fits a Graded Response Model Tree,
grmtree.control creates a control object for grmtree,
grmforest.control creates a control object for grmforest,
c.grmforest combines grmforest objects,
varimp calculates the variable importance for GRM Forest,
plot.varimp creates a bar plot of variable importance scores
library(grmtree)
library(hlt)
data("asti", package = "hlt")
asti$resp <- data.matrix(asti[, 1:4])
# Fit forest with default parameters
forest <- grmforest(resp ~ gender + group, data = asti)
# Fit with custom control
ctrl <- grmforest.control(n_tree = 20, sampling = "subsample")
forest <- grmforest(resp ~ gender + group, data = asti, control = ctrl)
#' ## Longitudinal GRM forest: same engine, longitudinal tree
data("grmtree_long_data", package = "grmtree")
items_t1 <- c("MOS_Listen", "MOS_Info", "MOS_Advice_Crisis", "MOS_Confide",
"MOS_Advice_Want", "MOS_Fears", "MOS_Personal", "MOS_Understand")
ld <- prepare_longitudinal_data(
data = grmtree_long_data, items_t1 = items_t1,
items_t2 = paste0(items_t1, "_year1"),
covariates = c("sex", "age", "residency", "job",
"education", "comorbidity_count", "ever_smoker"))
lforest <- grmforest(
resp_wide ~ sex + age + residency + job +
education + comorbidity_count + ever_smoker,
data = ld,
control = grmforest.control(n_tree = 20, seed = 123,
control = grmtree.control(minbucket = 200)),
tree_fun = longitudinal_grmtree, tree_args = list(n_items = 8))
print(lforest)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.