── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
Adjuntando el paquete: 'dagitty'
The following object is masked from 'package:rio':
convert
Adjuntando el paquete: 'ggdag'
The following object is masked from 'package:stats':
filter
Adjuntando el paquete: 'kableExtra'
The following object is masked from 'package:dplyr':
group_rows
Cargando paquete requerido: Matrix
Adjuntando el paquete: 'Matrix'
The following objects are masked from 'package:tidyr':
expand, pack, unpack
Adjuntando el paquete: 'lme4'
The following object is masked from 'package:rio':
factorize
This is DHARMa 0.4.7. For overview type '?DHARMa'. For recent changes, type news(package = 'DHARMa')
Cargando paquete requerido: carData
Adjuntando el paquete: 'car'
The following object is masked from 'package:purrr':
some
The following object is masked from 'package:dplyr':
recode
Cargando paquete requerido: Rcpp
Loading 'brms' package (version 2.22.0). Useful instructions
can be found by typing help('brms'). A more detailed introduction
to the package is available through vignette('brms_overview').
Adjuntando el paquete: 'brms'
The following object is masked from 'package:glmmTMB':
lognormal
The following object is masked from 'package:lme4':
ngrps
The following object is masked from 'package:stats':
ar
This is bayesplot version 1.12.0
- Online documentation and vignettes at mc-stan.org/bayesplot
- bayesplot theme set to bayesplot::theme_default()
* Does _not_ affect other ggplot2 plots
* See ?bayesplot_theme_set for details on theme setting
Adjuntando el paquete: 'bayesplot'
The following object is masked from 'package:brms':
rhat
This is loo version 2.8.0
- Online documentation and vignettes at mc-stan.org/loo
- As of v2.0.0 loo defaults to 1 core but we recommend using as many as possible. Use the 'cores' argument or set options(mc.cores = NUM_CORES) for an entire session.
- Windows 10 users: loo may be very slow if 'mc.cores' is set in your .Rprofile file (see https://github.com/stan-dev/loo/issues/94).
##
## Synth Package: Implements Synthetic Control Methods.
## See https://web.stanford.edu/~jhain/synthpage.html for additional information.
Warning: package 'weathercan' was built under R version 4.4.3
As of v0.7.2, the `normals` column in `stations()` reflects whether or not there
are *any* normals available (not just the most recent).
Welcome to emmeans.
Caution: You lose important information if you filter this package's results.
See '? untidy'
Registered S3 method overwritten by 'lfe':
method from
nobs.felm broom
Adjuntando el paquete: 'plm'
The following objects are masked from 'package:dplyr':
between, lag, lead
Adjuntando el paquete: 'PanelMatch'
The following object is masked from 'package:tidyr':
extract
The following object is masked from 'package:stats':
weights
Registered S3 method overwritten by 'GGally':
method from
+.gg ggplot2
Cargando paquete requerido: bsts
Cargando paquete requerido: BoomSpikeSlab
Cargando paquete requerido: Boom
Adjuntando el paquete: 'Boom'
The following objects are masked from 'package:brms':
ddirichlet, rdirichlet
The following object is masked from 'package:stats':
rWishart
Adjuntando el paquete: 'BoomSpikeSlab'
The following object is masked from 'package:stats':
knots
Cargando paquete requerido: zoo
Adjuntando el paquete: 'zoo'
The following objects are masked from 'package:base':
as.Date, as.Date.numeric
Cargando paquete requerido: xts
######################### Warning from 'xts' package ##########################
# #
# The dplyr lag() function breaks how base R's lag() function is supposed to #
# work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #
# source() into this session won't work correctly. #
# #
# Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
# conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #
# dplyr from breaking base R's lag() function. #
# #
# Code in packages is not affected. It's protected by R's namespace mechanism #
# Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #
# #
###############################################################################
Adjuntando el paquete: 'xts'
The following objects are masked from 'package:dplyr':
first, last
Adjuntando el paquete: 'bsts'
The following object is masked from 'package:BoomSpikeSlab':
SuggestBurn
Registered S3 method overwritten by 'quantmod':
method from
as.zoo.data.frame zoo
Adjuntando el paquete: 'forecast'
The following object is masked from 'package:brms':
ma
Code
#special repository indicated or the packageif(!require(weathercan)){install.packages("weathercan", repos =c("https://ropensci.r-universe.dev", "https://cloud.r-project.org")); library(weathercan) }#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_if(!require(bpmn)){devtools::install_github("bergant/bpmn")}
Warning in readLines(paste0(gsub("f1/", "", getwd()), "/key_alt.txt")):
incomplete final line found on 'H:/My Drive/PERSONAL
ANDRES/UCH_salud_publica/pasantia/f1/key_alt.txt'
API key has been set for the current session.
Bayesian
Code
cat("Treated (w/o Sherbrooke), effects after 2 days\n")
Treated (w/o Sherbrooke), effects after 2 days
Code
b_cmp <-brm( sum_velocidad_lead2 ~relevel(factor(exposure_window), ref="Pre-exposure")+ mean_min_temp_mean_lin + mean_max_temp_mean_lin + median_total_precip_median_lin + (1| cluster) +offset(off_lic),#median_lag_2_prec_median_imp+family =negbinomial(),#poisson(),data =subset(collisions_weather_corr_rect_pre_post, grepl("^Pre|^Exp",exposure_window) & treated_sens==TRUE),prior =c(prior(normal(0, 5), class ="b"),#,prior(exponential(1), class = "nu") # ν > 0prior(gamma(0.01, 0.01), class ="shape") # θ controla la sobre-disp. ),chains =4, cores =16, iter =4000*10, warmup =4000*2,control =list(adapt_delta = .99))
Compiling Stan program...
Start sampling
Code
a_cmp <-brm( sum_velocidad_lead2 ~relevel(factor(exposure_window), ref="Pre-exposure")+ mean_min_temp_mean_lin + mean_max_temp_mean_lin + median_total_precip_median_lin +(1| cluster) +offset(off_lic),# median_lag_2_prec_median_imp+ family =negbinomial(),#poisson(),data =subset(collisions_weather_corr_rect_pre_post, grepl("^Pre|^Exp",exposure_window) & treated_sens==FALSE),prior =c(prior(normal(0, 5), class ="b"),#,#,prior(exponential(1), class = "nu") # ν > 0prior(gamma(0.01, 0.01), class ="shape") # θ controla la sobre-disp. ),chains =4, cores =16, iter =4000*10, warmup =4000*2,control =list(adapt_delta = .99))
Compiling Stan program...
Start sampling
Code
# # 2.1 Histograma/overlay de densidades# pp_check(b_cmp, type = "dens_overlay", ndraws = 200)# pp_check(a_cmp, type = "dens_overlay", ndraws = 200)# # # 2.2 Rootogram (bueno para conteos)# pp_check(b_cmp, type = "rootogram")# pp_check(a_cmp, type = "rootogram")# # # 2.3 Distribución del número de ceros# pp_check(b_cmp, type = "bars", statistic = "zero")# # # 2.4 Estadísticos resumidos# pp_check(# b_cmp,# type = "stat",# statistic = c("mean", "sd", "var", "max") # elige los que te interesen# )#relevelfactorexposure_windowrefEQPreMexposureExposure# # y_rep <- posterior_predict(b_cmp, draws = 500) # 500 réplicas# summ_mean <- apply(y_rep, 1, function(x) c(mean = mean(x)))# summ_var <- apply(y_rep, 1, function(x) c(var = var(x)))# df_predict_mean<- sapply(summ_mean, FUN = identity) # df_predict_var<- sapply(summ_var, FUN = identity) # tibble(mean= as.numeric(df_predict_mean), var= as.numeric(df_predict_var))|># ggplot(aes(x = mean, y = var)) +# geom_point(alpha = .3) +# geom_abline(slope = 1, intercept = 0, colour = "red") +# labs(title = "Media vs Varianza en réplicas -> línea roja = Poisson ideal")# #MUCHA SOBREDISPERSIÓN# # Extrae draws del coeficiente, p. ej. el de `exposure_windowExp`betaA <-posterior_samples(a_cmp, "b_relevelfactorexposure_windowrefEQPreMexposureExposure")$b_relevelfactorexposure_windowrefEQPreMexposureExposure
Warning: Method 'posterior_samples' is deprecated. Please see ?as_draws for
recommended alternatives.
delta <- betaA - betaB # diferencia A − B# Resumen con intervalo de credibilidadquantile(delta, c(.025, .5, .975))
2.5% 50% 97.5%
-0.6492694 -0.1970737 0.2623611
Code
#> 2.5% 50% 97.5%#> -0.12 | 0.08 | 0.28 (ejemplo)#> #Si el 95 % CrI de delta incluye 0 → el efecto puede ser igual en ambas poblaciones.library(posterior)
This is posterior version 1.6.1
Adjuntando el paquete: 'posterior'
The following object is masked from 'package:bayesplot':
rhat
The following objects are masked from 'package:stats':
mad, sd, var
The following objects are masked from 'package:base':
%in%, match
Code
delta_draws <-as_draws_matrix(matrix(delta, ncol =1))colnames(delta_draws) <-"delta"# nombre de la columna → etiqueta en la leyenda# 2. Grafica el área de credibilidad del 95 %mcmc_areas(delta_draws, pars ="delta", prob =0.95) +geom_vline(xintercept =0, linetype ="dashed") +labs(title ="Δβ (A − B)",x ="Coefficient difference",y =NULL)
#ROPE: El 11.9 % de las simulaciones cae en la zona de irrelevancia práctica que fijaste.# Usando reglas heurísticas típicas:# • < 0.75 → débil, 0.75–0.90 → moderada, 0.90–0.97 → fuerte, > 0.97 → muy fuerte.# Con 0.82 estás en la franja moderada: hay más apoyo por un efecto positivo que negativo, pero la incertidumbre todavía es apreciable.
Matrix-completion method
Code
df <-subset( collisions_weather_corr_rect_synth, yday_corr <= (max_time -7) # mismo recorte temporal que en countSynth)df$treat_unit <- df$tr_contrl_corrdf$post_treat <-ifelse(df$yday_corr >=35, 1, 0)df$D <- df$tr_contrl_corr * df$post_treat # interacción exposición x tiempodf$log_rate <-log(df$sum_velocidad_lead2) -log(df$exp_lic) # log(count) – log(exposure)#table(collisions_weather_corr_rect_synth$id_lab,collisions_weather_corr_rect_synth$tr_contrl_corr)library(fect)set.seed(2125)road.main.gsynth <- fect::fect(formula = rate_lead2_lic ~ D + mean_min_temp_mean_lin + mean_max_temp_mean_lin +#rate_lead2_lic median_total_precip_median_lin + median_lag_2_prec_median_imp,data = df,index =c("id", "yday_corr"), # unit.variable y time.variableforce ="two-way", # fijamos efectos fijos unitarios y temporalesCV =TRUE, # selección automática de r con cross‑validationr =1:4, # ≈ K = 4 en tu modelo originalse =TRUE, # errores estándar por bootstrapnboots =1000, # ajusta según tu tolerancia de tiempo/precisiónparallel= F, # usa varios hilos si tu máquina lo permitemethod="mc")
Cannot use full pre-treatment periods in the F test. The first period is removed.
Code
# ATT:# ATT S.E. CI.lower CI.upper p.value# Tr obs equally weighted 0.223 0.1645 -0.09942 0.5455 0.1752# Tr units equally weighted 0.223 0.1645 -0.09942 0.5455 0.1752road.main.gsynthplot(road.main.gsynth, main="-3 pre to +0, Quebec+Sherbrooke")
Prediciton on the treated (adjusting on min max temperature and lagged precipitiation (2 days) and lagged rates
Code
df2 <-subset( collisions_weather_corr_rect_quebec_synth, yday_corr <= (max_time -7) # mismo recorte temporal que en countSynth)df2$treat_unit <- df2$tr_contrl_corrdf2$post_treat <-ifelse(df2$yday_corr >=35, 1, 0)df2$D <- df2$tr_contrl_corr * df2$post_treat # interacción exposición x tiemporoad.main.gsynth2 <- fect::fect(formula = rate_lead2_lic ~ D + mean_min_temp_mean_lin + mean_max_temp_mean_lin + median_total_precip_median_lin + median_lag_2_prec_median_imp,data = df2,index =c("id", "yday_corr"), # unit.variable y time.variableforce ="two-way", # fijamos efectos fijos unitarios y temporalesCV =TRUE, # selección automática de r con cross‑validationr =1:4, # ≈ K = 4 en tu modelo originalse =TRUE, # errores estándar por bootstrapnboots =1000, # ajusta según tu tolerancia de tiempo/precisiónparallel= F, # usa varios hilos si tu máquina lo permitemethod="mc")
p33_qc <-nixtla_client_plot(rbind(mutate(df33_qc[1:1,], ds = ds -1), df33_qc, df33_post_qc), fc33_qc,max_insample_length =100)## ── Estética idéntica a tu original ───────────────────────────────────────────p33_qc$layers[[1]]$geom_params$fill <-"#FFC10740"p33_qc$layers[[1]]$geom_params$alpha <-0.4p33_qc$layers[[2]]$aes_params$linewidth <-1.0t0_33_qc <-as.Date(min(p33_qc$data$ds))xint33_qc <-min(p33_qc$data$ds) + lubridate::days((t_int_man-3))p33_qc +scale_color_manual(values =c(TimeGPT ="red"),labels =c(TimeGPT ="Prediction (95% IC in gray area)") ) +scale_x_datetime(name ="Days of follow-up (33 before, 7 after)",limits =c(min(p33_qc$data$ds), max(p33_qc$data$ds)),breaks =seq(min(p33_qc$data$ds), max(p33_qc$data$ds), by ="7 days"),labels =function(x) as.integer(as.Date(x) - t0_33_qc +1) ) +theme_classic(base_size =13) +theme(strip.text =element_blank(),strip.background =element_blank(),legend.position ="bottom" ) +geom_vline(xintercept = xint33_qc,linetype ="dashed",color ="black",linewidth =1 ) +labs(y ="High-speed collisions per 1 M license holders")
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.
Prediction on the treated (-2 days before race, 7 days after — Québec)
Causal impact
We used the CausalImpact package, useful for time series data, inferring a counterfactual post race period based on pre-intervention components1. Given that the offset was constant, we used the sum of the high-speed collisions instead of rates.
Causal impact (Local linear trend, -3 days race), on Controls (Sherbrook+Quebec)
Code
err_ci_0c <- impact3d_ratio_resp2_c$series$response - impact3d_ratio_resp2_c$series$point.predrmse_ci_0c <-sqrt(mean(err_ci_0c[1:34]^2))mean_pre_0c <-mean(df33c$sum_velocidad_lead2[1:34]) sd_pre_0c <-sd(df33c$sum_velocidad_lead2[1:34])nrmse_0c <- rmse_ci_0c / mean_pre_0c # RMSE relativo; sd_ratio_0c <- rmse_ci_0c / sd_pre_0c # RMSE relativo a la variabilidad naturalcat(sprintf("RMSE on 35 post-period points: %.2f (average absolute forecast error)\n", rmse_ci_0c))cat(sprintf("NRMSE: %.2f (RMSE relative to pre-period mean, %.1f)\n", nrmse_0c, mean_pre_0c))cat(sprintf("SD-ratio: %.2f (RMSE vs pre-period variability, SD=%.1f)\n", sd_ratio_0c, sd_pre_0c))# Benchmark naïve (random walk de un paso):naive_rmse_0c <-sqrt(mean((df33c$sum_velocidad_lead2[2:34] - df33c$sum_velocidad_lead2[1:33])^2))improvement_0c <-1- rmse_ci_0c / naive_rmse_0c # >0 = mejora sobre el naïve
=-=-=-=-= Iteration 0 Tue Aug 19 16:08:42 2025
=-=-=-=-=
=-=-=-=-= Iteration 4000 Tue Aug 19 16:08:44 2025
=-=-=-=-=
=-=-=-=-= Iteration 8000 Tue Aug 19 16:08:45 2025
=-=-=-=-=
=-=-=-=-= Iteration 12000 Tue Aug 19 16:08:46 2025
=-=-=-=-=
=-=-=-=-= Iteration 16000 Tue Aug 19 16:08:48 2025
=-=-=-=-=
=-=-=-=-= Iteration 20000 Tue Aug 19 16:08:49 2025
=-=-=-=-=
=-=-=-=-= Iteration 24000 Tue Aug 19 16:08:50 2025
=-=-=-=-=
=-=-=-=-= Iteration 28000 Tue Aug 19 16:08:52 2025
=-=-=-=-=
=-=-=-=-= Iteration 32000 Tue Aug 19 16:08:53 2025
=-=-=-=-=
=-=-=-=-= Iteration 36000 Tue Aug 19 16:08:54 2025
=-=-=-=-=
Posterior inference {CausalImpact}
Average Cumulative
Actual 0.74 5.20
Prediction (s.d.) 0.75 (0.13) 5.22 (0.90)
95% CI [0.49, 1] [3.45, 7]
Absolute effect (s.d.) -0.0021 (0.13) -0.0144 (0.90)
95% CI [-0.26, 0.25] [-1.81, 1.75]
Relative effect (s.d.) 3.1% (20%) 3.1% (20%)
95% CI [-26%, 51%] [-26%, 51%]
Posterior tail-area probability p: 0.49319
Posterior prob. of a causal effect: 51%
For more details, type: summary(impact, "report")
RMSE on 35 post-period points: 0.00 (average absolute forecast error)
NRMSE: 0.00 (RMSE relative to pre-period mean, 21.2)
SD-ratio: 0.00 (RMSE vs pre-period variability, SD=5.9)
-3 days pre, +0
Code
# yss2ab<- c(as.numeric(df33$sum_velocidad_lead2), rep(NA,3))# yss2ab<- log(yss2ab)lambda_opt <- forecast::BoxCox.lambda(as.numeric(df33$sum_velocidad_lead2), lower =-2, upper =2)y_bc <-BoxCox(as.numeric(df33$sum_velocidad_lead2), lambda_opt)yss2ab <-c(y_bc, rep(NA, 4)) # respuesta escalada por 100 millones# Model 2ss2ab <-list()# Local trend, weekly-seasonal #https://qastack.mx/stats/209426/predictions-from-bsts-model-in-r-are-failing-completely - PUSE UN GENERALIZED LOCAL TRENDss2ab <-AddLocalLevel(ss2ab, yss2ab) ## Add weekly seasonalss2ab <-AddSeasonal(ss2ab, yss2ab, nseasons=7, season.duration =1) #weeks OJO, ESTOS NO SON WEEKS VERDADEROS. PORQUE TENGO MAS DE EUN AÑO#ss2ab <- AddAutoAr(ss2ab, y = c(as.numeric(df33$rate_lead2_lic), rep(NA,3)), lags = 10) #NO PUEDO AREGAR AR1 CON gaussian# For example, to add a day-of-week component to data with daily granularity, use model.args = list(nseasons = 7, season.duration = 1). To add a day-of-week component to data with hourly granularity, set model.args = list(nseasons = 7, season.duration = 24).covariates_future33b <-as.matrix(df33_post[1:4, c("mean_min_temp_mean_lin","mean_max_temp_mean_lin","mean_median_lag_2_prec_median_imp","mean_median_total_precip_median_lin"#,#"Y_lag10" )])covariates_full33b <-rbind(covariates33, covariates_future33b)# Include regression termsss2ab <-AddDynamicRegression(ss2ab, covariates_full33b)model2ab_ratio <-bsts(yss2ab,state.specification = ss2ab, #A list with elements created by AddLocalLinearTrend, AddSeasonal, and similar functions for adding components of state. See the help page for state.specification.family ="gaussian", #A Bayesian Analysis of Time-Series Event Count Dataniter =4e4, #burn = 2000, #http://finzi.psych.upenn.edu/library/bsts/html/SuggestBurn.html Suggest the size of an MCMC burn in sample as a proportion of the total run.seed=2125)## Since we have predictor variables in the model, we need to explicitly# make their coefficients time-varying using AddDynamicRegression().impact3ab_ratio_resp <-CausalImpact(bsts.model = model2ab_ratio,model.args =list(prior.level.sd=.1, dynamic.regression=T),post.period.response =as.numeric(BoxCox(as.numeric(df33_post$sum_velocidad_lead2[1:4]), lambda_opt)))#post.period.response = log(df33_post$sum_velocidad_lead2[1:3]))summary(impact3ab_ratio_resp)plot(impact3ab_ratio_resp)
Causal impact (Main, -3 days race, +0 days post)
Code
err_ci <- impact3ab_ratio_resp$series$response - impact3ab_ratio_resp$series$point.predrmse_ci <-sqrt(mean(err_ci[1:34]^2))mean_pre <-mean(df33$sum_velocidad_lead2[1:34]) sd_pre <-sd(df33$sum_velocidad_lead2[1:34])nrmse <- rmse_ci / mean_pre # RMSE relativo; sd_ratio <- rmse_ci / sd_pre # RMSE relativo a la variabilidad naturalcat(sprintf("RMSE on 35 post-period points: %.2f (average absolute forecast error)\n", rmse_ci))cat(sprintf("NRMSE: %.2f (RMSE relative to pre-period mean, %.1f)\n", nrmse, mean_pre))cat(sprintf("SD-ratio: %.2f (RMSE vs pre-period variability, SD=%.1f)\n", sd_ratio, sd_pre))# Benchmark naïve (random walk de un paso):naive_rmse <-sqrt(mean((df33$sum_velocidad_lead2[2:34] - df33$sum_velocidad_lead2[1:33])^2))improvement <-1- rmse_ci / naive_rmse # >0 = mejora sobre el naïve
=-=-=-=-= Iteration 0 Tue Aug 19 16:08:59 2025
=-=-=-=-=
=-=-=-=-= Iteration 4000 Tue Aug 19 16:09:00 2025
=-=-=-=-=
=-=-=-=-= Iteration 8000 Tue Aug 19 16:09:01 2025
=-=-=-=-=
=-=-=-=-= Iteration 12000 Tue Aug 19 16:09:02 2025
=-=-=-=-=
=-=-=-=-= Iteration 16000 Tue Aug 19 16:09:03 2025
=-=-=-=-=
=-=-=-=-= Iteration 20000 Tue Aug 19 16:09:04 2025
=-=-=-=-=
=-=-=-=-= Iteration 24000 Tue Aug 19 16:09:05 2025
=-=-=-=-=
=-=-=-=-= Iteration 28000 Tue Aug 19 16:09:06 2025
=-=-=-=-=
=-=-=-=-= Iteration 32000 Tue Aug 19 16:09:07 2025
=-=-=-=-=
=-=-=-=-= Iteration 36000 Tue Aug 19 16:09:08 2025
=-=-=-=-=
Posterior inference {CausalImpact}
Average Cumulative
Actual 26 103
Prediction (s.d.) 21 (1.9) 82 (7.4)
95% CI [17, 24] [68, 98]
Absolute effect (s.d.) 5.3 (1.9) 21.1 (7.4)
95% CI [1.4, 8.8] [5.8, 35.1]
Relative effect (s.d.) 27% (12%) 27% (12%)
95% CI [5.9%, 51%] [5.9%, 51%]
Posterior tail-area probability p: 0.00585
Posterior prob. of a causal effect: 99.41528%
For more details, type: summary(impact, "report")
RMSE on 35 post-period points: 1.55 (average absolute forecast error)
NRMSE: 0.03 (RMSE relative to pre-period mean, 54.6)
SD-ratio: 0.16 (RMSE vs pre-period variability, SD=9.6)
Code
# yss2cab <- c(as.numeric(df33c$sum_velocidad_lead2), rep(NA,3))# yss2cab <- log(yss2cab)lambda_opt <- forecast::BoxCox.lambda(as.numeric(df33c$sum_velocidad_lead2), lower =-2, upper =2)y_bc <-BoxCox(as.numeric(df33c$sum_velocidad_lead2), lambda_opt)yss2cab <-c(y_bc, rep(NA, 4)) # respuesta escalada por 100 millones# Model 2ss2cab <-list()# Local trend, weekly-seasonal #https://qastack.mx/stats/209426/predictions-from-bsts-model-in-r-are-failing-completely - PUSE UN GENERALIZED LOCAL TRENDss2cab <-AddLocalLevel(ss2cab, yss2cab) ## Add weekly seasonalss2cab <-AddSeasonal(ss2cab, yss2cab, nseasons=7, season.duration =1) #weeks OJO, ESTOS NO SON WEEKS VERDADEROS. PORQUE TENGO MAS DE EUN AÑO#ss2ab <- AddAutoAr(ss2ab, y = c(as.numeric(df33$rate_lead2_lic), rep(NA,3)), lags = 10) #NO PUEDO AREGAR AR1 CON gaussian# For example, to add a day-of-week component to data with daily granularity, use model.args = list(nseasons = 7, season.duration = 1). To add a day-of-week component to data with hourly granularity, set model.args = list(nseasons = 7, season.duration = 24).covariates_future33cb <-as.matrix(df33c_post[1:4, c("mean_min_temp_mean_lin","mean_max_temp_mean_lin","mean_median_lag_2_prec_median_imp","mean_median_total_precip_median_lin"#,#"Y_lag10" )])covariates_full33cb <-rbind(covariates33c, covariates_future33cb)# Include regression termsss2cab <-AddDynamicRegression(ss2cab, covariates_full33cb)model2cab_ratio <-bsts(yss2cab,state.specification = ss2cab, #A list with elements created by AddLocalLinearTrend, AddSeasonal, and similar functions for adding components of state. See the help page for state.specification.family ="gaussian", #A Bayesian Analysis of Time-Series Event Count Dataniter =4e4, #burn = 2000, #http://finzi.psych.upenn.edu/library/bsts/html/SuggestBurn.html Suggest the size of an MCMC burn in sample as a proportion of the total run.seed=2125)## Since we have predictor variables in the model, we need to explicitly# make their coefficients time-varying using AddDynamicRegression().impact3cab_ratio_resp <-CausalImpact(bsts.model = model2cab_ratio,model.args =list(prior.level.sd=.1, dynamic.regression=T),#post.period.response = log(df33c_post$sum_velocidad_lead2[1:3]))post.period.response =as.numeric(BoxCox(as.numeric(df33c_post$sum_velocidad_lead2[1:4]), lambda_opt)))summary(impact3cab_ratio_resp)plot(impact3cab_ratio_resp)
Causal impact (Main, -3 days race, +0 days post)
Code
err_ci_c <- impact3cab_ratio_resp$series$response - impact3cab_ratio_resp$series$point.predrmse_ci_c <-sqrt(mean(err_ci_c[1:34]^2))mean_pre_c <-mean(df33c$sum_velocidad_lead2[1:34]) sd_pre_c <-sd(df33c$sum_velocidad_lead2[1:34])nrmse_c <- rmse_ci_c / mean_pre_c # RMSE relativo; sd_ratio_c <- rmse_ci_c / sd_pre_c # RMSE relativo a la variabilidad naturalcat(sprintf("RMSE on 35 post-period points: %.2f (average absolute forecast error)\n", rmse_ci_c))cat(sprintf("NRMSE: %.2f (RMSE relative to pre-period mean, %.1f)\n", nrmse_c, mean_pre_c))cat(sprintf("SD-ratio: %.2f (RMSE vs pre-period variability, SD=%.1f)\n", sd_ratio_c, sd_pre_c))# Benchmark naïve (random walk de un paso):naive_rmse_c <-sqrt(mean((df33c$sum_velocidad_lead2[2:34] - df33c$sum_velocidad_lead2[1:33])^2))improvement_c <-1- rmse_ci_c / naive_rmse_c # >0 = mejora sobre el naïve
=-=-=-=-= Iteration 0 Tue Aug 19 16:09:12 2025
=-=-=-=-=
=-=-=-=-= Iteration 4000 Tue Aug 19 16:09:13 2025
=-=-=-=-=
=-=-=-=-= Iteration 8000 Tue Aug 19 16:09:14 2025
=-=-=-=-=
=-=-=-=-= Iteration 12000 Tue Aug 19 16:09:15 2025
=-=-=-=-=
=-=-=-=-= Iteration 16000 Tue Aug 19 16:09:16 2025
=-=-=-=-=
=-=-=-=-= Iteration 20000 Tue Aug 19 16:09:18 2025
=-=-=-=-=
=-=-=-=-= Iteration 24000 Tue Aug 19 16:09:19 2025
=-=-=-=-=
=-=-=-=-= Iteration 28000 Tue Aug 19 16:09:20 2025
=-=-=-=-=
=-=-=-=-= Iteration 32000 Tue Aug 19 16:09:21 2025
=-=-=-=-=
=-=-=-=-= Iteration 36000 Tue Aug 19 16:09:22 2025
=-=-=-=-=
Posterior inference {CausalImpact}
Average Cumulative
Actual 0.74 2.97
Prediction (s.d.) 0.75 (0.098) 2.98 (0.393)
95% CI [0.55, 0.94] [2.20, 3.77]
Absolute effect (s.d.) -0.0029 (0.098) -0.0115 (0.393)
95% CI [-0.2, 0.19] [-0.8, 0.77]
Relative effect (s.d.) 1.5% (14%) 1.5% (14%)
95% CI [-21%, 35%] [-21%, 35%]
Posterior tail-area probability p: 0.48879
Posterior prob. of a causal effect: 51%
For more details, type: summary(impact, "report")
RMSE on 35 post-period points: 0.00 (average absolute forecast error)
NRMSE: 0.00 (RMSE relative to pre-period mean, 21.2)
SD-ratio: 0.00 (RMSE vs pre-period variability, SD=5.9)
# RRR e intervalo (cuantílico)rrr_draws <- res1$rr_draws / res2$rr_drawsRRR_hat <- res1$rr_hat / res2$rr_hatci <-quantile(rrr_draws, c(0.025, 0.5, 0.975), na.rm =TRUE)cat("Québec only, -3 días pre, local linear trend (escala original via back-transform)\n")
Québec only, -3 días pre, local linear trend (escala original via back-transform)
Code
cat(sprintf("RRR = %.3f (95%% CI %.3f–%.3f)\n", RRR_hat, ci[1], ci[3]))
RRR = 1.535 (95% CI 0.404–29841960211.971)
Code
#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_## --- Asigna los λ que realmente usaste en cada impacto ---lambda_imp1q <-0.4903961# para impact33b_qc (df33_qc)lambda_imp2q <--1.720255# para impact2_33b_qc_c (df33c_qc)# Calcula RR de cada impacto (post = 4 tiempos)res1q <-rr_from_impact(impact33b_qc, lambda = lambda_imp1q, Tpost =4, n_sims =2e5, seed =2125)sprintf("Back-transformed RRs: %.2f (%.2f,%.2f)", quantile(res1q$rr_draws, c(0.5), na.rm =TRUE),quantile(res1q$rr_draws, c(0.025), na.rm =TRUE),quantile(res1q$rr_draws, c(0.975), na.rm =TRUE))
# RRR e intervalo (cuantílico)rrr_drawsq <- res1q$rr_draws / res2q$rr_drawsRRR_hatq <- res1q$rr_hat / res2q$rr_hatciq <-quantile(rrr_drawsq, c(0.025, 0.5, 0.975), na.rm =TRUE)cat("Québec only, -3 días pre, local linear trend (escala original via back-transform)\n")
Québec only, -3 días pre, local linear trend (escala original via back-transform)
Code
cat(sprintf("RRR = %.3f (95%% CI %.3f–%.3f)\n", RRR_hatq, ciq[1], ciq[3]))
Error in path.expand(path): argumento 'path' inválido
References
1.
Brodersen KH, Gallusser F, Koehler J, Remy N, Scott SL. Inferring causal impact using bayesian structural time-series models. The Annals of Applied Statistics. 2015;9(1). doi:10.1214/14-aoas788.