knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
library(wavecov)
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
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:
estimate: change in the metric between wave 0 and wave 1.se: standard error of the change estimate.ci_lower, ci_upper: lower/upper confidence limits at the requested
level.N0, N1: counts in wave 0 and wave 1.nS: number of "stayers" (ids present in both waves).method: the estimation method actually used.You can pull individual fields:
res_linked$estimate res_linked$se c(res_linked$ci_lower, res_linked$ci_upper)
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)
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.
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.
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.