Measure the campaign funnel –
sent, engaged, opted in, completed – across the whole fleet, by
registration, brand, client, fielding location, or mode, from the
consolidated campaign-metrics projection. Assumes you
have completed First-time setup (the package README, or
?s160_gcs_init from R): Cloud Storage access to
s160_analytics_prod.
Pull the projection once (cached), then roll it up:
library(survey160r)
s160_gcs_init() # one browser sign-in, cached
path <- campaign_metrics_pull() # cached after the first download
campaign_metrics_summary(path, by = "registration_id")
campaign_metrics_summary(path, by = c("brand", "mode"), percent = TRUE)campaign_metrics_summary() returns one row per
by group: the number of campaigns, the summed funnel
counts, and the four funnel rates (see What
you get back). by defaults to campaign_id;
any of registration_id, brand,
client, fielding_location, and
mode work, alone or together. percent = TRUE
scales the rates to 0-100.
To scope the rollup – a date window, a set of campaigns – read the
cells with campaign_metrics_records(), filter them, and
pass the frame to campaign_metrics_summary(). On a frame it
does no I/O, so this runs:
library(survey160r)
cells <- data.frame(
campaign_id = c(101L, 101L, 101L, 102L, 102L),
date = as.Date(c("2026-03-02", "2026-03-02", "2026-03-02",
"2026-03-09", "2026-03-09")),
hour_local = c(10L, 11L, NA, 14L, NA), # NA = the day total
registration_id = c("R-1", "R-1", "R-1", "R-2", "R-2"),
mode = c("T2W", "T2W", "T2W", "Live", "Live"),
n_sent = c(600L, 400L, 1000L, 500L, 500L),
n_engaged = c(60L, 40L, 100L, 75L, 75L),
n_opted_in = c(30L, 20L, 50L, 25L, 25L),
n_completed = c(12L, 8L, 20L, 10L, 10L)
)
march_week_one <- subset(cells, date >= as.Date("2026-03-01") & date < as.Date("2026-03-08"))
campaign_metrics_summary(march_week_one, by = "mode")
#> mode campaigns n_sent n_engaged n_opted_in n_completed engagement_rate
#> 1 T2W 1 1000 100 50 20 0.1
#> opted_in_rate opted_in_engaged_rate completion_rate
#> 1 0.05 0.5 0.02
campaign_metrics_summary(cells, by = "registration_id", percent = TRUE)
#> registration_id campaigns n_sent n_engaged n_opted_in n_completed
#> 1 R-1 1 1000 100 50 20
#> 2 R-2 1 500 75 25 10
#> engagement_rate opted_in_rate opted_in_engaged_rate completion_rate
#> 1 10 5 50.00000 2
#> 2 15 5 33.33333 2Campaign 101’s day reads n_sent = 1000, not
2000: the summary counts each campaign-day once, from its
day total, though the cells carry both the hour rows and that total (see
Notes). With real data,
cells <- campaign_metrics_records(path) reads the
projection into this shape.
The rates come from funnel_rates(), the one definition
campaign_metrics_summary() and
disposition_funnel() share. Use it on any frame of summed
counts so your numbers match theirs:
campaign_metrics_summary() returns one row per
by group:
| Column | Meaning |
|---|---|
the by columns |
The group, e.g. registration_id. |
campaigns |
Distinct campaigns in the group. |
n_sent / n_engaged /
n_opted_in / n_completed |
Summed funnel counts: sent, replied, consented, reached the close. |
engagement_rate |
n_engaged / n_sent. |
opted_in_rate |
n_opted_in / n_sent – opt-ins per send, end to
end. |
opted_in_engaged_rate |
n_opted_in / n_engaged – opt-in conversion once a
recipient replies. |
completion_rate |
n_completed / n_sent. |
The rates are proportions, or 0-100 with
percent = TRUE; rates = FALSE drops them. A
rate whose denominator is 0 is NA.
campaign_metrics_records() returns the cells:
campaign_id, date, hour_local,
the project dimensions (registration_id,
brand, client, fielding_location,
mode) when the projection carries them, and the four
n_* counts. See ?campaign_metrics_records.
hour_local 0-23) and a day-total cell
(hour_local = NA) with the same sends.
campaign_metrics_summary() counts each campaign-day once;
if you sum the cells yourself, keep one grain –
subset(cells, is.na(hour_local)) for daily totals – never
both.campaign_metrics_records() collapses that; read through it
(or campaign_metrics_summary()), not with your own Parquet
reader.mode is the declared mode. It is the
Project Tracker’s mode (Live, T2W), not the
mode detected from the export, which the disposition dataset carries as
survey_mode.NA and
groups as its own NA row.date = NA; it counts in an all-dates rollup and
drops out of any date filter.vignette("disposition").campaign_metrics_pull(refresh = TRUE) forces
a fresh download.env.
campaign_metrics_pull() reads "prod" (default)
or "dev" – there is no staging tier, so
env = "staging" errors. Run s160_datasets() to
see every dataset’s environments.?campaign_metrics_summary,
?campaign_metrics_records,
?campaign_metrics_pull, ?funnel_rates, and
?survey160r for every function by task. For the same funnel
per recipient, by carrier or any stored dimension,
disposition_funnel() in
vignette("disposition"). To screen a phone sample,
vignette("disposition") and
vignette("opt-out"). For per-campaign latency reports,
vignette("latency").