Repository navigation
cd_anomaly() and cd_summary(): accept series outside cd_variables() instead of returning NA #92
Description
If we do it: cd's baseline, anomaly, trend and window-comparison functions work on any annual series in cd's long format, streamflow or stream temperature produced by another package included. Departure is then computed one way everywhere. If we never do: a package that wants departure for its own series either gets NA from cd_anomaly() or writes a second copy of the statistics.
Problem
cd_baseline(), cd_trend() and cd_compare() already accept any tibble with variable, period, year, value. cd_anomaly() does not: it looks the anomaly type up in cd_variables(), and a variable that is not there returns NA without an error.
x <- data.frame(variable = "q_mean", period = "spawn", year = 2000:2001, value = 1:2)
cd_anomaly(x, cd_baseline(x, 2000:2001))
#> variable period year anomaly anomaly_type unit
#> 1 q_mean spawn 2000 NA <NA> <NA>
#> 2 q_mean spawn 2001 NA <NA> <NA>cd_summary() uses the same lookup for labels and units.
Proposed Solution
cd_anomaly(): when the input carriesanomaly_type(and optionallyunit) columns, use them; otherwise fall back tocd_variables(). Raise an error naming any variable whose type cannot be resolved, instead of returningNA.cd_summary(): the same fallback forlong_nameandunit.- Tests on a series that is not in
cd_variables(), and a documented input contract (variable,period,year,value, optionalanomaly_type/unit) so other packages can target it. periodis free text in the consumer functions; confirm nothing downstream assumescd_periods()values.
Scope stays with the statistics. Building per-year values from a daily series over date windows belongs to whichever package produces the series.
What landed (#94)
The work settled three points the proposal left open, and grew one guard:
unitis the anomaly's unit, passed through verbatim — the same meaningcd_variables()$unitalready had (prcpis"%"). A registered variable that carries a differentanomaly_typefrom the registry's (e.g.prcpas"absolute") gets no registry unit.cd_trend()passes the metadata through —long_namealways,anomaly_type/unitonly when it trends theanomalycolumn — socd_summary()sees it without the caller joining anything. The proposal's "same fallback incd_summary()" could not work on its own, becausecd_trend()dropped every input column.cd_summary()falls back to the variable name for the label, with no unit, rather than erroring: a label is cosmetic.- Added: one row per
(variable, period, year)is enforced incd_baseline,cd_anomaly,cd_compareandcd_trend. Two stations stacked under onevariableused to be pooled silently; they are now refused. Grouped input is accepted. periodaudit: nothing downstream assumescd_periods()values.
The contract is under "Input contract" in ?cd_anomaly. Plot labels are split out to #93.
Activity
Record PR #94 in the #92 archive