--- title: "Use Case: Time Series Analysis" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Use Case: Time Series Analysis} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` LOWESS for trend extraction and temporal smoothing. ## Overview Time series data often contains noise, seasonality, and trends. LOWESS provides flexible trend extraction without parametric assumptions. --- ## Basic Trend Extraction `fraction = 0.1` sizes the neighbourhood as 10% of the data at each evaluation point — narrow enough to follow a slowly varying trend without smearing periodic variation. Three robustness `iterations` down-weight noise spikes so they cannot bias the fitted curve; this is especially important when the signal-to-noise ratio is low or when occasional outliers are expected. ```{r use_case_time_series_1} library(rfastlowess) n <- 500 t <- seq(0, 100, length.out = n) i <- 0:(n - 1) y <- 10 + 0.5 * t + 3 * sin(t / 10) + ((i * 7 + 3) %% 1.7 - 0.85) * 3 # t and y are your time series vectors model <- Lowess( fraction = 0.1, iterations = 3 ) result <- fit(model, t, y) cat(sprintf("y[0]: %.4f\n", result$y[1])) ``` --- ## Detrending Remove trend to analyze residual patterns. Setting `outputs = "residuals"` stores `observed - smoothed` alongside the smooth. A slightly wider `fraction = 0.3` produces a smoother baseline trend, so short-duration oscillations end up in the residuals rather than being absorbed into the trend component. The residual series is then ready for spectral analysis, seasonality detection, or change-point methods. ```{r use_case_time_series_2} library(rfastlowess) n <- 100 t <- seq(0, 2 * pi, length.out = n) y <- sin(t) + 0.1 model <- Lowess( fraction = 0.3, iterations = 3, outputs = "residuals" ) result <- fit(model, t, y) trend <- result$y detrended <- result$residuals cat(sprintf("Trend y[0]: %.4f residual: %.4f\n", trend[1], detrended[1])) ``` --- ## Forecasting with Prediction Intervals Prediction intervals widen the uncertainty band to include both the uncertainty in the fitted curve (confidence interval) and the expected scatter of new observations around it. `fraction = 0.2` offers a balance between local detail and stable interval width — too small a fraction produces jagged interval edges; too large a fraction underestimates local variance near turning points. ```{r use_case_time_series_3} library(rfastlowess) n <- 100 t <- seq(0, 2 * pi, length.out = n) y <- sin(t) + 0.1 model <- Lowess( fraction = 0.2, iterations = 3, intervals = intervals_opts(confidence = 0.90, prediction = 0.99) ) result <- fit(model, t, y) cat(sprintf( "95%% PI: [%.4f, %.4f]\n", result$prediction_lower[1], result$prediction_upper[1] )) ``` --- ## Handling Missing Data LOWESS naturally handles irregular time sampling: ```{r use_case_time_series_4} library(rfastlowess) t_irregular <- vapply( 0:99, function(i) i * 1.0 + (i * 31 %% 10) * 0.1, numeric(1) ) y_irregular <- 10 + 0.3 * t_irregular + 2.0 * sin(t_irregular * 0.1) # No special handling needed for irregular spacing model <- Lowess(fraction = 0.2) result <- fit(model, t_irregular, y_irregular) cat(sprintf("y[0]: %.4f\n", result$y[1])) ``` --- ## Multi-Scale Analysis Use different fractions to extract features at different scales: ```{r use_case_time_series_5} library(rfastlowess) n <- 100 t <- seq(0, 2 * pi, length.out = n) y <- sin(t) + 0.1 scales <- c(0.05, 0.2, 0.5) trends <- lapply(scales, function(f) { model <- Lowess(fraction = f) fit(model, t, y)$y }) cat("Trend y[0] values:", vapply(trends, function(tr) tr[1], numeric(1)), "\n") ``` --- ## Gene Expression Time Course Biological application: ```{r use_case_time_series_6} library(rfastlowess) hours <- seq(0, 24, by = 0.5) i <- seq_along(hours) - 1 expression <- 100 * (1 + 0.5 * sin(hours * pi / 12)) + ((i * 7 + 3) %% 1.7 - 0.85) * 10 model <- Lowess( fraction = 0.3, iterations = 3, outputs = "diagnostics", intervals = intervals_opts(confidence = 0.95) ) result <- fit(model, hours, expression) cat(sprintf("R2: %.3f\n", result$diagnostics$r_squared)) ``` --- ## Choosing Fraction for Time Series | Data Type | Recommended Fraction | Rationale | | --- | --- | --- | | Daily data (years) | 0.3–0.5 | Capture annual trends | | Hourly data (days) | 0.1–0.2 | Capture daily patterns | | Sensor data (minutes) | 0.05–0.1 | Preserve short-term features | | Noisy data | Higher | Reduce noise impact | | Clean data | Lower | Preserve detail | --- ## See Also - [Real-Time Processing](use-case-real-time.html) — For streaming time series - [Cross-Validation](cross-validation.html) — Optimal fraction selection - [Boundary Handling](boundary.html) — Edge bias in trend extraction - `?Lowess` — Full parameter reference ```{r session-info} sessionInfo() ```