Package {csemGT}


Type: Package
Title: Conditional Standard Error of Measurement in Generalizability Theory
Version: 1.0.0
Description: Estimates the per-person conditional standard error of measurement (CSEM) under the persons-by-items single-facet crossed design of Generalizability Theory, following Brennan (1998) <doi:10.1177/014662169802200401>. Implements three estimators of the relative error variance (full, large_a, uncorrelated) and the closed-form absolute error variance, with both analytical and item-resampling bootstrap sampling variances, quadratic smoothing of CSEMs on observed score, D-study extrapolation, and base-graphics plotting.
License: GPL (≥ 3)
Encoding: UTF-8
LazyData: true
Depends: R (≥ 4.1.0)
Imports: stats, utils, graphics, grDevices
Suggests: boot, mgcv, ggplot2, knitr, rmarkdown, testthat (≥ 3.0.0), vdiffr, covr, spelling, mirt, haven
Config/testthat/edition: 3
VignetteBuilder: knitr
URL: https://github.com/rgempp/csemGT, https://gempp.cl/csemGT/
BugReports: https://github.com/rgempp/csemGT/issues
Language: en-GB
Config/roxygen2/version: 8.0.0
NeedsCompilation: no
Packaged: 2026-05-28 13:42:59 UTC; rene.gempp
Author: René Gempp ORCID iD [aut, cre, cph]
Maintainer: René Gempp <rene.gempp@udp.cl>
Repository: CRAN
Date/Publication: 2026-06-01 09:10:08 UTC

csemGT: Conditional Standard Errors of Measurement in Generalizability Theory

Description

Estimates the conditional standard error of measurement (CSEM) within the Generalizability Theory framework for the univariate, single-facet, persons-by-items (p x i) crossed design (Brennan, 1998). Returns person-level CSEM estimates for absolute and relative error variances, three estimators of the relative error variance ('full', 'large_a', 'uncorrelated'), closed-form analytical and item-resampling bootstrap sampling variances, quadratic smoothing of CSEMs on observed score, and D-study extrapolation.

Main function

The user-facing function is 'csem_gt()' (implemented in Sprint 2 of the csemGT pilot).

Author(s)

Maintainer: René Gempp rene.gempp@udp.cl (ORCID) [copyright holder]

Authors:

References

Brennan, R. L. (1998). Raw-score conditional standard errors of measurement in generalizability theory. Applied Psychological Measurement, 22(4), 307-331.

Brennan, R. L. (2001). Generalizability theory. Springer.

See Also

Useful links:


Smooth 'csem_var.*' columns of a per-person wide table

Description

For each 'csem_var.<suffix>' column in 'per_person_wide', fits an ordinary least squares polynomial regression of the variance on the observed score and takes the square root of the fitted values, leaving the smoothed CSEM undefined ('NA') where the fitted variance is negative, and writes the result back as 'smoothed_csem.<suffix>'. Smoother diagnostics (intercept, slope, quadratic coefficient, R^2, RMSE, sample size used for the fit) are returned as an 'attr(<>, "smooth_fits")'.

Usage

.apply_smoother(
  per_person_wide,
  smoother = "polynomial",
  smoother_args = list(degree = 2),
  exclude_extremes = FALSE,
  score_extremes = NULL
)

Arguments

per_person_wide

Data frame with at least 'observed_score' and one or more 'csem_var.<suffix>' columns.

smoother

Character; '"polynomial"' (default) or '"none"'. The '"none"' value returns the input unchanged.

smoother_args

Named list. The element 'degree' controls the polynomial degree (default 2).

exclude_extremes

Logical; if 'TRUE', rows of 'per_person_wide' whose 'observed_score' is in 'score_extremes' are excluded from the OLS fit and their smoothed values are set to 'NA'.

score_extremes

Numeric vector of scores to exclude when 'exclude_extremes = TRUE'. Typically 'c(0, J)'.

Details

The RMSE reported here is the population-style residual standard deviation 'sqrt(SSE / N)', matching the convention used by 'gtcsem.ado' (see '_gtcsem_qfit') rather than the small-sample adjusted 'sqrt(SSE / (N - k - 1))' that 'summary(lm(.))$sigma' returns. This choice preserves cross-package parity.

Value

The input 'per_person_wide' with new 'smoothed_csem.<suffix>' columns and two attributes: '"smooth_fits"' (a named list, one element per smoothed suffix) and '"smoothing_diagnostics"' (a list with 'n_floor', 'n_ceiling', 'n_fit' — the floor, ceiling, and fit-sample counts when 'exclude_extremes = TRUE', all 'NA' when extremes are retained). The 'smoother = "none"' passthrough sets neither attribute.


Collapse a person-level wide table to a by-score wide table

Description

Inverse of '.expand_to_person()'. For each distinct value of 'observed_score', returns a single row containing the value of every estimation column at that score. Under the GT model the conditional error variance is a function of the score (or, for 'full' and 'large_a', additionally of within-score variability — see Brennan, 1998), so per-person values within a score are not necessarily identical. Non-identical values are collapsed by the within-score mean. Heterogeneity is by design for 'cov_xim' and the 'full' and 'large_a' estimators, so it is collapsed silently; for the score-conditioned estimators ('absolute', 'relative_uncorrelated') a single descriptive message names the affected columns.

Usage

.collapse_to_score(per_person_wide)

Arguments

per_person_wide

A data frame in person-level wide format with columns 'observed_score' plus any number of estimation columns.

Value

A data frame with one row per distinct observed score and identifier columns 'observed_score' and 'group_size'.


Extract the population-level global statistics of a 'csem' object

Description

Pulls the relative and absolute standard errors of measurement and their companion reliability-like coefficients out of the 'variance_components' component. Internal helper for [summary.csem()].

Usage

.compute_global_stats(object)

Arguments

object

A 'csem' object.

Value

A named list with 'relative_sem', 'erho2', 'absolute_sem' and 'phi'.


Expand a by-score wide table to one row per person

Description

Given a wide-format 'by_score' table (one row per distinct value of the conditioning variable) and a vector of per-person observed scores, returns the corresponding person-level table by matching each person's score to the row of 'by_score'. Persons whose score is not represented in 'by_score' receive 'NA' values in all expanded columns and trigger a warning.

Usage

.expand_to_person(by_score_wide, X, person_id)

Arguments

by_score_wide

