From 714834aac4892c526153e4a0d07d6010123e324e Mon Sep 17 00:00:00 2001 From: "Steven Paul Sanderson II, MPH" Date: Thu, 26 Oct 2023 21:48:41 -0400 Subject: [PATCH] Fixes #485 --- NAMESPACE | 1 + NEWS.md | 1 + R/utils-singlediff-stationary.R | 83 +++++++++++++++++++++++++++ man/auto_stationarize.Rd | 3 +- man/calibrate_and_plot.Rd | 3 +- man/internal_ts_backward_event_tbl.Rd | 3 +- man/internal_ts_both_event_tbl.Rd | 3 +- man/internal_ts_forward_event_tbl.Rd | 3 +- man/model_extraction_helper.Rd | 3 +- man/ts_get_date_columns.Rd | 3 +- man/ts_info_tbl.Rd | 3 +- man/ts_is_date_class.Rd | 3 +- man/ts_lag_correlation.Rd | 3 +- man/ts_model_auto_tune.Rd | 3 +- man/ts_model_compare.Rd | 3 +- man/ts_model_rank_tbl.Rd | 3 +- man/ts_model_spec_tune_template.Rd | 3 +- man/ts_qq_plot.Rd | 3 +- man/ts_scedacity_scatter_plot.Rd | 3 +- man/ts_to_tbl.Rd | 3 +- man/util_log_ts.Rd | 3 +- man/util_singlediff_ts.Rd | 71 +++++++++++++++++++++++ 22 files changed, 192 insertions(+), 18 deletions(-) create mode 100644 R/utils-singlediff-stationary.R create mode 100644 man/util_singlediff_ts.Rd diff --git a/NAMESPACE b/NAMESPACE index ff0186e..b442bd6 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -102,6 +102,7 @@ export(ts_wfs_svm_poly) export(ts_wfs_svm_rbf) export(ts_wfs_xgboost) export(util_log_ts) +export(util_singlediff_ts) importFrom(magrittr,"%>%") importFrom(recipes,bake) importFrom(recipes,prep) diff --git a/NEWS.md b/NEWS.md index 7908b50..e3e170f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,7 @@ None ## New Features 1. Fix #484 - Add function `util_log_ts()` +2. Fix #485 - Add function `util_singlediff_ts()` ## Minor Fixes and Improvements 1. Fix #480 - Add attributes to output of `ts_growth_rate_vec()` diff --git a/R/utils-singlediff-stationary.R b/R/utils-singlediff-stationary.R new file mode 100644 index 0000000..571f6dc --- /dev/null +++ b/R/utils-singlediff-stationary.R @@ -0,0 +1,83 @@ +#' Single Differencing to Make Time Series Stationary +#' +#' @family Utility +#' +#' @author Steven P. Sanderson II, MPH +#' +#' @description This function attempts to make a non-stationary time series stationary by applying +#' single differencing. It iteratively increases the differencing order until stationarity is achieved. +#' +#' @details +#' The function calculates the frequency of the input time series using the `stats::frequency` function. +#' It then applies single differencing incrementally until the Augmented Dickey-Fuller test indicates +#' stationarity (p-value < 0.05) or until the differencing order reaches the frequency of the data. +#' +#' If single differencing successfully makes the time series stationary, it returns the stationary time series +#' and related information as a list with the following elements: +#' - stationary_ts: The stationary time series after differencing. +#' - ndiffs: The order of differencing applied to make it stationary. +#' - adf_stats: Augmented Dickey-Fuller test statistics on the stationary time series. +#' - trans_type: Transformation type, which is "diff" in this case. +#' - ret: TRUE to indicate a successful transformation. +#' +#' If the data requires more single differencing than its frequency allows, it informs the user and +#' returns a list with ret set to FALSE, indicating that double differencing may be needed. +#' +#' @param .time_series A time series object to be made stationary. +#' +#' @examples +#' # Example 1: Using a time series dataset +#' util_singlediff_ts(AirPassengers) +#' +#' # Example 2: Using a different time series dataset +#' util_singlediff_ts(BJsales)$ret +#' +#' @return +#' If the time series is already stationary or the single differencing is successful, +#' it returns a list as described in the details section. If additional differencing is required, +#' it informs the user and returns a list with ret set to FALSE. +#' +#' @name util_singlediff_ts +NULL + +#' @export +#' @rdname util_singlediff_ts +util_singlediff_ts <- function(.time_series){ + + time_series <- .time_series + f <- stats::frequency(time_series) + + # Single Differencing + diff_order <- 1 + while ((ts_adf_test(diff(time_series, diff_order))$p_value >= 0.05) & + (diff_order <= f)){ + diff_order <- diff_order + 1 + } + + if (diff_order <= f){ + rlang::inform( + message = paste0("Differencing of order " + , diff_order + , " made the time series stationary"), + use_cli_format = TRUE + ) + # Return + stationary_ts <- diff(time_series, diff_order) + return( + list( + stationary_ts = stationary_ts, + ndiffs = diff_order, + adf_stats = ts_adf_test(stationary_ts), + trans_type = "diff", + ret = TRUE + ) + ) + } else { + rlang::inform( + message = "Data requires more single differencing than its frequency, + trying double differencing", + use_cli_format = TRUE + ) + return(list(ret = FALSE)) + } +} diff --git a/man/auto_stationarize.Rd b/man/auto_stationarize.Rd index 5bf2582..39a0202 100644 --- a/man/auto_stationarize.Rd +++ b/man/auto_stationarize.Rd @@ -58,7 +58,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/calibrate_and_plot.Rd b/man/calibrate_and_plot.Rd index 9da4160..7fb6f76 100644 --- a/man/calibrate_and_plot.Rd +++ b/man/calibrate_and_plot.Rd @@ -101,7 +101,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/internal_ts_backward_event_tbl.Rd b/man/internal_ts_backward_event_tbl.Rd index fc08cf3..0508640 100644 --- a/man/internal_ts_backward_event_tbl.Rd +++ b/man/internal_ts_backward_event_tbl.Rd @@ -39,7 +39,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/internal_ts_both_event_tbl.Rd b/man/internal_ts_both_event_tbl.Rd index 8eff1d7..240340d 100644 --- a/man/internal_ts_both_event_tbl.Rd +++ b/man/internal_ts_both_event_tbl.Rd @@ -39,7 +39,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/internal_ts_forward_event_tbl.Rd b/man/internal_ts_forward_event_tbl.Rd index dc558af..4be90ae 100644 --- a/man/internal_ts_forward_event_tbl.Rd +++ b/man/internal_ts_forward_event_tbl.Rd @@ -39,7 +39,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/model_extraction_helper.Rd b/man/model_extraction_helper.Rd index 76dab00..e6fd70e 100644 --- a/man/model_extraction_helper.Rd +++ b/man/model_extraction_helper.Rd @@ -56,7 +56,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/ts_get_date_columns.Rd b/man/ts_get_date_columns.Rd index dbecf5b..7e1f82b 100644 --- a/man/ts_get_date_columns.Rd +++ b/man/ts_get_date_columns.Rd @@ -42,7 +42,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/ts_info_tbl.Rd b/man/ts_info_tbl.Rd index 181bcbe..e1eea7d 100644 --- a/man/ts_info_tbl.Rd +++ b/man/ts_info_tbl.Rd @@ -62,7 +62,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/ts_is_date_class.Rd b/man/ts_is_date_class.Rd index 1c34983..427104a 100644 --- a/man/ts_is_date_class.Rd +++ b/man/ts_is_date_class.Rd @@ -42,6 +42,7 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \concept{Utility} diff --git a/man/ts_lag_correlation.Rd b/man/ts_lag_correlation.Rd index bf3faea..2480380 100644 --- a/man/ts_lag_correlation.Rd +++ b/man/ts_lag_correlation.Rd @@ -91,7 +91,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/ts_model_auto_tune.Rd b/man/ts_model_auto_tune.Rd index 0eeb68d..39293c5 100644 --- a/man/ts_model_auto_tune.Rd +++ b/man/ts_model_auto_tune.Rd @@ -204,7 +204,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/ts_model_compare.Rd b/man/ts_model_compare.Rd index 714cf0d..4a281bf 100644 --- a/man/ts_model_compare.Rd +++ b/man/ts_model_compare.Rd @@ -128,7 +128,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/ts_model_rank_tbl.Rd b/man/ts_model_rank_tbl.Rd index dd82a9f..7ac72cd 100644 --- a/man/ts_model_rank_tbl.Rd +++ b/man/ts_model_rank_tbl.Rd @@ -96,7 +96,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/ts_model_spec_tune_template.Rd b/man/ts_model_spec_tune_template.Rd index e60f4ff..b3cca6b 100644 --- a/man/ts_model_spec_tune_template.Rd +++ b/man/ts_model_spec_tune_template.Rd @@ -72,7 +72,8 @@ Other Utility: \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/ts_qq_plot.Rd b/man/ts_qq_plot.Rd index 8fbaecd..95a0e51 100644 --- a/man/ts_qq_plot.Rd +++ b/man/ts_qq_plot.Rd @@ -101,7 +101,8 @@ Other Utility: \code{\link{ts_model_spec_tune_template}()}, \code{\link{ts_scedacity_scatter_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/ts_scedacity_scatter_plot.Rd b/man/ts_scedacity_scatter_plot.Rd index b20fcea..2e79c03 100644 --- a/man/ts_scedacity_scatter_plot.Rd +++ b/man/ts_scedacity_scatter_plot.Rd @@ -105,7 +105,8 @@ Other Utility: \code{\link{ts_model_spec_tune_template}()}, \code{\link{ts_qq_plot}()}, \code{\link{ts_to_tbl}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/ts_to_tbl.Rd b/man/ts_to_tbl.Rd index c569aa1..e61dd2e 100644 --- a/man/ts_to_tbl.Rd +++ b/man/ts_to_tbl.Rd @@ -46,7 +46,8 @@ Other Utility: \code{\link{ts_model_spec_tune_template}()}, \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, -\code{\link{util_log_ts}()} +\code{\link{util_log_ts}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/util_log_ts.Rd b/man/util_log_ts.Rd index e46578f..e890000 100644 --- a/man/util_log_ts.Rd +++ b/man/util_log_ts.Rd @@ -62,7 +62,8 @@ Other Utility: \code{\link{ts_model_spec_tune_template}()}, \code{\link{ts_qq_plot}()}, \code{\link{ts_scedacity_scatter_plot}()}, -\code{\link{ts_to_tbl}()} +\code{\link{ts_to_tbl}()}, +\code{\link{util_singlediff_ts}()} } \author{ Steven P. Sanderson II, MPH diff --git a/man/util_singlediff_ts.Rd b/man/util_singlediff_ts.Rd new file mode 100644 index 0000000..0d4fa70 --- /dev/null +++ b/man/util_singlediff_ts.Rd @@ -0,0 +1,71 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/utils-singlediff-stationary.R +\name{util_singlediff_ts} +\alias{util_singlediff_ts} +\title{Single Differencing to Make Time Series Stationary} +\usage{ +util_singlediff_ts(.time_series) +} +\arguments{ +\item{.time_series}{A time series object to be made stationary.} +} +\value{ +If the time series is already stationary or the single differencing is successful, +it returns a list as described in the details section. If additional differencing is required, +it informs the user and returns a list with ret set to FALSE. +} +\description{ +This function attempts to make a non-stationary time series stationary by applying +single differencing. It iteratively increases the differencing order until stationarity is achieved. +} +\details{ +The function calculates the frequency of the input time series using the \code{stats::frequency} function. +It then applies single differencing incrementally until the Augmented Dickey-Fuller test indicates +stationarity (p-value < 0.05) or until the differencing order reaches the frequency of the data. + +If single differencing successfully makes the time series stationary, it returns the stationary time series +and related information as a list with the following elements: +\itemize{ +\item stationary_ts: The stationary time series after differencing. +\item ndiffs: The order of differencing applied to make it stationary. +\item adf_stats: Augmented Dickey-Fuller test statistics on the stationary time series. +\item trans_type: Transformation type, which is "diff" in this case. +\item ret: TRUE to indicate a successful transformation. +} + +If the data requires more single differencing than its frequency allows, it informs the user and +returns a list with ret set to FALSE, indicating that double differencing may be needed. +} +\examples{ +# Example 1: Using a time series dataset +util_singlediff_ts(AirPassengers) + +# Example 2: Using a different time series dataset +util_singlediff_ts(BJsales)$ret + +} +\seealso{ +Other Utility: +\code{\link{auto_stationarize}()}, +\code{\link{calibrate_and_plot}()}, +\code{\link{internal_ts_backward_event_tbl}()}, +\code{\link{internal_ts_both_event_tbl}()}, +\code{\link{internal_ts_forward_event_tbl}()}, +\code{\link{model_extraction_helper}()}, +\code{\link{ts_get_date_columns}()}, +\code{\link{ts_info_tbl}()}, +\code{\link{ts_is_date_class}()}, +\code{\link{ts_lag_correlation}()}, +\code{\link{ts_model_auto_tune}()}, +\code{\link{ts_model_compare}()}, +\code{\link{ts_model_rank_tbl}()}, +\code{\link{ts_model_spec_tune_template}()}, +\code{\link{ts_qq_plot}()}, +\code{\link{ts_scedacity_scatter_plot}()}, +\code{\link{ts_to_tbl}()}, +\code{\link{util_log_ts}()} +} +\author{ +Steven P. Sanderson II, MPH +} +\concept{Utility}