Short analysis report

Alex Litovchenko

2026-03-06

This vignette shows a minimal analysis report: fit a model, print fixed effects, plot fitted vs observed, and show residual ACF and Q-Q.

1. Fit model(s)

library(tidyILD)
d <- ild_simulate(n_id = 8, n_obs_per = 10, irregular = TRUE, seed = 101)
x <- ild_prepare(d, id = "id", time = "time", gap_threshold = 7200)
x <- ild_center(x, y)
fit <- ild_lme(y ~ y_bp + y_wp + (1 | id), data = x, ar1 = FALSE, warn_no_ar1 = FALSE)
#> Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control$checkConv, :
#> Model failed to converge with max|grad| = 0.117947 (tol = 0.002, component 1)
#> Warning in checkConv(attr(opt, "derivs"), opt$par, ctrl = control$checkConv, : Model is nearly unidentifiable: very large eigenvalue
#>  - Rescale variables?

2. Tidy fixed-effects table

tidy_ild_model(fit)
#> # A tibble: 3 × 6
#>   term        estimate std_error   ci_low  ci_high p_value
#>   <chr>          <dbl>     <dbl>    <dbl>    <dbl>   <dbl>
#> 1 (Intercept) 9.93e-17  2.69e-17 4.65e-17 1.52e-16      NA
#> 2 y_bp        1   e+ 0  2.72e-17 1   e+ 0 1   e+ 0      NA
#> 3 y_wp        1   e+ 0  5.29e-17 1   e+ 0 1   e+ 0      NA

With cluster-robust standard errors (requires the clubSandwich package):

tidy_ild_model(fit, se = "robust", robust_type = "CR2")
#> # A tibble: 3 × 6
#>   term        estimate std_error     ci_low  ci_high p_value
#>   <chr>          <dbl>     <dbl>      <dbl>    <dbl>   <dbl>
#> 1 (Intercept) 9.93e-17  1.38e-16 -1.71 e-16 3.70e-16   0.472
#> 2 y_bp        1   e+ 0  2.07e-16  1.000e+ 0 1   e+ 0   0    
#> 3 y_wp        1   e+ 0  1.99e-17  1    e+ 0 1   e+ 0   0

3. Fitted vs observed

ild_plot(fit, type = "fitted")

Fitted vs observed

4. Residual diagnostics: ACF and Q-Q

diag <- ild_diagnostics(fit, type = c("residual_acf", "qq"))
diag
#> ILD diagnostics
#>   Engine: lmer
#>   AR1/CAR1: no
#>   Id column: id  Time column: time
#>   N persons: 8  N observations: 80
#>   Types computed: residual_acf, qq
plots <- plot_ild_diagnostics(diag)
plots$residual_acf
plots$qq

Residual ACF and Q-QResidual ACF and Q-Q

With AR1 (nlme)

Same workflow with residual autocorrelation (nlme path). If the AR1 model fails to converge on this small example, we show the code only; in practice use more data or a different seed.

fit_ar1 <- tryCatch(
  ild_lme(y ~ y_bp + y_wp, data = x, random = ~ 1 | id, ar1 = TRUE),
  error = function(e) NULL
)
if (!is.null(fit_ar1)) {
  tidy_ild_model(fit_ar1)
} else {
  message("AR1 fit did not converge on this run; use ild_lme(..., ar1 = TRUE) with your data.")
}
#> AR1 fit did not converge on this run; use ild_lme(..., ar1 = TRUE) with your data.
if (!is.null(fit_ar1)) {
  diag_ar1 <- ild_diagnostics(fit_ar1, type = c("residual_acf", "qq"))
  diag_ar1
}

Time-varying effects (TVEM)

When the effect of a predictor may change over time (e.g. stronger in the morning), use ild_tvem() to fit a GAM with a smooth in time and a time-varying coefficient. The plot shows how the effect of the predictor varies over the study timeline; interpret the curve as the estimated effect at each time point (with uncertainty band).

set.seed(101)
d2 <- ild_simulate(n_id = 6, n_obs_per = 12, seed = 101)
d2$x <- rnorm(nrow(d2))
x2 <- ild_prepare(d2, id = "id", time = "time")
tv <- ild_tvem(x2, "y", "x", k = 5, re_id = TRUE)
ild_tvem_plot(tv)