A data frame in wide format with identifier columns 'observed_score' and 'group_size', plus any number of estimation columns (e.g. 'csem.absolute', 'csem_var.relative_full', 'smoothed_csem.absolute', etc.).

X

Numeric vector of length N (the conditioning value per person; typically the row sum of 'data' when 'conditioning = "total"').

person_id

Vector of length N with person identifiers.

Value

A data frame with N rows containing the identifier columns 'person_id', 'observed_score', 'conditioning_value', 'group_size', 'extreme', followed by the expanded estimation columns from 'by_score_wide'.


Attach bootstrap-based standard errors to the per-person long table

Description

Given a per-person long table (long-tidy format, one row per (person, estimator) pair) with at least columns 'person_id', 'estimator', and 'csem', this helper reads the per-person bootstrap variances produced by '.item_bootstrap()' or '.person_bootstrap()' and attaches two columns: 'csem_var.boot' and 'se.boot'.

Usage

.gt_add_bootstrap_se(per_person_long, boot_results)

Arguments

per_person_long

Data frame in long-tidy format, with at least 'person_id', 'estimator', 'csem'.

boot_results

Output of '.item_bootstrap()' or '.person_bootstrap()'; its 'per_person_variance' matrix must have column names identifying the estimators.

Details

Scale. The bootstrap engines return 'per_person_variance' on the ERROR-VARIANCE scale (the sampling variance of \hat V_p). This helper converts to the CSEM scale via the delta method \mathrm{Var}(\sqrt{V}) \approx \mathrm{Var}(V) / (4 V), using the per-person point estimate 'csem' (which is \sqrt{V_p}) as the evaluation point. The result 'csem_var.boot' is therefore on the CSEM scale, dimensionally consistent with 'se.analytic' from '.gt_add_analytical_se()' and with the Wald intervals built by '.gt_add_ci()'. Rows with 'csem <= 0' (or NA) receive NA, since the delta-method denominator is not defined there.

This helper performs SE attachment only. Confidence intervals are attached separately by '.gt_add_ci()' (spec v4 §5.3, steps 8 and 9).

Value

The input data frame augmented with 'csem_var.boot' and 'se.boot'. Estimators present in 'per_person_long$estimator' but absent from the bootstrap result trigger a warning and receive NA.


Item-resampling bootstrap for the GT CSEM estimators

Description

Implements the default bootstrap of 'csem_gt()'. For each person, draws 'R' independent samples of items with replacement (each of size J = 'ncol(data)'), recomputes the four GT per-person estimators on every resampled item set, and returns the per-person empirical variances across the 'R' replicates.

Usage

.item_bootstrap(
  data,
  vc,
  n_items_D = NULL,
  R = 1000L,
  seed = NULL,
  return_replicates = FALSE,
  verbose = FALSE
)

Arguments

data

Numeric matrix N \times J.

vc

Output of '.gt_variance_components(data)' — the variance components and per-person ingredients from the ORIGINAL sample (NOT from any bootstrap resample). Item bootstrap holds 'sigma2_i' and 'b_vec' fixed across replicates; this is the parity anchor against the legacy and '.ado' implementations.

n_items_D

Positive scalar; D-study number of items. Defaults to 'ncol(data)'.

R

Integer; number of bootstrap replications. Default 1000.

seed

Integer or 'NULL'; seed for reproducibility.

return_replicates

Logical; if 'TRUE', also returns the per-person mean of the replicate estimates in component '$replicates'.

verbose

Logical; emit progress messages every 100 persons.

Details

Rationale: item resampling preserves the per-person interpretation of the conditional SEM (the unit of resampling is the same as the unit of replication that underlies the estimator), matching the 'gtcsem.ado' Stata implementation. See also the legacy R reference 'bootstrap_csem_g1f()' in 'inst/legacy/'.

Value

A named list with components 'type = "item"', 'R', 'seed', and 'per_person_variance' (an N \times 4 matrix with columns 'c("absolute", "relative_full", "relative_large_a", "relative_uncorrelated")'). When 'return_replicates = TRUE', a '$replicates' element of the same shape contains the per-person mean across replicates for each estimator.


Person-resampling bootstrap for the GT CSEM estimators

Description

Resamples persons with replacement, refits the variance components, and recomputes the per-person CSEMs on every replicate. The per-person sampling variance is then evaluated by aligning the replicate estimates with the original person index (or, equivalently for csem_gt, with the score level) and computing the empirical variance across replicates.

Usage

.person_bootstrap(
  data,
  vc,
  n_items_D = NULL,
  X,
  paradigm = "gt",
  method = c("full", "large_a", "uncorrelated"),
  error_type = c("absolute", "relative"),
  R = 1000L,
  seed = NULL,
  return_replicates = FALSE,
  verbose = FALSE
)

Arguments

data

Numeric matrix N \times J.

vc

Output of '.gt_variance_components(data)' from the ORIGINAL sample. Used only for dimensions (N, J) and for fall-back; each replicate recomputes its own vc internally.

n_items_D

Positive scalar; D-study number of items. Defaults to 'ncol(data)'.

X

Numeric vector of length N; conditioning value per person, used to aggregate replicate estimates by score level.

paradigm

Character; currently must be '"gt"'.

method, error_type

Resolved arguments of 'csem_gt()'. Accepted for API compatibility with Sprint 1 tests but not used internally — the helper always returns all four estimators and downstream filtering is done by the orchestrator.

R

Integer; number of bootstrap replications. Default 1000.

seed

Integer or 'NULL'; seed for reproducibility.

return_replicates

Logical; if 'TRUE', also returns the per-person mean of the replicate estimates in component '$replicates'.

verbose

Logical.

Value

A list with the same shape as '.item_bootstrap()' but 'type = "person"'.


Compute confidence-band vertices for a CSEM plot

Description

Builds the ribbon vertices consumed by [.plot_csem_single()] when 'plot_type' is '"ci"' or '"both"'. Two band sources are supported, following the 'gtcsem_plot' Stata command:

Usage

.plot_csem_bands(x, series, cibands, asemethod, ci_level)

Arguments

x

A 'csem' object.

series

A single series descriptor from [.resolve_plot_columns()].

cibands

Band source: '"person"' or '"model"'.

asemethod

Sampling-SE source for 'cibands = "person"': '"analytical"' or '"bootstrap"'. Ignored when 'cibands = "model"'.

ci_level

