getting-started"

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(wavecov)

Overview

The wavecov package provides overlap-aware comparisons of workforce metrics between two waves of data. This vignette shows the core scalar API, compare_waves(), on a minimal example.

We assume a long panel with one row per employee-wave-metric:

dat <- data.frame(
  eeid   = c("a", "b", "c",  "a",  "b",  "c"),
  wave   = c(0,   0,   0,    1,    1,    1),
  metric = c(1.0, 2.0, 3.0,
             1.2, 2.1, 2.9)
)

dat

Basic scalar comparison

The simplest use case is a single metric between two waves:

res_linked <- compare_waves(
  data       = dat,
  wave_0     = 0,
  wave_1     = 1,
  id_col     = "eeid",
  wave_col   = "wave",
  metric_col = "metric",
  method     = "linked"
)

res_linked

The result is a wavecov_result object with:

You can pull individual fields:

res_linked$estimate
res_linked$se
c(res_linked$ci_lower, res_linked$ci_upper)

When linked data is not available

If stayer information is unavailable or individual-level data are not available, the linked method cannot be used. In that case, you can either specify method = "reliability" directly, or let method = "auto" choose between linked, reliability, and bounds. The example below uses a case where individual data is available at both waves, but information on stayers has been lost (e.g., due to anonymized records). The user should note that reliability should reflect temporal stability for this use case.

dat_no_stayers <- data.frame(
  eeid   = c("a", "b", "c",  "d",  "e",  "f"),
  wave   = c(0,   0,   0,    1,    1,    1),
  metric = c(1.0, 2.0, 3.0,
             1.5, 2.2, 3.1)
)

# Auto will fall back to reliability or bounds as needed
res_auto <- compare_waves(
  data        = dat_no_stayers,
  wave_0      = 0,
  wave_1      = 1,
  id_col      = "eeid",
  wave_col    = "wave",
  metric_col  = "metric",
  method      = "auto",
  reliability = 0.8
)

res_auto$method
res_auto$estimate
c(res_auto$ci_lower, res_auto$ci_upper)

When only bounds are possible

In some cases we neither have stayer information available nor are willing to assume a reliability. In that setting, compare_waves() can fall back to Cauchy-based bounds, which describe a range of possible changes consistent with the data instead of a single point estimate.

Setting method = "bounds" forces this behaviour:

dat_bounds <- data.frame(
  eeid   = c("a", "b", "c",  "d",  "e",  "f"),
  wave   = c(0,   0,   0,    1,    1,    1),
  metric = c(1.0, 2.0, 3.0,
             1.5, 2.2, 3.1)
)

res_bounds <- compare_waves(
  data       = dat_bounds,
  wave_0     = 0,
  wave_1     = 1,
  id_col     = "eeid",
  wave_col   = "wave",
  metric_col = "metric",
  method     = "bounds",
  cov_sign   = "unrestricted",
  overlap_mode = "generic"
)

res_bounds

A wavecov_bounds_result object does not commit to a single change estimate; instead it reports bounds implied by the observed wave-level variances and any assumptions you specify (cov_sign, overlap_mode, and optionally sigma2S). This is appropriate when composition change is large and we lack enough structure for a defensible point estimate.

Summary

Use compare_waves() when you want a single, well-understood comparison between two waves for one metric and (optionally) one population slice. The companion compare_waves_batch() wrapper (see the Panel comparisons vignette) generalizes this to many groups and metrics.



Try the wavecov package in your browser

Any scripts or data that you put into this service are public.

wavecov documentation built on Nov. 3, 2026, 5:07 p.m.