generate_initial_disease_states() errors when number_initial_E = 0, and can miscount when number_initial_S = 0
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 92/100
Línea de trabajo
Comienza con generate_initial_disease_states() y reproduce ambos fallos usando los ejemplos de parámetros del issue. Añade casos de regresión a test-variables.R para cero personas expuestas y cero personas susceptibles; después, ejecuta las pruebas relevantes de R. Se termina cuando cada combinación válida de recuentos iniciales produce los recuentos S, E, I y R solicitados, incluidos los pools que contienen solo una persona.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
generate_initial_disease_states() breaks on two kinds of valid initial conditions:
number_initial_E = 0with any initial I or R people errors withinvalid first argument. For example, you can't start an epidemic from infectious people alone.number_initial_S = 0can silently give the wrong counts. When only one person is left for the last draw, that draw can pick someone already assigned to an earlier state.
Both bugs are on main. They have been there since 6b5daf8 (2024-07-23), which added explicit initial I and R counts.
Reproducer
p <- list(human_population = 100, number_initial_S = 95, number_initial_E = 0,
number_initial_I = 5, number_initial_R = 0, seed = 1)
generate_initial_disease_states(p)
#> Error in sample.int(length(x), size, replace, prob) : invalid first argument
The same error comes through get_parameters() and create_variables(), so run_simulation() can't start either.
p <- list(human_population = 10, number_initial_S = 0, number_initial_E = 9,
number_initial_I = 1, number_initial_R = 0, seed = 1)
table(generate_initial_disease_states(p))
#> E I_mild S
#> 8 1 1
Seeds 1, 4 and 5 give E = 8 and S = 1 instead of E = 9 and S = 0. Seeds 2 and 3 happen to be correct.
Which inputs are affected
Tested with human_population = 100, with each count set to 0 or 5:
| E | I | R | Result |
|---|---|---|---|
| 0 | 0 | 0 | ok |
| 0 | > 0 | any | error |
| 0 | 0 | > 0 | error |
| > 0 | any | any | ok, unless S = 0 (below) |
With S = 0, the counts are wrong for some seeds whenever exactly one person is left for the I draw or the R draw. For example, with N = 10: E = 9, I = 1, R = 0, or E = 5, I = 4, R = 1.
Cause
Two R gotchas in how the remaining pool is built and sampled:
x[-integer(0)]returns an empty vector, notx. When E = 0,exposed_indexisinteger(0). Sopopulation_index[-exposed_index]is empty, and the I and R draws sample from nobody.sample(x, size)treats a single numberxas1:x. When one person is left in the pool,sample()draws from everyone up to that person's index, which can include people already made E or I. The draw overwrites them, and the person who should have been drawn stays S.
Proposed fix
Build each remaining pool with setdiff(), and draw with sample.int() so a pool of one person is handled correctly:
draw <- function(pool, size) pool[sample.int(length(pool), size)]
pool <- seq_along(initial_disease_states)
exposed_index <- draw(pool, parameters_list$number_initial_E)
initial_disease_states[exposed_index] <- "E"
pool <- setdiff(pool, exposed_index)
infectious_index <- draw(pool, parameters_list$number_initial_I)
initial_disease_states[infectious_index] <- "I_mild"
pool <- setdiff(pool, infectious_index)
recovered_index <- draw(pool, parameters_list$number_initial_R)
initial_disease_states[recovered_index] <- "R"
I checked this against the current function for every case above, with seeds 1 to 20:
- It gives the right counts in every case.
- It gives identical output in every case where the current function is already correct, so existing seeded runs don't change.
A single shuffle, sample(rep(c("S", "E", "I_mild", "R"), counts)), would be simpler. But it changes the initial state of every seeded run.
test-variables.R should get cases for E = 0 with I > 0, and for S = 0.
- Lenguaje dominante
- R
- Estrellas
- 8
- Forks
- 4
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de petal-code/helios
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
petal-code/helios#174 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
petal-code/helios#173 ·
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 84/100
petal-code/helios#166 ·
-
run_simulation() is not reproducible from seed: the leisure draw uses dqrng's own RNGPosiblemente ocupada Un pull request vinculado a esta issue está abierto o ya se fusionó. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
petal-code/helios#157 · 1 comentario ·
-
Dificultad 3/5 1-2 días Aptitud para principiantes 55/100
petal-code/helios#178 ·
Todos los issues de petal-code/helios
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 68/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 71/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
OHDSI/PatientLevelPrediction#688 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
rfordatascience/tidytuesday#1098 ·