cmu-delphi / cmu-delphi/DelphiRF
`cv_revision_forecast` fold selection can produce uneven amounts of `test_lag` data, including 0
- Dominant language
- R
- Stars
- 1
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
When rows are in a certain order, fold assignment can place uneven amounts of `test_lag` data into the different folds, even placing 0 rows in a fold. This seems to be in part due to assigning folds before filtering to `test_lag`. (There's also some row reordering and/or exclusion that seems to be happening somewhere that's making it hard to understand why exactly this is happening when the number of lags is not a multiple of the number of folds.)
``` r
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(vctrs)
#>
#> Attaching package: 'vctrs'
#> The following object is masked from 'package:dplyr':
#>
#> data_frame
library(DelphiRF)
withr::with_tempdir({
dir.create("receiving")
tibble(report_date = as.Date("2020-01-01") + 7L * (0:21)) %>%
reframe(
.by = report_date,
reference_date = seq(as.Date("2020-01-01"), report_date, by = "week")
) %>%
transmute(
reference_date,
lag = as.numeric(report_date - reference_date)
) %>%
filter(lag <= 7 * 10) %>%
# filter(! (reference_date == unique(reference_date)[[6]] & lag == 0L)) %>%
# ^ excluding this row makes the problem crop up first in fold 3
# rather than fold 1
mutate(value = 100/(1+exp(-lag)) + rnorm(n())) %>%
DelphiRF::data_preprocessing(
value_col = "value",
refd_col = "reference_date",
lag_col = "lag",
ref_lag = 7L * 6L,
temporal_resol = "weekly",
smoothed = TRUE
) %>%
DelphiRF::add_weights_related() %>%
DelphiRF::cv_revision_forecast(
test_lag = 7L,
# ^ basing parameter selections solely on this lag.
# TODO: revisit
taus = (1:10 - 0.5)/10,
smoothed_target = TRUE,
# default lagged_term_list
temporal_resol = "weekly",
# default lambda, gamma candidates
lag_pad_candidates = 0L,
lp_solver = "glpk", # XXX
geo = "network-available",
indicator = "covid-net",
signal = "n",
geo_level = "national",
# no training_end_date
training_days = 90
# default n_folds
) %>%
{}
})
#> Error in `z[i, ]`:
#> ! subscript out of bounds
```
Created on 2026-07-20 with [reprex v2.1.1](https://reprex.tidyverse.org)
Potential workaround, but it also has issues: add this before `data_preprocessing`:
```r
complete(lag, reference_date) %>%
arrange(lag, reference_date) %>%
```
This ensures that each lag appears consecutively N times, once for each of the N reference dates, at least in the input to `data_preprocessing`, so unless whatever reordering/exclusion is happening in the above also messes this up and/or NA exclusion removes the completed row here and causes a problem, fold selection should still look something like 3:5, 1:5, 1:5, ..., 1:5, 1:5, 1:2 when filtering to the `test_lag` later on.
- Issue 1: if we then take this preprocessed data + the cv parameter selections and feed them into DelphiRF(), somehow this makes DelphiRF() output multiple predictions for the same targets (in one test case, it gave 1 prediction for the first reference date, 2 for the second, ..., 6 for the sixth, and multiple predictions for the same reference date differed). I guess this bit of preprocessing could be removed from what is fed into DelphiRF(), but I'd be concerned about the same issues happening somewhere inside the cv evaluations.
- Issue 2: this still fails for certain data. I started using `epix_zero_fill_low_lags()` from [here](https://github.com/cmu-delphi/epiprocess/issues/273#issuecomment-5402142786) to fill in some unreported times with zeros (in count data where that might make sense), and the indexing issue cropped up again. Possible workaround:
```r
complete(lag, reference_date) %>%
```
before `data_preprocessing()`, and
```r
arrange(lag, reference_date) %>%
```
before `cv_revision_forecast()`
Potential fix: filter to `test_lag` before assigning folds.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the cv_revision_forecast entry point and trace how data_preprocessing output is filtered for test_lag and assigned to folds. Run the provided R reprex, then verify that fold selection no longer produces empty or uneven test_lag folds or the subscript-out-of-bounds error, while checking the reported DelphiRF prediction issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- r
- Domain
- data, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100