Applies a user-supplied weight vector as a causal filter. Use this when you have a kernel from somewhere else – an econometric study, a vendor's published curve, a shape you fitted yourself – and want the same state handling, grouping and length guarantees as the built-in transforms.
Usage
adstock_filter(
x,
weights,
state = 0,
by = NULL,
na_action = c("error", "zero", "keep")
)Arguments
- x
Numeric vector of media spend (or impressions, or GRPs) in time order.
xmust already be sorted by time and evenly spaced; the function has no index argument and cannot check this for you. Usestep_adstock()if you want the time index validated.- weights
Numeric vector of kernel weights, ordered from the current period to the most distant lag. Not rescaled: whatever you supply is what is applied.
- state
The preceding
length(weights) - 1values ofx, oldest first, or0for a cold start – that is,utils::tail(x_previous, length(weights) - 1).- by
Optional grouping vector, or data frame of grouping vectors, the same length as
x. Adstock is applied independently within each group, which is what geo-level and panel models need. Never rely ondplyr::group_by()for this: grouping metadata does not reliably survive into every context where this function is called.- na_action
What to do about missing values in
x."error"(the default) refuses to guess."zero"treats missing media as no media, which is usually right for spend but is a substantive assumption."keep"letsNApropagate through the filter, which for the recursive form poisons every subsequent value.
See also
adstock_geometric() and adstock_weibull() for the built-in
kernels, adstock_weights() to build a geometric kernel to pass here,
adstock_state() for chaining.
Examples
# An explicitly humped kernel: the peak lands one period after the spend
adstock_filter(c(100, 0, 0, 0, 0), weights = c(0.2, 0.5, 0.3))
#> [1] 20 50 30 0 0
# Weights are applied as supplied, never rescaled. These sum to 2, and the
# output level doubles accordingly.
adstock_filter(c(100, 100, 100, 100), weights = c(1, 1))
#> [1] 100 200 200 200
# Chaining across chunks, and grouping, work as they do for the built-in
# kernels. Use `adstock_state()` with a matching `max_lag` to get the state.
w <- c(0.5, 0.3, 0.2)
whole <- adstock_filter(c(100, 80, 60, 40, 20), weights = w)
s <- utils::tail(c(100, 80, 60), length(w) - 1L)
chunked <- c(adstock_filter(c(100, 80, 60), weights = w),
adstock_filter(c(40, 20), weights = w, state = s))
all.equal(chunked, whole)
#> [1] TRUE