% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/sim_tirt.R
\name{sim_tirt}
\alias{sim_tirt}
\title{Simulate Mixed IRT and Testlet (TRT) Data}
\usage{
sim_tirt(
  n_people = 1000,
  item_structure = list(),
  theta = NULL,
  theta_mean = 0,
  theta_sd = 1
)
}
\arguments{
\item{n_people}{Integer. Number of examinees.}

\item{item_structure}{List of lists defining item blocks (see Details).}

\item{theta}{Numeric vector (Optional). If provided, these exact ability
values are used.}

\item{theta_mean}{Numeric. Mean of the latent trait (used if \code{theta} is
\code{NULL}).}

\item{theta_sd}{Numeric. SD of the latent trait (used if \code{theta} is
\code{NULL}).}
}
\value{
A list containing:
\item{resp}{data.frame of responses (rows = people, cols = items).}
\item{true_item_params}{data.frame of true item parameters, including a
\code{model} column and a \code{testlet} column (\code{NA} for
independent items). Its \code{item_id}, \code{model}, and \code{testlet}
columns provide everything needed to build the \code{item_spec} argument
of \code{\link{irt_trt}} (rename \code{item_id} to \code{item}).}
\item{true_person_params}{data.frame of true person parameters: the primary
ability plus one gamma column per testlet.}
}
\description{
Simulates a data set that mixes ordinary independent item response theory
items with testlet (locally dependent) items in a single test form, the
simulation counterpart of \code{\link{irt_trt}}. Independent blocks depend
only on the primary trait (theta); testlet blocks additionally depend on a
testlet-specific nuisance effect (gamma). Both dichotomous and polytomous
formats are supported for the independent and the testlet parts, so the whole
family of models handled by \code{\link{irt_trt}} can be generated at once.
}
\details{
Each element of \code{item_structure} is a list describing one block. The
\code{model} name determines whether the block is independent or a testlet:
\itemize{
\item Independent (theta only): \code{"Rasch"}, \code{"2PL"}, \code{"3PL"},
\code{"PCM"}, \code{"GPCM"}, \code{"GRM"}.
\item Testlet (theta + gamma): \code{"RaschT"}, \code{"2PLT"},
\code{"3PLT"}, \code{"BiFT"}, \code{"PCT"}, \code{"GPCT"}, \code{"GRT"}.
}
Other recognized keys are \code{n_items}, \code{categories} (polytomous),
\code{a}, \code{b}, \code{c} (given as a fixed value or a \code{c(lo, hi)}
range to sample from), \code{s} (testlet loading for \code{"BiFT"}),
\code{testlet_id} (the testlet label, required for testlet blocks),
\code{testlet_var} (variance of the gamma effect), and \code{gamma_vector}
(a user-supplied gamma effect of length \code{n_people}).
}
\examples{
  # A form with independent items and two testlets
  set.seed(2025)
  design <- list(
    list(model = "2PL",  n_items = 8),                       # independent
    list(model = "GRM",  n_items = 4, categories = 3),       # independent poly
    list(model = "2PLT", n_items = 4, testlet_id = "P1",
         testlet_var = 0.6),                                 # testlet
    list(model = "GPCT", n_items = 3, categories = 3,
         testlet_id = "P2", testlet_var = 0.5)               # testlet poly
  )

  sim <- sim_tirt(n_people = 600, item_structure = design)

  head(sim$resp)
  sim$true_item_params[, c("item_id", "model", "testlet")]
  head(sim$true_person_params)

  \donttest{
  # Feed the true structure straight into the joint estimator
  spec <- data.frame(
    item = sim$true_item_params$item_id,
    model = sim$true_item_params$model,
    testlet = sim$true_item_params$testlet,
    stringsAsFactors = FALSE
  )
  fit <- irt_trt(sim$resp, spec, method = "EM",
                 control = list(max_iter = 15, verbose = FALSE))
  head(fit$item_params)
  }
}
\seealso{
\code{\link{irt_trt}}, \code{\link{sim_trt}}, \code{\link{sim_irt}}
}
