knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(wavecov)
The compare_waves() function is designed for a single metric and a
single pair of waves. In most real applications we want to:
compare multiple wave pairs (e.g., 2023Q1–2023Q2, 2023Q2–2023Q3),
for multiple metrics,
and often by groups (e.g., business unit, level, critical talent).
This vignette shows how to move from individual comparisons to batch
panel comparisons using compare_waves_batch().
We assume a long panel with:
one row per id–wave–metric,
optional metric identifiers and grouping columns.
For illustration, we create a small synthetic panel with:
100 employees,
3 waves (0, 1, 2),
2 metrics:
engagement_score
pay_index
a simple group column.
set.seed(123) n_id <- 100 waves <- 0:2 ids <- sprintf("ee%03d", 1:n_id) base_panel <- expand.grid( eeid = ids, wave = waves, KEEP.OUT.ATTRS = FALSE, stringsAsFactors = FALSE ) # Simple group assignment (one group per id-wave, then reused) base_panel$group <- sample(c("Group A", "Group B"), nrow(base_panel), replace = TRUE) # Engagement metric block eng_panel <- base_panel eng_panel$metric_id <- "engagement_score" eng_panel$metric <- 3.5 + 0.2 * eng_panel$wave + ifelse(eng_panel$group == "Group A", 0.1, -0.1) + rnorm(nrow(eng_panel), sd = 0.4) # Pay index metric block pay_panel <- base_panel pay_panel$metric_id <- "pay_index" pay_panel$metric <- 1.0 + 0.05 * pay_panel$wave + ifelse(pay_panel$group == "Group A", 0.05, -0.05) + rnorm(nrow(pay_panel), sd = 0.1) # Stack into one long panel panel <- rbind(eng_panel, pay_panel) head(panel) nrow(panel) # should be 100 ids * 3 waves * 2 metrics = 600
compare_waves_batch() expects an explicit set of wave pairs. A simple
case is adjacent waves:
wave_pairs <- data.frame( wave_0 = c(0, 1), wave_1 = c(1, 2) ) wave_pairs
This will run comparisons for:
wave 0 vs 1, and
wave 1 vs 2.
To run batch comparisons across all metrics and both groups:
batch_res <- compare_waves_batch( data = panel, wave_pairs = wave_pairs, id_col = "eeid", wave_col = "wave", metric_col = "metric", metric_id_col = "metric_id", group_cols = "group", method = "auto", reliability = 0.8 ) head(batch_res)
Each row corresponds to one combination of:
wave_0, wave_1
metric_id
group
with associated estimate, standard error, interval, and diagnostics.
A typical minimal view is:
batch_res_min <- batch_res[, c( "wave_0", "wave_1", "metric_id", "group", "estimate", "se", "ci_lower", "ci_upper", "method" )] head(batch_res_min)
estimate: estimated change in the metric between wave_0 and
wave_1.
se: standard error of that change.
ci_lower, ci_upper: normal-approximation confidence interval.
method: which estimator was actually used (linked, reliability,
or bounds).
You can use standard dplyr / ggplot2 tooling to filter or visualize
by metric, group, or wave pair.
To focus on engagement only:
eng_changes <- subset(batch_res_min, metric_id == "engagement_score") eng_changes
To see differences for Group A vs Group B:
subset(batch_res_min, metric_id == "engagement_score" & wave_0 == 0 & wave_1 == 1)
If there information on stayers is not available and no reliability
estimate exists, method = "auto" may fall back to bounds. In that
case, estimate / se are not available in the same way, and the
result will use the bounds structure instead. In this example we
supplied a reliability, so most comparisons will use linked or
reliability.
For more detail on the scalar API and methods, see the Getting Started vignette
Use compare_waves() when you need a single, well-understood scalar
comparison.
Use compare_waves_batch() when you need many comparisons across wave
pairs, metrics, and groups, with a consistent, tabular result.
Both functions share the same underlying panel summary and variance logic, so batch results are method-consistent with the scalar API.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.