--- title: "Simulate Seasonal Epidemic Waves" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Simulate Seasonal Epidemic Waves} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup, warning=FALSE, message=FALSE} library(aedseo) ``` ## Simulation To demonstrate seasonal variation in a time series while accounting for trends and variability, we use the `generate_seasonal_wave()` function. This function generates a sinusoidal wave to represent periodic fluctuations, such as dayly, weekly or monthly cycles, while also incorporating optional exponential trend and random noise. This makes it suitable for modeling more realistic phenomena like infection rates. The wave is defined by the following equation: $$ \text{SeasonalWave}(t) = \left( \text{mean} + \text{amplitude} \cdot \sin\left(\frac{2\pi t}{\text{period}} + \text{phase}\right) \right) \cdot e^{\log(\text{trend_rate}) \cdot t} + \epsilon $$ Where: - $t$: The time variable (e.g., weeks or months, represented on the x-axis). - $\text{amplitude}$: Controls the height of the oscillations; the output varies between **\( \text{mean} \pm \text{amplitude} \)**. - $\text{mean}$: The baseline value around which the seasonal wave oscillates. Must be greater than or equal to the amplitude. - $\text{period}$: Defines the cycle length (e.g., 52 weeks for yearly seasonality) (is calculated based on `time_interval`). - $\text{phase}$: Adjusts the horizontal position of the wave on the x-axis. - $\text{trend_rate}$: Controls the exponential growth or decay of the trend over time. - $\epsilon$: Optional random noise, which can be included as a specified standard deviation. The first step is to create and transform simulated data into a `tsd` object using the `generate_seasonal_data()` function. - `time_interval` is a character vector specifying the time interval, choose between "day," "week," or "month." ```{r} seasonal_wave_sim_weekly <- generate_seasonal_data( years = 3, start_date = as.Date("2021-05-26"), amplitude = 1000, phase = 0, trend_rate = 1.001, noise_sd = 100, time_interval = "week" ) ``` ## Plot seasonal waves The `aedseo` package has an implemented a `plot()` S3 method to plot the `tsd` object. The `time_interval` argument can be used to visualise the x-axis as desired, either with days, weeks or months. The following figures shows the simulated data (solid circles) as individual observations. The solid line connects these points, representing the underlying mean trend over three years of weekly data. ### Example of weekly observations The x-axis shows the weeks and years, while the y-axis represents the simulated observations. In this simulation there is a positive `trend_rate`, which can be seen as the observations increase exponentially across seasons. The noise is the jumps between observations, instead of smoothly transitioning between observations. ```{r, dpi=300} plot(seasonal_wave_sim_weekly, time_interval = "5 weeks") ``` ### Example of monthly observations The x-axis shows the months and years, while the y-axis represents the simulated observations. In this simulation there is a negative `trend_rate`, which can be seen as the observations decrease exponentially across seasons. This simulation does not have any noise. ```{r, dpi=300} seasonal_wave_sim_monthly <- generate_seasonal_data( years = 4, start_date = as.Date("2021-05-26"), amplitude = 2000, mean = 2000, phase = 0, trend_rate = 0.99, time_interval = "month" ) plot( seasonal_wave_sim_monthly, time_interval = "3 months", y_label = "Monthly observations" ) ``` ### Example of daily observations The x-axis shows the days, months, years, while the y-axis represents the simulated observations. In this simulation there is no trend. The noise is the jumps between observations, instead of smoothly transitioning between observations. ```{r, dpi=300} seasonal_wave_sim_daily <- generate_seasonal_data( years = 1, start_date = as.Date("2021-05-26"), amplitude = 10000, mean = 10000, phase = 0, noise_sd = 200, time_interval = "day" ) plot( seasonal_wave_sim_daily, time_interval = "15 days", y_label = "Daily observations" ) ``` ### Example of phase shift A phase shift in a sinusoidal pattern effectively shifts where the wave starts along the x-axis instead of peaking (or hitting zero) at the same times as a wave with `phase = 0` (like in previous plot), it is shifted in time. in this example where `phase = 1` rather than `0`, we see that the rise and fall of the sine wave happens later compared to a wave with no phase shift. ```{r, dpi=300} seasonal_wave_sim_daily_phase_shift <- generate_seasonal_data( years = 1, start_date = as.Date("2021-05-26"), amplitude = 10000, mean = 10000, phase = 1, noise_sd = 200, time_interval = "day" ) plot( seasonal_wave_sim_daily_phase_shift, time_interval = "15 days", y_label = "Daily observations" ) ```