# ===========================================================================
# Example: Equating Form Y (New) to Form X (Base)
# ===========================================================================
set.seed(123)
# 1. Generate "True" Base Parameters (Form X)
# ---------------------------------------------------------------------------
# 10 Common Items (Anchors) + 10 Unique Items
# 2PL and GRM mixed
gen_item_params <- function(n, type="2PL") {
if(type=="2PL") {
data.frame(
item = paste0("Item_", 1:n),
model = "2PL",
a = round(runif(n, 0.8, 1.5), 2),
b = round(rnorm(n, 0, 1), 2),
stringsAsFactors = FALSE
)
} else {
# GRM with 3 thresholds
d <- t(apply(matrix(rnorm(n*3, 0, 0.5), n, 3), 1, sort))
df <- data.frame(
item = paste0("Poly_", 1:n),
model = "GRM",
a = round(runif(n, 0.8, 1.5), 2),
stringsAsFactors = FALSE
)
df <- cbind(df, setNames(as.data.frame(d), paste0("step_", 1:3)))
df
}
}
# Anchors
anchor_2pl <- gen_item_params(5, "2PL")
anchor_grm <- gen_item_params(3, "GRM")
# Unique Form X
unique_x <- gen_item_params(5, "2PL")
unique_x$item <- paste0("X_", unique_x$item)
base_params <- dplyr::bind_rows(anchor_2pl, anchor_grm, unique_x)
# 2. Generate "New" Form Y Parameters (with Scale Shift)
# ---------------------------------------------------------------------------
# Scale Transformation: Theta_base = 1.2 * Theta_new + 0.5
# True Constants: A = 1.2, B = 0.5
TRUE_A <- 1.2
TRUE_B <- 0.5
# Transform Anchor Parameters to "New" scale (Inverse Logic)
# a_new = a_base * A
# b_new = (b_base - B) / A
anchor_2pl_new <- anchor_2pl
anchor_2pl_new$a <- anchor_2pl$a * TRUE_A
anchor_2pl_new$b <- (anchor_2pl$b - TRUE_B) / TRUE_A
anchor_grm_new <- anchor_grm
anchor_grm_new$a <- anchor_grm$a * TRUE_A
step_cols <- grep("step_", names(anchor_grm_new))
anchor_grm_new[, step_cols] <- (anchor_grm[, step_cols] - TRUE_B) / TRUE_A
# Unique Form Y
unique_y <- gen_item_params(5, "2PL")
unique_y$item <- paste0("Y_", unique_y$item)
new_params <- dplyr::bind_rows(anchor_2pl_new, anchor_grm_new, unique_y)
# 3. Create Dummy Person Parameters for Form Y
# ---------------------------------------------------------------------------
person_params <- data.frame(
id = paste0("P", 1:50),
theta = rnorm(50, 0, 1),
theta_se = runif(50, 0.2, 0.5)
)
# 4. Perform Equating
# ---------------------------------------------------------------------------
# We expect to recover A approx 1.2 and B approx 0.5
results <- equate_irt(
base_params = base_params,
new_params = new_params,
person_params = person_params,
methods = c("Mean-Mean", "Stocking-Lord")
)
# 5. Inspect Results
# ---------------------------------------------------------------------------
# Linking Constants
print(results$linking_constants)
# Transformed Items (Form Y items on Form X scale)
head(results$transformed_item_params)
# Transformed Persons
head(results$transformed_person_params)
Run the code above in your browser using DataLab