Confidence level for the band.

Details

* 'cibands = "person"' — a band around the by-score CSEM curve, \widehat{csem} \pm z\, \widehat{se}, where \widehat{se} is the per-person sampling SE of the CSEM collapsed to the score level ('se.analytic.*' or 'se.boot.*', selected by 'asemethod'). The lower edge is truncated at zero. The ribbon is restricted to the non-extreme score range when the fit excluded extremes from the smoother (mirroring the 'keep' filter of 'gtcsem_plot'). * 'cibands = "model"' — a band around the quadratic smoother. The per-person error variance is refit on the observed score and its square by ordinary least squares, over the same non-extreme sample the smoother used. Because that is the same fit '.apply_smoother()' performs, the band centre coincides with the stored 'smoothed_csem.*' curve; 'predict(se.fit = TRUE)' supplies the SE of the mean fit, which the delta method converts to the CSEM scale as se.fit / (2\, \widehat{csem}). 'asemethod' is ignored for this source.

Value

A list with numeric vectors 'x' (the sorted score grid), 'lo' and 'hi' (the ribbon edges) and 'center' (the curve the band is built around).


Draw the compare layout overlaying the relative estimators

Description

Implements the compare layout of [plot.csem()]: the three relative-error estimators ('relative_full', 'relative_large_a', 'relative_uncorrelated') are overlaid on one panel with a legend, so their smoother curves can be read against each other. By default only the curves are drawn; 'compare_points = TRUE' adds the per-person scatter for every estimator.

Usage

.plot_csem_compare(
  x,
  series_list,
  theme_settings,
  compare_points = FALSE,
  show_smooth = TRUE,
  cex = NULL,
  lwd = 2,
  lty = 1,
  alpha = NULL,
  main = NULL,
  sub = NULL,
  xlab = NULL,
  ylab = NULL,
  ylim = NULL,
  xlim = NULL,
  ...
)

Arguments

x

A 'csem' object.

series_list

A list of three series descriptors from [.resolve_plot_columns()].

theme_settings

A list from [.resolve_plot_theme()].

compare_points

Logical; also draw the per-person scatter for each estimator.

show_smooth

Logical; draw the smoother curves.

cex, lwd, lty, alpha

Graphical overrides passed through to each series. 'pch' is not an override here: each estimator uses a fixed symbol from the package symbol map (open circle / diamond / triangle), parallel to its palette colour.

main, sub, xlab, ylab, ylim, xlim

Annotation and axis overrides. 'main' defaults to the shared '"Relative conditional SEM"' label; 'ylim', when 'NULL', is shared across the three series.

...

Passed to the underlying 'plot()' call.

Details

Each estimator keeps its own palette colour, so a user-supplied 'col' is not applied here. No confidence ribbon is drawn – three overlapping ribbons would not be legible – so 'bands' is 'NULL' throughout and the inner 'plot_type' only toggles the scatter: '"csem"' draws it, '"ci"' (with 'bands = NULL') suppresses both the scatter and the ribbon, leaving the curve alone.

Value

The y-axis limits used, invisibly.


Draw the side-by-side layout for two error types

Description

Implements the two-panel layout of [plot.csem()]: when both error types are requested, the absolute and relative CSEMs are drawn as a pair of panels on one shared y-axis, so they are read on a common vertical scale. Each panel is rendered by [.plot_csem_single()] with 'manage_par = FALSE', the orchestrator owning the 'mfrow' layout state. Each panel keeps its own series label as its title; a user-supplied 'main' is not applied in this layout.

Usage

.plot_csem_sidebyside(
  x,
  series_list,
  theme_settings,
  plot_type = "csem",
  cibands = "person",
  asemethod = "analytical",
  ci_level = 0.95,
  show_smooth = TRUE,
  col = NULL,
  pch = 16,
  cex = NULL,
  lwd = 2,
  lty = 1,
  alpha = NULL,
  sub = NULL,
  xlab = NULL,
  ylab = NULL,
  xlim = NULL,
  ...
)

Arguments

x

A 'csem' object.

series_list

A list of two series descriptors from [.resolve_plot_columns()].

theme_settings

A list from [.resolve_plot_theme()].

plot_type

One of '"csem"', '"ci"', '"both"'.

cibands, asemethod, ci_level

Confidence-band controls, passed to [.plot_csem_bands()] for each panel.

show_smooth

Logical; overlay the smoother curve when available.

col, pch, cex, lwd, lty, alpha

Graphical overrides passed through to each panel.

sub, xlab, ylab, xlim

Annotation and axis overrides passed through to each panel. 'sub' defaults, when bands are drawn, to the same confidence-level subtitle on both panels.

...

Passed to the underlying 'plot()' calls.

Value

The shared y-axis limits, invisibly.


Draw a single-panel CSEM plot

Description

Implements the single-panel layout of [plot.csem()]: a per-person scatter of the conditional SEM against the observed score, an optional quadratic-smoother curve, and an optional confidence-band ribbon. The scatter is drawn from the per-person '$estimates' table; the smoother curve from the score-level '$by_score' table; the ribbon from the vertices computed by [.plot_csem_bands()].

Usage

.plot_csem_single(
  x,
  series,
  theme_settings,
  show_smooth,
  plot_type,
  bands,
  manage_par = TRUE,
  col,
  pch,
  cex,
  lwd,
  lty,
  alpha,
  main,
  sub,
  xlab,
  ylab,
  ylim,
  xlim,
  add,
  ...
)

Arguments

x

A 'csem' object.

series

A single series descriptor from [.resolve_plot_columns()].

theme_settings

A list from [.resolve_plot_theme()].

show_smooth

Logical; draw the smoother curve when available.

plot_type

One of '"csem"', '"ci"', '"both"'. The scatter is drawn for '"csem"' and '"both"'; the ribbon for '"ci"' and '"both"'.

bands

A list of ribbon vertices from [.plot_csem_bands()], or 'NULL' when no ribbon is drawn.

manage_par

Logical; if 'TRUE' (the default) the helper saves, sets and restores the graphical parameters ('mar', 'mgp', 'tcl', 'las') itself. The side-by-side orchestrator passes 'FALSE' so it can own the layout state ('mfrow') without the per-panel save/restore resetting it.

col, pch, cex, lwd, lty, alpha

Graphical overrides; 'NULL' means "use the theme or calibrated default".

main, sub, xlab, ylab, ylim, xlim

