The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
Repeated-measures analysis requires a different data layout and, usually, a different estimand. The wide-data matrix workflow is not enough because the analysis must account for the repeated structure within subject.
This vignette covers:
rmcorr()ba_rm()ccc_rm_ustat()ccc_rm_reml()icc_rm_reml()Repeated-measures functions use a subject argument for
the subject identifier role, including rmcorr(),
ba_rm(), ccc_rm_ustat(),
ccc_rm_reml(), and icc_rm_reml().
library(matrixCorr)
set.seed(50)
n_id <- 14
n_time <- 4
dat <- expand.grid(
id = factor(seq_len(n_id)),
time = factor(seq_len(n_time)),
method = factor(c("A", "B"))
)
dat$time_index <- as.integer(dat$time)
subj <- rnorm(n_id, sd = 1.0)[dat$id]
subject_method <- rnorm(n_id * 2, sd = 0.25)
sm <- subject_method[(as.integer(dat$id) - 1L) * 2L + as.integer(dat$method)]
subject_time <- rnorm(n_id * n_time, sd = 0.75)
st <- subject_time[(as.integer(dat$id) - 1L) * n_time + as.integer(dat$time)]
dat$y <- subj + sm + st + 0.35 * (dat$method == "B") +
rnorm(nrow(dat), sd = 0.35)rmcorr() targets within-subject association, not
agreement. It is the right function when the question is whether two
responses vary together within subjects after removing subject-level
offsets.
set.seed(51)
dat_rmcorr <- data.frame(
id = rep(seq_len(n_id), each = n_time),
x = rnorm(n_id * n_time),
y = rnorm(n_id * n_time),
z = rnorm(n_id * n_time)
)
dat_rmcorr$y <- 0.7 * dat_rmcorr$x +
rnorm(n_id, sd = 1)[dat_rmcorr$id] +
rnorm(nrow(dat_rmcorr), sd = 0.3)
fit_rmcorr <- rmcorr(dat_rmcorr, response = c("x", "y", "z"), subject = "id")
summary(fit_rmcorr)
#> Correlation summary
#> output : matrix
#> dimensions : 3 x 3
#> retained_pairs: 6
#> threshold : 0.0000
#> diag : included
#> estimate : -0.3995 to 1.0000
#>
#> item1 item2 estimate n_complete fisher_z
#> x y 0.9397 56 1.7356
#> y z -0.3995 56 -0.4230
#> x z -0.3843 56 -0.4051
#>
#> Strongest pairs by |estimate|
#>
#> item1 item2 estimate n_complete fisher_z
#> x y 0.9397160 56 1.7356154
#> y z -0.3994915 56 -0.4230437
#> x z -0.3843429 56 -0.4051453Agreement methods require method labels and, for paired repeated analysis, a time or replicate key.
ba_rm() is the repeated-measures Bland-Altman route. It
models subject-time matched paired differences and returns bias and
limits of agreement.
fit_ba_rm <- ba_rm(
dat,
response = "y",
subject = "id",
method = "method",
time = "time_index"
)
summary(fit_ba_rm)
#>
#> Bland-Altman (two methods) (95% CI)
#>
#> Agreement estimates
#>
#> item1 item2 n_obs bias sd_loa loa_low loa_up width
#> method 1 method 2 56 0.654 0.651 -0.622 1.93 2.552
#>
#> Confidence intervals
#>
#> bias_lwr bias_upr lo_lwr lo_upr up_lwr up_upr
#> 0.483 0.824 -0.793 -0.452 1.759 2.101
#>
#> Model details
#>
#> sigma2_subject sigma2_resid residual_model
#> 0 0.424 iidThe package provides two repeated-measures CCC routes.
ccc_rm_ustat() is a nonparametric U-statistic
approach.ccc_rm_reml() uses the REML mixed-model backend.fit_ccc_ustat <- ccc_rm_ustat(
dat,
response = "y",
subject = "id",
method = "method",
time = "time_index"
)
fit_ccc_reml <- ccc_rm_reml(
dat,
response = "y",
subject = "id",
method = "method",
time = "time_index",
ci = FALSE
)
summary(fit_ccc_ustat)
#> Lin's concordance summary
#> method : Repeated-measures Lin's concordance
#> dimensions : 2 x 2
#> pairs : 1
#> estimate : 0.7180
#> most_negative: A-B (0.7180)
#> most_positive: A-B (0.7180)
#>
#> Strongest pairs by |estimate|
#>
#> item1 item2 estimate
#> A B 0.718
summary(fit_ccc_reml)
#>
#> Repeated-measures concordance (REML)
#>
#> Concordance estimates
#>
#> item1 item2 estimate n_subjects n_obs SB se_ccc
#> A B 0.6542 14 112 0.2047 0.0607
#>
#> Variance components
#>
#> sigma2_subject sigma2_subject_method sigma2_subject_time sigma2_error
#> 0.4785 0.0997 0.5943 0.1085
#>
#> AR(1) diagnostics
#>
#> ar1_rho ar1_rho_lag1 ar1_rho_mom ar1_pairs ar1_pval use_ar1 ar1_recommend
#> -0.3941 -0.3941 -0.3941 84 3e-04 FALSE FALSEThe two functions are related, but they are not interchangeable. The U-statistic route is useful when its design assumptions are appropriate. The REML route is the more flexible model-based path when variance components and residual structure need to be handled explicitly.
icc_rm_reml() uses the same REML and Woodbury backend as
repeated CCC, but it targets a different reliability quantity.
fit_icc_cons <- icc_rm_reml(
dat,
response = "y",
subject = "id",
method = "method",
time = "time_index",
type = "consistency",
ci = TRUE
)
fit_icc_agr <- icc_rm_reml(
dat,
response = "y",
subject = "id",
method = "method",
time = "time_index",
type = "agreement",
ci = FALSE
)
summary(fit_icc_cons)
#>
#> Repeated-measures intraclass correlation (REML) (95% CI)
#>
#> ICC estimates
#>
#> item1 item2 estimate lwr upr n_subjects n_obs se_icc residual_model
#> A B 0.6347 0.63 0.64 14 112 0.0022 iid
#>
#> Variance components
#>
#> sigma2_subject sigma2_subject_method sigma2_subject_time sigma2_error SB
#> 0.4785 0.0997 0.5943 0.1085 0.2047
#>
#> AR(1) diagnostics
#>
#> ar1_rho_lag1 ar1_rho_mom ar1_pairs ar1_pval use_ar1 ar1_recommend
#> -0.3941 -0.3941 84 3e-04 FALSE FALSE
summary(fit_icc_agr)
#>
#> Repeated-measures intraclass correlation (REML)
#>
#> ICC estimates
#>
#> item1 item2 estimate n_subjects n_obs se_icc residual_model
#> A B 0.4992 14 112 0.0463 iid
#>
#> Variance components
#>
#> sigma2_subject sigma2_subject_method sigma2_subject_time sigma2_error SB
#> 0.4785 0.0997 0.5943 0.1085 0.2047
#>
#> AR(1) diagnostics
#>
#> ar1_rho_lag1 ar1_rho_mom ar1_pairs ar1_pval use_ar1 ar1_recommend
#> -0.3941 -0.3941 84 3e-04 FALSE FALSEThe simulation above gives the subject-time component a visibly non-trivial variance contribution. That makes the CCC-versus-ICC distinction easier to see:
data.frame(
method = c("Repeated CCC (REML)", "Repeated ICC (agreement, REML)"),
estimate = c(
fit_ccc_reml[1, 2],
fit_icc_agr[1, 2]
)
)
#> method estimate
#> 1 Repeated CCC (REML) 0.6541643
#> 2 Repeated ICC (agreement, REML) 0.4991620The most important distinction between repeated CCC and repeated ICC is the numerator. Repeated ICC uses only the stable between-subject variance in the numerator. Repeated CCC also credits the time-averaged subject-time component. As a result, the two summaries can differ materially even when they are fitted through the same backend.
The method choice should follow the scientific question.
rmcorr() for within-subject association.ba_rm() for repeated-measures bias and limits of
agreement.ccc_rm_ustat() or ccc_rm_reml() for
repeated concordance.icc_rm_reml() for repeated reliability under a
variance-components interpretation.The shared long-format interface is intentional. The statistical targets are different, but the package keeps the surrounding workflow stable.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.