--- title: "panel-comparisons" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{panel-comparisons} %\VignetteEncoding{UTF-8} %\VignetteEngine{knitr::rmarkdown} editor_options: markdown: wrap: 72 --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(wavecov) ``` # Overview 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. # Example panel 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. ```{r} 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 ``` # Defining wave pairs `compare_waves_batch()` expects an explicit set of wave pairs. A simple case is adjacent waves: ```{r} 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. # Basic batch comparison To run batch comparisons across all metrics and both groups: ```{r} 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. # Interpreting batch output A typical minimal view is: ```{r} 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. # Filtering by metric or group To focus on engagement only: ```{r} eng_changes <- subset(batch_res_min, metric_id == "engagement_score") eng_changes ``` To see differences for `Group A` vs `Group B`: ```{r} subset(batch_res_min, metric_id == "engagement_score" & wave_0 == 0 & wave_1 == 1) ``` # When bounds are used 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 # Summary - 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.