Annotation and axis overrides; 'NULL' means "use a sensible default".

add

Logical; if 'TRUE', draw onto the current plot without opening a new one.

...

Passed to the underlying 'plot()' call.

Details

Layering, back to front: faint horizontal grid, the confidence ribbon, the per-person scatter, the smoother curve.

Value

'NULL', invisibly.


Resolve which estimator series a plot call should draw

Description

Translates the 'error_types' / 'method' / 'compare_methods' arguments of [plot.csem()] into a list of series descriptors, one per estimator to be drawn. Each descriptor carries the estimator key, the names of the point-estimate, error-variance, sampling-SE and smoothed columns, a display label, a short label for legends, and the palette colour.

Usage

.resolve_plot_columns(x, error_types, method, compare_methods)

Arguments

x

A 'csem' object.

error_types

Character vector of error types to plot.

method

Relative-error estimator to use for 'error_types' containing '"relative"'.

compare_methods

Logical; if 'TRUE', the three relative-error estimators are returned regardless of 'error_types' and 'method'.

Details

The sampling-SE and error-variance column names are constructed but not validated here: a fit may legitimately lack 'se.boot.*' (no bootstrap was run), and whether a given band source needs a given column is decided by [.plot_csem_bands()] at band-computation time.

Value

A list of series descriptors (each itself a list).


Resolve a plot theme to its concrete settings

Description

Maps a 'theme' name to the list of concrete settings consumed by the plotting helpers. csemGT ships a single own theme, '"csem"'; the argument is kept as a vector for forward extension.

Usage

.resolve_plot_theme(theme = c("csem"))

Arguments

theme

Theme name; currently only '"csem"'.

Value

A list with the palette and the structural (grid) colour.


Restore a previously captured RNG seed

Description

Restores the global '.Random.seed' from a value captured earlier by '.set_seed_restoring()'. If 'old_seed' is 'NULL' the seed is removed (returning the RNG to a "no seed set yet" state), reproducing the state the session was in before the seed was modified.

Usage

.restore_seed(old_seed)

Arguments

old_seed

Integer vector previously captured, or 'NULL'.

Value

Invisibly 'NULL'.


Set the RNG seed while remembering the prior state

Description

Captures the current value of '.Random.seed' (or 'NULL' if no seed has been set in the session), calls 'base::set.seed()' with the user-supplied seed, and returns the captured state. The caller is responsible for restoring the prior state using '.restore_seed()' via an 'on.exit()' registration, e.g.:

Usage

.set_seed_restoring(seed)

Arguments

seed

Integer or numeric scalar passed to 'base::set.seed()'.

Details

if (!is.null(seed)) {
  old_seed <- .set_seed_restoring(seed)
  on.exit(.restore_seed(old_seed), add = TRUE)
}

This pattern keeps the public function reproducible without leaking a deterministic state into the user's session.

Value

Invisibly the previous value of '.Random.seed', or 'NULL' if none was set.


Lightweight check of scalar arguments supplied to csem_gt()

Description

Validates types and ranges of the scalar arguments that 'csem_gt()' accepts. Numeric requirements are enforced (e.g. 'R >= 100', 'ci_level in (0, 1)'); logical flags are checked for length 1.

Usage

.validate_args(
  ci_level = 0.95,
  R = 1000L,
  n_items_D = NULL,
  cutpoint = NULL,
  seed = NULL,
  bootstrap = FALSE,
  return_analytical = TRUE,
  exclude_extremes = FALSE,
  truncate_vc = FALSE,
  truncate_negative_error_var = FALSE,
  boot_keep_replicates = FALSE,
  verbose = FALSE
)

Arguments

ci_level, R, n_items_D, cutpoint, seed

As in 'csem_gt()'.

bootstrap, return_analytical, exclude_extremes, truncate_vc, truncate_negative_error_var, boot_keep_replicates, verbose

As in 'csem_gt()'.

Value

Invisibly 'TRUE'.


Validate the input data matrix

Description

Coerces a data frame or matrix to a numeric matrix and checks the preconditions of the persons-by-items single-facet crossed design: all columns numeric, no missing values (the legacy 'csem_g1f()' and 'gtcsem.ado' both require complete balanced data), and at least 2 persons by 2 items.

Usage

.validate_data(
  data,
  na_action = "listwise",
  require_balanced = TRUE,
  require_complete = TRUE,
  require_dichotomous = FALSE
)

Arguments

data

Matrix or data frame, persons in rows, items in columns.

na_action

Character; one of '"listwise"', '"fail"', '"pairwise"'. In 'csemGT' v1.0 only '"listwise"' and '"fail"' are supported.

require_balanced

Logical; reserved for future designs. Currently the single-facet crossed design is always balanced by construction.

require_complete

Logical; if 'TRUE' (default), an error is raised when missing values remain after 'na_action' is applied.

require_dichotomous

Logical; reserved for future use. Ignored in 'csemGT'.

Value

A numeric matrix, persons in rows, items in columns.


Validate the error_type argument

Description

Enforces the paradigm-specific set of allowed values for 'error_type'. For 'csem_gt()', both '"absolute"' and '"relative"' are valid.

Usage

.validate_error_type(method, error_type, paradigm = "gt")

Arguments

method

Character vector of resolved methods.

error_type

Character vector supplied by the user.

paradigm

Character scalar.

Value

The validated character vector (subset of valid values).


Validate the method argument against the paradigm's valid set

Description

Validate the method argument against the paradigm's valid set

Usage

.validate_method(method, valid, paradigm = "gt")

Arguments

method

Character vector supplied by the user.

valid

Character vector of allowed methods.

paradigm

Character scalar (for error messages).

Value

The validated character vector (subset of 'valid').


Coerce a 'csem' object to a data frame

Description

Returns one of the two wide-format tables carried by a 'csem' object: the person-level table ('by = "person"', the default) or the score-level table ('by = "score"').

Usage

## S3 method for class 'csem'
as.data.frame(
  x,
  row.names = NULL,
  optional = FALSE,
  by = c("person", "score"),
  ...
)

Arguments

x

A 'csem' object.

row.names, optional

Accepted for consistency with the [base::as.data.frame()] generic; both are ignored.

by

One of '"person"' (the default) or '"score"'. '"person"' returns the per-person '$estimates' table; '"score"' returns the '$by_score' table.

...

Currently ignored.

