11# Aim: use a GAMM to model the effects of model structure and country target type on WIS
2+ # Model:
3+ #
4+ # Method: model method (mechanistic, statistical, etc.)
5+ # CountryTargets: model predicts for single- vs multi-country
6+ # Trend: epidemic trend (stable, increasing, decreasing)
7+ # Location: location (random effect)
8+ # VariantPhase: dominant variant phase (random effect)
9+ # Horizon: forecast horizon (smooth, by model)
10+ # Model: individual model (random effect)
11+ #
12+ # Response: WIS (log-transformed, Gaussian family with log link)
13+
214library(here )
315library(dplyr )
416library(readr )
@@ -11,44 +23,31 @@ source(here("R", "process-data.R"))
1123source(here(" R" , " analysis-descriptive.R" ))
1224
1325# --- Get data ---
14- data <- prep_data(scoring_scale = " log" )
15- outcomes <- unique(data $ outcome_target )
16- classification <- classify_models()
17- targets <- table_targets(data )
18-
26+ data <- process_data(scoring_scale = " log" )
1927m.data <- data | >
20- filter(! grepl(" EuroCOVIDhub-" , Model )) | >
21- mutate(location = factor (location )) | >
22- group_by(location ) | >
23- mutate(
24- time = as.numeric(forecast_date - min(forecast_date )) / 7 ,
25- Horizon = as.numeric(Horizon ),
26- wis = wis + 1e-7
27- ) | >
28- ungroup()
28+ filter(! grepl(" EuroCOVIDhub-" , Model ))
29+ outcomes <- unique(data $ outcome_target )
2930
3031# --- Model formula ---
31- # Univariate for explanatory variables
32- m.formula_uni_type <- wis ~ s(Method , bs = " re" )
33- m.formula_uni_tgt <- wis ~ s(CountryTargets , bs = " re" )
34- m.formula_uni_model <- wis ~ s(Model , bs = " re" )
32+ # Univariate for each explanatory variable
33+ m.formulas_uni <- list (
34+ method = wis ~ s(Method , bs = " re" ),
35+ target = wis ~ s(CountryTargets , bs = " re" ),
36+ trend = wis ~ s(Trend , bs = " re" ),
37+ location = wis ~ s(Location , bs = " re" ),
38+ variant = wis ~ s(VariantPhase , bs = " re" ),
39+ horizon = wis ~ s(Horizon , by = Model , k = 3 , bs = " sz" ),
40+ model = wis ~ s(Model , bs = " re" )
41+ )
3542
36- # Full model
37- m.formula <- wis ~
38- # Method
43+ # Full joint model
44+ m.formula_joint <- wis ~
3945 s(Method , bs = " re" ) +
40- # Number of target countries
4146 s(CountryTargets , bs = " re" ) +
42- # -----------------------------
43- # Trend
4447 s(Trend , bs = " re" ) +
45- # Location
46- s(location , bs = " re" ) +
47- # Week * location
48- s(time , by = location , k = 40 ) +
49- # Horizon
50- s(Horizon , k = 3 , by = Model , bs = " sz" ) +
51- # Individual model
48+ s(Location , bs = " re" ) +
49+ s(VariantPhase , bs = " re" ) +
50+ s(Horizon , by = Model , k = 3 , bs = " sz" ) +
5251 s(Model , bs = " re" )
5352
5453# --- Model fitting ---
@@ -69,23 +68,22 @@ m.fit <- function(outcomes, m.formula) {
6968}
7069# Fit
7170cat(" --------fitting univariate models" )
72- m.fits_uni_type <- m.fit(outcomes , m.formula_uni_type )
73- m.fits_uni_tgt <- m.fit(outcomes , m.formula_uni_tgt )
74- m.fits_uni_model <- m.fit(outcomes , m.formula_uni_model )
71+ m.fits_uni <- map(m.formulas_uni , ~ m.fit(outcomes , .x ))
72+
7573cat(" --------fitting joint model" )
76- m.fits_joint <- m.fit(outcomes , m.formula )
77- cat( " finished fitting " )
74+ m.fits_joint <- m.fit(outcomes , m.formula_joint )
75+
7876# --- Output handling ---
7977# Extract estimates for random effects
80- random_effects_uni <- map_df(
81- c( m.fits_uni_type , m.fits_uni_tgt , m.fits_uni_model ),
82- extract_ranef ,
83- .id = " outcome_target " ) | >
78+ random_effects_uni <- m.fits_uni [ ! grepl( " horizon " , names( m.fits_uni ))] | >
79+ map_depth( .depth = 2 , ~ extract_ranef( .x )) | >
80+ map( ~ list_rbind( .x , names_to = " outcome_target " )) | >
81+ list_rbind( ) | >
8482 mutate(model = " Unadjusted" )
8583
8684random_effects_joint <- map_df(m.fits_joint ,
87- extract_ranef ,
88- .id = " outcome_target" ) | >
85+ extract_ranef ,
86+ .id = " outcome_target" ) | >
8987 mutate(model = " Adjusted" )
9088
9189random_effects <- random_effects_joint | >
0 commit comments