Value

A data frame: '$estimates' when 'by = "person"', '$by_score' when 'by = "score"'.

See Also

[by_score()] for the score-level table through a dedicated accessor; [coef.csem()] for the variance components.

Examples

set.seed(1)
d <- matrix(rbinom(60 * 12, 1, 0.5), nrow = 60)
fit <- csem_gt(d, error_type = "absolute")
head(as.data.frame(fit))                 # by = "person"
head(as.data.frame(fit, by = "score"))


Extract the score-level table from a 'csem' object

Description

'by_score()' returns the score-level summary table of a 'csem' object: one row per distinct observed score, with the estimation columns collapsed to that score. It is the accessor-style equivalent of the '$by_score' component and of 'as.data.frame(x, by = "score")'.

Usage

by_score(x, ...)

## S3 method for class 'csem'
by_score(x, ...)

Arguments

x

A 'csem' object.

...

Currently ignored; present for S3 extensibility.

Value

A data frame with one row per distinct observed score.

See Also

[as.data.frame.csem()] for the person-level and score-level tables through the 'as.data.frame' interface; [coef.csem()] for the variance components.

Examples

set.seed(1)
d <- matrix(rbinom(60 * 12, 1, 0.5), nrow = 60)
fit <- csem_gt(d, error_type = "absolute")
head(by_score(fit))


Extract the variance components of a 'csem' object

Description

Returns the 'variance_components' list of a 'csem' object: the ANOVA table, the person / item / residual variance components, the population-level error variances and SEMs, and the reliability-like coefficients. For the GT paradigm this is the natural set of fitted "coefficients", so it is what 'coef()' returns.

Usage

## S3 method for class 'csem'
coef(object, ...)

Arguments

object

A 'csem' object.

...

Currently ignored.

Value

The 'variance_components' list of 'object'. See [csem_gt()] for its structure.

See Also

[by_score()] and [as.data.frame.csem()] for the estimation tables.

Examples

set.seed(1)
d <- matrix(rbinom(60 * 12, 1, 0.5), nrow = 60)
fit <- csem_gt(d, error_type = "absolute")
coef(fit)$reliability_coefficients


Conditional standard errors of measurement under Generalizability Theory

Description

Estimates conditional standard errors of measurement (CSEMs) for the univariate, single-facet, persons-by-items (p x i) crossed design following Brennan (1998). Returns absolute and relative error variances, three estimators of the relative error variance, closed-form analytical sampling variances, optional item-resampling bootstrap, quadratic smoothing, and D-study extrapolation.

Usage

csem_gt(
  data,
  method = c("full", "large_a", "uncorrelated"),
  error_type = c("absolute", "relative"),
  conditioning = "total",
  n_items_D = NULL,
  bootstrap = FALSE,
  R = 1000L,
  bootstrap_type = c("item", "person"),
  ci_method = c("percentile", "basic", "normal", "bca"),
  ci_level = 0.95,
  seed = NULL,
  return_analytical = TRUE,
  smoother = c("polynomial", "none"),
  smoother_args = list(degree = 2),
  exclude_extremes = FALSE,
  cutpoint = NULL,
  truncate_vc = FALSE,
  truncate_negative_error_var = FALSE,
  boot_keep_replicates = FALSE,
  na_action = c("listwise", "fail", "pairwise"),
  verbose = FALSE,
  ...
)

Arguments

data

Matrix or data.frame, N persons by J items, all numeric and complete (the single-facet crossed design requires balanced data).

method

Character vector; one or more of '"full"', '"large_a"', '"uncorrelated"'. Default: all three. Only applies when 'error_type' includes '"relative"'.

error_type

Character vector; one or both of '"absolute"', '"relative"'. Default: both.

conditioning

Either '"total"' (the per-person mean over items, i.e. 'rowMeans(data)') or a numeric vector of length N specifying an alternative conditioning variable. Default: '"total"'. In csemGT v1.0 'observed_score' and 'conditioning_value' coincide.

n_items_D

Integer; number of items for D-study extrapolation. Default: the number of observed items in 'data'.

bootstrap

Logical; if 'TRUE', a resampling bootstrap is run. Default: 'FALSE'.

R

Integer; number of bootstrap replications. Default: 1000.

bootstrap_type

One of '"item"' (default) or '"person"'. The item bootstrap is the default following Brennan (1998) and matches the 'gtcsem' Stata package.

ci_method

One of '"percentile"', '"basic"', '"normal"', '"bca"'. Default: '"percentile"'. In csemGT v1.0 the confidence intervals are Wald (normal-approximation) intervals; replicate-based methods are deferred to a later release, and a non-'"normal"' request is satisfied with the normal interval (the requested and effective methods are both recorded).

ci_level

Confidence level. Default: 0.95.

seed

Integer or 'NULL'; seed for the bootstrap. The bootstrap engines restore the prior RNG state on exit, so a non-'NULL' seed does not leak into the caller's session.

return_analytical

Logical; if 'TRUE' (default), analytical SEs are computed even when 'bootstrap = TRUE'.

smoother

One of '"polynomial"' (default) or '"none"'.

smoother_args

List of smoother arguments. Default: 'list(degree = 2)'.

exclude_extremes

Logical; if 'TRUE', floor and ceiling cases are excluded from the smoother fit (their unsmoothed CSEMs remain, but their 'smoothed_csem.*' values are 'NA'). Default: 'FALSE'.

cutpoint

Numeric or 'NULL'; cutpoint lambda for the mastery dependability coefficient Phi(lambda), on the same mean-per-item scale as 'observed_score'. Default: 'NULL' (not computed).

truncate_vc

Logical; truncate negative ANOVA variance components to zero. Default: 'FALSE'.

truncate_negative_error_var

Logical; truncate negative per-person error variances to zero before taking the CSEM square root. Default: 'FALSE'.

boot_keep_replicates

Logical; retain the bootstrap replicate summary in the output. Default: 'FALSE'.

na_action

One of '"listwise"' (default) or '"fail"'. '"pairwise"' is not supported for the GT paradigm.

verbose

Logical; emit progress messages during the bootstrap.

...

Reserved for forward compatibility; currently ignored.

Details

The analytical standard errors returned in the 'se.analytic.*' columns are **original contributions of the csemGT package** (derived in Gempp, 2026); they are not derived in Brennan (1998), which focuses on the point estimators. Users requiring fully verified inferential coverage should prefer the bootstrap standard errors ('bootstrap = TRUE').

The 'relative_uncorrelated' estimator is the per-person absolute error variance minus 'sigma^2(i)/I'. When 'sigma^2(Delta_p) < sigma^2(i)/I' the estimated relative error variance is negative and, under the default 'truncate_negative_error_var = FALSE', **its conditional SEM is 'NaN' at that score rather than truncated to zero**. This is expected behaviour, not a defect: it marks scores at which the estimator admits no non-negative variance, typically the extreme scores. Set 'truncate_negative_error_var = TRUE' to clip such variances to zero (the CSEM is then zero at those scores).

Value

An object of class 'csem'. Key components:

'estimates'

Data frame, one row per person, wide format. Identifier columns 'person_id', 'observed_score', 'conditioning_value', 'group_size', 'extreme', followed by 'cov_xim' and the estimation columns 'csem.<estimator>', 'csem_var.<estimator>', 'se.analytic.<estimator>' / 'se.boot.<estimator>', 'ci_low.*' / 'ci_up.*', and 'smoothed_csem.<estimator>'.

'by_score'

Data frame, one row per distinct observed score, the score-level summary of the estimation columns.

'variance_components'

ANOVA table, the three variance components, population-level error variances/SEMs, and the reliability-like coefficients ('erho2', 'phi', 'phi_lambda').

'smooth_fits'

Per-estimator smoother diagnostics, or 'NULL' when 'smoother = "none"'.

'bootstrap'

Bootstrap metadata, or 'NULL' when 'bootstrap = FALSE'.

See ['new_csem'] for the full structure.

References

Brennan, R. L. (1998). Raw-score conditional standard errors of measurement in generalizability theory. Applied Psychological Measurement, 22(4), 307-331. doi:10.1177/014662169802200401

Gempp, R. (2026). Analytical sampling variances for per-person estimators of conditional standard errors of measurement in Generalizability Theory. PsyArXiv working paper. doi:10.31234/osf.io/6qg9r_v1

Examples

set.seed(1)
d <- matrix(rbinom(60 * 12, 1, 0.5), nrow = 60)
fit <- csem_gt(d, error_type = "absolute")
head(fit$estimates)
fit$variance_components$reliability_coefficients


The csemGT colour palette

Description

Returns the package colour palette: one colour per CSEM estimator ('absolute', 'relative_full', 'relative_large_a', 'relative_uncorrelated') plus a neutral 'structural' colour used for grid lines and other non-data elements. The hues are taken from the Okabe-Ito qualitative palette, which is colourblind-safe. [plot.csem()] uses this palette by default; it is exported so the same colours can be reused elsewhere, for example to keep a manuscript figure consistent with the package plots.

Usage

csem_palette(which = NULL)

Arguments

which

Optional character vector of palette entry names to return. If 'NULL' (the default), the full named vector is returned.

Value

A named character vector of hex colour strings.

See Also

[plot.csem()], which uses this palette.

Examples

csem_palette()
csem_palette("relative_full")
csem_palette(c("absolute", "relative_full"))


Null-coalescing operator

Description

Returns 'b' when 'a' is 'NULL', otherwise returns 'a'. Provided here for compatibility with R versions earlier than 4.4 (where ' base operator). Internal use only.

Usage

a %||% b

Arguments

a, b

R objects.

Value

'a' if not 'NULL', else 'b'.


Simulated ITED-like dichotomous responses (Brennan, 1998)

Description

A simulated person-by-item matrix of dichotomously scored responses built to mimic the summary characteristics of the ITED Vocabulary Test example analysed in Brennan (1998, p. 314; Figure 1, p. 315). It is intended as a self-contained illustration dataset for the single-facet, person-by-item crossed Generalizability Theory design implemented in csem_gt.

Usage

iowa_like

Format

An integer matrix with 3000 rows (persons) and 40 columns (items). Each entry is 0 or 1 (incorrect / correct). Columns are named item01, item02, ..., item40.

Details

These are simulated data, not the original ITED data. The real Iowa Tests of Educational Development Vocabulary data described by Feldt, Forsyth, Ansley, and Alnot (1993, 1994) are not publicly available. iowa_like was generated from a Rasch (1PL) model whose parameters were calibrated so that the ANOVA-based mean absolute and relative error variances reproduce the values Brennan reports: \bar{\sigma}^2(\Delta) \approx .00514 and \bar{\sigma}^2(\delta) \approx .00475. The matrix uses A = 3000 simulated persons, matching Brennan's own use of 3,000 generated examinees for the absolute-error illustration. The full, seeded generation script is in data-raw/make_iowa_like.R.

Source

Simulated to match the summary statistics of the ITED Vocabulary Test example in Brennan, R. L. (1998). Raw-score conditional standard errors of measurement in generalizability theory. Applied Psychological Measurement, 22(4), 307-331. The underlying instrument is described in Feldt, L. S., Forsyth, R. A., Ansley, T. N., & Alnot, S. D. (1993, 1994). Iowa Tests of Educational Development. Riverside.

References

Brennan, R. L. (1998). Raw-score conditional standard errors of measurement in generalizability theory. Applied Psychological Measurement, 22(4), 307-331.

Examples

data(iowa_like)
dim(iowa_like)
iowa_like[1:5, 1:6]

## Relative conditional SEM, 'full' estimator (the default),
## reproducing the kind of dispersion seen in Brennan (1998),
## Figure 1b/1d.

fit <- csem_gt(iowa_like, error_type = "relative", method = "full")
fit
plot(fit)


Simulated IPIP-10-like Likert responses

Description

A simulated person-by-item matrix of Likert-scaled (1-5) responses built to mimic the qualitative features of a short, positively oriented Big-Five Conscientiousness subscale – in particular, the Conscientiousness items of the IPIP-50 inventory (Goldberg, 1992; Goldberg et al., 2006). It is intended as a self-contained illustration dataset for the polytomous Likert use case in the single-facet, person-by-item crossed Generalizability Theory design implemented in csem_gt.

Usage

ipip_like

Format

An integer matrix with 2000 rows (persons) and 10 columns (items). Each entry is an integer in \{1, 2, 3, 4, 5\}. Columns are named item01, item02, ..., item10.

Details

These are simulated data, not real IPIP-50 responses. ipip_like was generated by drawing independent normal person, item, and residual effects under the random-effects model that Generalizability Theory assumes for the p \times i design, and then rounding and clipping the resulting scores to the 1-5 Likert metric. The pre-truncation variance components are inflated to absorb the contraction induced by the clip-and-round step, so that the post-truncation ANOVA estimates approximate the targets \sigma^2(p) \approx 0.434, \sigma^2(i) \approx 0.136, and \sigma^2(pi) \approx 1.000, with generalizability coefficient E\rho^2 \approx 0.81. These targets are representative of the Conscientiousness subscale of the IPIP-50 dataset distributed by the Open-Source Psychometrics Project (n.d.) and can be reproduced by any user with access to that public dataset via a one-way p \times i ANOVA. The matrix uses A = 2{,}000 simulated persons and I = 10 items, with all items oriented positively (any reverse-keying is assumed already applied so that higher scores indicate higher Conscientiousness). The full, seeded generation script is in data-raw/make_ipip_like.R.

Source

Simulated to be broadly comparable to the Conscientiousness subscale of the IPIP-50 inventory, as administered in the public dataset of the Open-Source Psychometrics Project (https://openpsychometrics.org/_rawdata/). The underlying instrument is described in Goldberg, L. R. (1992) and Goldberg, L. R., Johnson, J. A., Eber, H. W., Hogan, R., Ashton, M. C., Cloninger, C. R., & Gough, H. G. (2006).

References

Goldberg, L. R. (1992). The development of markers for the Big-Five factor structure. Psychological Assessment, 4(1), 26-42.

Goldberg, L. R., Johnson, J. A., Eber, H. W., Hogan, R., Ashton, M. C., Cloninger, C. R., & Gough, H. G. (2006). The International Personality Item Pool and the future of public-domain personality measures. Journal of Research in Personality, 40(1), 84-96.

Open-Source Psychometrics Project. (n.d.). Raw data. https://openpsychometrics.org/_rawdata/

Examples

data(ipip_like)
dim(ipip_like)
ipip_like[1:5, 1:6]


fit <- csem_gt(ipip_like, error_type = "relative", method = "full",
               smoother = "polynomial")
fit
plot(fit, plot_type = "both", cibands = "model")


Test whether an object is a 'csem' object

Description

Test whether an object is a 'csem' object

Usage

is.csem(x)

Arguments

x

Any R object.

Value

'TRUE' if 'x' inherits from '"csem"', 'FALSE' otherwise.

Examples

set.seed(1)
d <- matrix(rbinom(80 * 15, 1, 0.5), nrow = 80)
fit <- suppressMessages(csem_gt(d, error_type = "absolute"))
is.csem(fit)
is.csem(list())


Construct a 'csem' object

Description

Low-level constructor for the 'csem' S3 class. This is an internal building block used by 'csem_gt()'. End users should not call this directly.

Usage

new_csem(
  estimates,
  by_score,
  call,
  paradigm,
  methods,
  error_types,
  arguments,
  variance_components = NULL,
  smooth_fits = NULL,
  diagnostics = NULL,
  bootstrap = NULL,
  scale_transform = NULL,
  n_persons,
  n_items,
  version = .csemGT_version()
)

Arguments

estimates

A data frame, one row per person, in wide format. Must contain at minimum the identifier columns 'person_id', 'observed_score', 'group_size'.

by_score

A data frame, one row per distinct value of the conditioning variable, also in wide format.

call

A captured 'match.call()' of the user-facing function.

paradigm

Character scalar; one of '"gt"', '"split_half"', '"anova"', '"binomial"'.

methods

Character vector of methods applied.

error_types

Character vector of error types reported.

arguments

Named list with the resolved arguments of the user-facing call.

variance_components

Named list with ANOVA-based variance components (used by the GT paradigm). May be 'NULL'.

smooth_fits

Named list of smoother diagnostics (one element per smoothed column). May be 'NULL'.

diagnostics

Named list of smoother sample-size diagnostics ('n_floor', 'n_ceiling', 'n_fit'). May be 'NULL'.

bootstrap

Named list with bootstrap metadata and replicates, or 'NULL' when bootstrap is not performed.

scale_transform

Scale transformation specification, or 'NULL'.

n_persons, n_items

Integer scalars.

version

Package version. Defaults to the installed version of 'csemGT'; falls back to '"0.0.0"' when the package is being built.

Value

An object of class 'c("csem", "list")'.


Plot a 'csem' object

Description

Draws a Brennan-style plot of the per-person conditional standard error of measurement against the observed score, in base graphics, following the layout of the 'gtcsem_plot' Stata command. The per-person scatter is drawn from the '$estimates' table – one point per person, so that the within-score spread of the CSEM is visible – and the optional quadratic-smoother curve from the '$by_score' table.

Usage

## S3 method for class 'csem'
plot(
  x,
  plot_type = c("csem", "ci", "both"),
  error_types = NULL,
  method = NULL,
  show_smooth = TRUE,
  compare_methods = FALSE,
  compare_points = FALSE,
  cibands = c("person", "model"),
  asemethod = c("analytical", "bootstrap"),
  ci_level = NULL,
  theme = c("csem"),
  col = NULL,
  pch = 16,
  cex = NULL,
  lwd = 2,
  lty = 1,
  alpha = NULL,
  main = NULL,
  sub = NULL,
  xlab = NULL,
  ylab = NULL,
  ylim = NULL,
  xlim = NULL,
  add = FALSE,
  ...
)

Arguments

x

A 'csem' object.

plot_type

One of '"csem"' (the per-person scatter, the default), '"ci"' (confidence bands only), or '"both"'. Not used by the compare layout.

error_types

Character vector selecting the error type(s) to plot: '"absolute"', '"relative"', or both. Two error types are drawn as a side-by-side pair of panels. Defaults to the error types carried by 'x'.

method

Relative-error estimator to plot when 'error_types' includes '"relative"': '"full"', '"large_a"', or '"uncorrelated"'. Defaults to the first method carried by 'x'.

show_smooth

Logical; overlay the quadratic-smoother curve when it is available. Defaults to 'TRUE'.

compare_methods

Logical; overlay the three relative-error estimators on one panel with a legend. Defaults to 'FALSE'.

compare_points

Logical; in the compare layout ('compare_methods = TRUE'), also draw the per-person scatter for each estimator. Defaults to 'FALSE', which overlays the smoother curves alone.

cibands

Source of the confidence bands when 'plot_type' is '"ci"' or '"both"': '"person"' (per-person intervals collapsed to the score level) or '"model"' (a band around the quadratic fit).

asemethod

Sampling-variance source for the '"person"' bands: '"analytical"' or '"bootstrap"'. Ignored when 'cibands = "model"'.

ci_level

Confidence level for the bands. Defaults to the level stored in 'x'.

theme

Plot theme. csemGT ships a single own theme, '"csem"'.

col

Override colour for the plotted series. 'NULL' uses the theme palette. Not applied in the compare layout.

pch, cex, lwd, lty

Graphical parameters for the scatter points ('pch', 'cex') and the smoother curve ('lwd', 'lty').

alpha

Point transparency in '[0, 1]'. 'NULL' calibrates it to the number of plotted persons.

main, sub, xlab, ylab

Title, subtitle and axis labels. 'NULL' selects a sensible default; for 'plot_type' '"ci"' / '"both"' the default subtitle reports the confidence level and band source. In the side-by-side layout 'main' is not applied (each panel keeps its own title).

ylim, xlim

Axis limits. 'NULL' selects a sensible default; the side-by-side and compare layouts share one 'ylim' across series.

add

Logical; if 'TRUE', draw onto the current plot instead of opening a new one. Not supported with the side-by-side or compare layouts.

...

Additional graphical parameters passed to the underlying 'plot()' call.

Details

When 'plot_type' is '"ci"' or '"both"' a confidence-band ribbon is added. Two band sources are available through 'cibands':

* '"person"' (the default) draws \widehat{csem} \pm z\, \widehat{se} around the by-score CSEM curve, using the per-person sampling SE of the CSEM. 'asemethod' selects whether that SE is the analytical or the bootstrap one; the bootstrap SE is only available when 'csem_gt()' was run with 'bootstrap = TRUE'. * '"model"' draws a band around the quadratic smoother. The per-person error variance is refit on the observed score and its square, and the SE of the mean fit is converted to the CSEM scale by the delta method. 'asemethod' is ignored for this source.

The confidence level is 'ci_level' (defaulting to the level stored in 'x'), so a level different from the one used at fitting time can be requested at plot time. The lower edge of every band is truncated at zero.

When two error types are requested ('error_types = c("absolute", "relative")') the two are drawn as a pair of panels sharing one y-axis, so the absolute and relative CSEMs are read on a common scale. Each panel keeps its own title; a user-supplied 'main' is not applied in this layout, and 'add = TRUE' is not supported.

When 'compare_methods = TRUE' the three relative-error estimators are overlaid on one panel with a legend, to compare their smoother curves directly. The per-person scatter is omitted by default – three clouds would not be legible – and added for every estimator by 'compare_points = TRUE'. Confidence bands are not available in this layout, 'add = TRUE' is not supported, and 'col' is not applied (each estimator keeps its palette colour).

Value

'x', invisibly.

See Also

[csem_palette()] for the colours used; [by_score()] and [as.data.frame.csem()] for the tables the plot is built from.

Examples

set.seed(1)
d <- matrix(rbinom(100 * 14, 1, 0.5), nrow = 100)
fit <- csem_gt(d, error_type = "absolute")
plot(fit)
plot(fit, plot_type = "both")


Print a 'csem' object

Description

Displays a 'csem' object as a sequence of console blocks mirroring the output of the 'gtcsem' Stata command: a header summarising the design, the ANOVA table, the D-study population error variances and standard errors of measurement, the reliability-like coefficients, the quadratic smoothing fits (when smoothing was applied), and the mean sampling variance of each estimator across persons.

Usage

## S3 method for class 'csem'
print(x, ...)

Arguments

x

A 'csem' object.

...

Currently ignored; present for S3 consistency.

Value

'x', invisibly.

See Also

[summary.csem()] for the score-level table and global statistics; [coef.csem()] and [by_score()] for programmatic access to the underlying components.

Examples

set.seed(1)
d <- matrix(rbinom(80 * 15, 1, 0.5), nrow = 80)
fit <- csem_gt(d, cutpoint = 0.5)
print(fit)


Print a 'summary.csem' object

Description

Displays a curated console view of a [summary.csem()] object: a short header, the population-level global statistics, and the score-level table reduced to the identifier columns, the cumulative frequency and percentile, and the conditional-SEM point estimates (the 'csem.*' columns). The sampling-variance, standard-error, confidence-interval and smoothed columns carried by the underlying object are not shown.

Usage

## S3 method for class 'summary.csem'
print(x, ...)

Arguments

x

A 'summary.csem' object.

...

Currently ignored; present for S3 consistency.

Value

'x', invisibly.


Summarise a 'csem' object

Description

Produces a score-level summary of a 'csem' object. The returned object carries the full 'by_score' table augmented with two columns, 'cum_freq' (the cumulative proportion of persons at or below each observed score) and 'percentile' ('100 * cum_freq'), together with the population-level global statistics: the relative and absolute standard errors of measurement and their companion reliability-like coefficients (the generalizability coefficient 'E rho^2' and the dependability coefficient 'Phi').

Usage

## S3 method for class 'csem'
summary(object, ...)

Arguments

object

A 'csem' object.

...

Currently ignored; present for S3 consistency.

Details

The returned object retains every column of the original 'by_score' table; [print.summary.csem()] displays a curated subset.

Value

An object of class 'summary.csem': a list with components 'call', 'paradigm', 'methods', 'error_types', 'n_persons', 'n_items', 'global_stats' (a list with 'relative_sem', 'erho2', 'absolute_sem', 'phi') and 'by_score_summary' (the augmented 'by_score' table).

See Also

[print.csem()] for the full-object display; [by_score()] and [coef.csem()] for programmatic access to the underlying components.

Examples

set.seed(1)
d <- matrix(rbinom(80 * 15, 1, 0.5), nrow = 80)
fit <- csem_gt(d, error_type = "absolute")
s <- summary(fit)
s$global_stats
head(s$by_score_summary)


Validate a 'csem' object

Description

Performs structural checks beyond the type assertions enforced by 'new_csem()'. Specifically, verifies that:

Usage

validate_csem(x)

Arguments

x

A candidate 'csem' object.

Details

Called automatically at the end of 'csem_gt()'; can also be invoked programmatically.

Value

Invisibly 'x' if all checks pass; otherwise raises an error.