diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 2b176d57..fa262d0a 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -1,17 +1,12 @@ # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help -# usethis::use_github_action("check-standard") on: schedule: - cron: '0 0 1 * *' push: - branches: - - main - - master + branches: [main, master] pull_request: - branches: - - main - - master + branches: [main, master] name: R-CMD-check diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index bdd6de79..ed7650c7 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -1,8 +1,13 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: - branches: - - main - - master + branches: [main, master] + pull_request: + branches: [main, master] + release: + types: [published] + workflow_dispatch: name: pkgdown @@ -14,6 +19,8 @@ jobs: group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/pr-commands.yaml b/.github/workflows/pr-commands.yaml index 843bcef7..71f335b3 100644 --- a/.github/workflows/pr-commands.yaml +++ b/.github/workflows/pr-commands.yaml @@ -1,55 +1,79 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: issue_comment: types: [created] + name: Commands + jobs: document: - if: startsWith(github.event.comment.body, '/document') + if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/document') }} name: document - runs-on: macOS-latest + runs-on: ubuntu-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v2 - - uses: r-lib/actions/pr-fetch@v1 + - uses: actions/checkout@v3 + + - uses: r-lib/actions/pr-fetch@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: r-lib/actions/setup-r@v2 - - name: Install dependencies - run: Rscript -e 'install.packages(c("remotes", "roxygen2"))' -e 'remotes::install_deps(dependencies = TRUE)' + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::roxygen2 + needs: pr-document + - name: Document - run: Rscript -e 'roxygen2::roxygenise()' + run: roxygen2::roxygenise() + shell: Rscript {0} + - name: commit run: | - git config --local user.email "actions@github.com" - git config --local user.name "GitHub Actions" + git config --local user.name "$GITHUB_ACTOR" + git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" git add man/\* NAMESPACE git commit -m 'Document' - - uses: r-lib/actions/pr-push@v1 + + - uses: r-lib/actions/pr-push@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} + style: - if: startsWith(github.event.comment.body, '/style') + if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/style') }} name: style - runs-on: macOS-latest + runs-on: ubuntu-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v2 - - uses: r-lib/actions/pr-fetch@v1 + - uses: actions/checkout@v3 + + - uses: r-lib/actions/pr-fetch@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: r-lib/actions/setup-r@v2 + - name: Install dependencies - run: Rscript -e 'install.packages("styler")' + run: install.packages("styler") + shell: Rscript {0} + - name: Style - run: Rscript -e 'styler::style_pkg()' + run: styler::style_pkg() + shell: Rscript {0} + - name: commit run: | - git config --local user.email "actions@github.com" - git config --local user.name "GitHub Actions" + git config --local user.name "$GITHUB_ACTOR" + git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" git add \*.R git commit -m 'Style' - - uses: r-lib/actions/pr-push@v1 + + - uses: r-lib/actions/pr-push@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index e1c4120a..2c5bb502 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -1,54 +1,50 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: - branches: - - main - - master + branches: [main, master] pull_request: - branches: - - main - - master + branches: [main, master] name: test-coverage jobs: test-coverage: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest env: - RSPM: https://packagemanager.rstudio.com/cran/__linux__/bionic/latest GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: r-lib/actions/setup-r@v2 - id: install-r - - - name: Install pak and query dependencies - run: | - install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/") - saveRDS(pak::pkg_deps("local::.", dependencies = TRUE), ".github/r-depends.rds") - shell: Rscript {0} + with: + use-public-rspm: true - - name: Restore R package cache - uses: actions/cache@v2 + - uses: r-lib/actions/setup-r-dependencies@v2 with: - path: ${{ env.R_LIBS_USER }} - key: ubuntu-18.04-${{ steps.install-r.outputs.installed-r-version }}-1-${{ hashFiles('.github/r-depends.rds') }} - restore-keys: ubuntu-18.04-${{ steps.install-r.outputs.installed-r-version }}-1- + extra-packages: any::covr + needs: coverage - - name: Install system dependencies - if: runner.os == 'Linux' + - name: Test coverage run: | - pak::local_system_requirements(execute = TRUE) - pak::pkg_system_requirements("covr", execute = TRUE) + covr::codecov( + quiet = FALSE, + clean = FALSE, + install_path = file.path(Sys.getenv("RUNNER_TEMP"), "package") + ) shell: Rscript {0} - - name: Install dependencies + - name: Show testthat output + if: always() run: | - pak::local_install_dev_deps(upgrade = TRUE) - pak::pkg_install("covr") - shell: Rscript {0} + ## -------------------------------------------------------------------- + find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true + shell: bash - - name: Test coverage - run: covr::codecov() - shell: Rscript {0} + - name: Upload test results + if: failure() + uses: actions/upload-artifact@v3 + with: + name: coverage-test-failures + path: ${{ runner.temp }}/package diff --git a/DESCRIPTION b/DESCRIPTION index 9a494d4e..29ca554b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,7 +22,7 @@ Imports: recipes (>= 1.0.4), rsample, dplyr (>= 1.0.0), - ggplot2, + ggplot2 (>= 3.4.0), forcats, stringr, plotly, @@ -35,7 +35,7 @@ Imports: tidyr (>= 1.1.0), xts (>= 0.9-7), zoo (>= 1.7-14), - rlang (>= 0.4.11), + rlang (>= 1.1.1), tidyselect (>= 1.1.0), slider, anytime, @@ -43,7 +43,6 @@ Imports: forecast, tsfeatures, hms, - assertthat, generics, tidymodels Suggests: @@ -61,10 +60,7 @@ Suggests: fracdiff, timeSeries, tseries, - trelliscopejs, - roxygen2, - covr + trelliscopejs RoxygenNote: 7.2.3 Roxygen: list(markdown = TRUE) VignetteBuilder: knitr - diff --git a/R/augment-tk_augment_differences.R b/R/augment-tk_augment_differences.R index 27fc584c..1c8b2870 100644 --- a/R/augment-tk_augment_differences.R +++ b/R/augment-tk_augment_differences.R @@ -145,7 +145,7 @@ tk_augment_differences.grouped_df <- function(.data, .names = .names ) )) %>% - dplyr::select(-data) %>% + dplyr::select(-"data") %>% tidyr::unnest(cols = nested.col) %>% dplyr::group_by_at(.vars = group_names) } diff --git a/R/augment-tk_augment_fourier.R b/R/augment-tk_augment_fourier.R index 2d50b31e..7d92f94d 100644 --- a/R/augment-tk_augment_fourier.R +++ b/R/augment-tk_augment_fourier.R @@ -151,7 +151,7 @@ tk_augment_fourier.grouped_df <- function(.data, .names = .names ) )) %>% - dplyr::select(-data) %>% + dplyr::select(-"data") %>% tidyr::unnest(cols = nested.col) %>% dplyr::group_by_at(.vars = group_names) } diff --git a/R/diagnostics-tk_anomaly_diagnostics.R b/R/diagnostics-tk_anomaly_diagnostics.R index b55e6e4b..034f398a 100644 --- a/R/diagnostics-tk_anomaly_diagnostics.R +++ b/R/diagnostics-tk_anomaly_diagnostics.R @@ -234,7 +234,7 @@ iqr_vec <- function(x, alpha = 0.05, max_anoms = 0.2, verbose = FALSE) { abs_diff_upper = ifelse(value >= limit_upper, abs(value - limit_upper), 0), max_abs_diff = ifelse(abs_diff_lower > abs_diff_upper, abs_diff_lower, abs_diff_upper) ) %>% - dplyr::select(index, dplyr::everything()) %>% + dplyr::relocate(index) %>% dplyr::select(-c(abs_diff_lower, abs_diff_upper)) %>% # Sort by absolute distance from centerline of limits dplyr::mutate( @@ -284,7 +284,7 @@ iqr_vec <- function(x, alpha = 0.05, max_anoms = 0.2, verbose = FALSE) { } else { # All outliers, pick last limits limit_tbl <- vals_tbl %>% - dplyr::slice(n()) + dplyr::slice_tail(n = 1) limits_vec <- c( limit_lower = limit_tbl$limit_lower, limit_upper = limit_tbl$limit_upper diff --git a/R/diagnostics-tk_stl_diagnostics.R b/R/diagnostics-tk_stl_diagnostics.R index bfbe376a..ceb82fb7 100644 --- a/R/diagnostics-tk_stl_diagnostics.R +++ b/R/diagnostics-tk_stl_diagnostics.R @@ -157,7 +157,7 @@ tk_stl_diagnostics.grouped_df <- function(.data, .date_var, .value, .message = .message ) )) %>% - dplyr::select(-data) %>% + dplyr::select(-"data") %>% tidyr::unnest(cols = nested.col) %>% dplyr::group_by_at(.vars = group_names) diff --git a/R/dplyr-pad_by_time.R b/R/dplyr-pad_by_time.R index e4574358..09d7ae02 100644 --- a/R/dplyr-pad_by_time.R +++ b/R/dplyr-pad_by_time.R @@ -132,9 +132,7 @@ pad_by_time <- function(.data, .date_var, .by = "auto", .fill_na_direction = c("none", "down", "up", "downup", "updown"), .start_date = NULL, .end_date = NULL) { - if (!tolower(.fill_na_direction[1]) %in% c("none", "down", "up", "downup", "updown")) { - rlang::abort("'.fill_na_direction' must be one of c('none', 'down', 'up', 'downup', 'updown')") - } + rlang::arg_match(.fill_na_direction) if (rlang::quo_is_missing(rlang::enquo(.date_var))) { date_var_text <- tk_get_timeseries_variables(.data)[1] @@ -296,7 +294,7 @@ padder <- function(.data, .date_var, .by = "auto", .pad_value = NA, .fill_na_dir # Drop check_row_exists column ret <- ret %>% - dplyr::select(-check_row_exists) + dplyr::select(-"check_row_exists") # Fill NA if (.fill_na_direction != "none") { diff --git a/R/dplyr-slidify.R b/R/dplyr-slidify.R index d78f7277..ca5445ea 100644 --- a/R/dplyr-slidify.R +++ b/R/dplyr-slidify.R @@ -245,26 +245,30 @@ slider_2 <- function(..., .slider_fun, .f, .period, .align, .partial, .unlist) { check_dots <- function(x, .period) { # The user must have passed something to be passed on to .f - assertthat::assert_that(length(x) > 0, - msg = "At least 1 data argument must be supplied to be - passed on to the rolling function") + if (length(x) == 0) { + stop("At least 1 data argument must be supplied to be + passed on to the rolling function", call. = FALSE) + } # The .period must be smaller than the length of the data - assertthat::assert_that(.period <= length(x[[1]]), - msg = "Cannot roll apply with a .period larger than the + if (any(.period > length(x[[1]]))) { + stop(call. = FALSE, "Cannot roll apply with a .period larger than the length of the data") + } # Length of every element of .dots should be the same # Only data used in the rolling should be in .dots # Optional args should be specified in the slidify call - for(i in 1:length(x)) { - assertthat::assert_that(length(x[[i]]) == length(x[[1]]), - msg = "Arguments supplied to the rolling version + lens <- lengths(x) + n_distinct_length_x <- length(unique(lens)) + if (n_distinct_length_x != 1) { + stop(call. = FALSE, "Arguments supplied to the rolling version of the function should be data of the same length. Optional arguments should be specified when creating the rolling version with `slidify()`") } + TRUE } diff --git a/R/get-tk_get_holiday_signature.R b/R/get-tk_get_holiday_signature.R index 9661b9a3..21b7bea9 100644 --- a/R/get-tk_get_holiday_signature.R +++ b/R/get-tk_get_holiday_signature.R @@ -139,9 +139,9 @@ get_holiday_signature <- function(idx, # Setup idx <- lubridate::as_date(idx) - years <- lubridate::year(idx) %>% unique() - locale_set <- locale_set %>% tolower() - exchange_set <- exchange_set %>% tolower() + years <- unique(lubridate::year(idx)) + locale_set <- tolower(locale_set) + exchange_set <- tolower(exchange_set) if (any("all" %in% locale_set)) locale_set <- "all" if (any("all" %in% exchange_set)) exchange_set <- "all" @@ -150,7 +150,7 @@ get_holiday_signature <- function(idx, if (any("none" %in% exchange_set)) exchange_set <- "none" initial_index_tbl <- tibble::tibble(index = idx) - unique_index_tbl <- initial_index_tbl %>% dplyr::distinct() + unique_index_tbl <- dplyr::distinct(initial_index_tbl) # HOLIDAY & LOCALE FEATURES ---- diff --git a/R/get-tk_get_timeseries.R b/R/get-tk_get_timeseries.R index 22a4ea49..db8a25f0 100644 --- a/R/get-tk_get_timeseries.R +++ b/R/get-tk_get_timeseries.R @@ -51,7 +51,7 @@ #' idx_yearmon <- seq.Date(from = ymd("2016-01-01"), #' by = "month", #' length.out = 12) %>% -#' as.yearmon() +#' zoo::as.yearmon() #' #' tk_get_timeseries_signature(idx_yearmon) #' tk_get_timeseries_summary(idx_yearmon) diff --git a/R/lubridate-date_parsers.R b/R/lubridate-date_parsers.R index 3ecee72c..b970eb9f 100644 --- a/R/lubridate-date_parsers.R +++ b/R/lubridate-date_parsers.R @@ -31,7 +31,7 @@ #' shifts datetimes to the specified timezone by default. #' #' @references -#' - This function wraps the `anytime::anytime()` and `anytime::anydate` functions developed by Dirk Eddelbuettel. +#' - This function wraps the `anytime::anytime()` and `anytime::anydate()` functions developed by Dirk Eddelbuettel. #' #' @examples #' diff --git a/R/plot-acf_diagnostics.R b/R/plot-acf_diagnostics.R index 7015a562..0592bf4d 100644 --- a/R/plot-acf_diagnostics.R +++ b/R/plot-acf_diagnostics.R @@ -18,7 +18,7 @@ #' @param .facet_ncol Facets: Number of facet columns. Has no effect if using `grouped_df`. #' @param .facet_scales Facets: Options include "fixed", "free", "free_y", "free_x" #' @param .line_color Line color. Use keyword: "scale_color" to change the color by the facet. -#' @param .line_size Line size +#' @param .line_size Line size (linewidth) #' @param .line_alpha Line opacity. Adjust the transparency of the line. Range: (0, 1) #' @param .point_color Point color. Use keyword: "scale_color" to change the color by the facet. #' @param .point_size Point size @@ -215,11 +215,11 @@ plot_acf_diagnostics.data.frame <- function(.data, .date_var, .value, .ccf_vars if (.line_color == "scale_color") { g <- g + ggplot2::geom_line(ggplot2::aes(color = name), - size = .line_size, alpha = .line_alpha) + + linewidth = .line_size, alpha = .line_alpha) + scale_color_tq() } else { g <- g + - ggplot2::geom_line(color = .line_color, size = .line_size, alpha = .line_alpha) + ggplot2::geom_line(color = .line_color, linewidth = .line_size, alpha = .line_alpha) } # Add points @@ -309,7 +309,7 @@ plot_acf_diagnostics.grouped_df <- function(.data, .date_var, .value, .ccf_vars dplyr::mutate(.groups_consolidated = stringr::str_c(!!! rlang::syms(group_names), sep = "_")) %>% dplyr::mutate(.groups_consolidated = forcats::as_factor(.groups_consolidated)) %>% dplyr::select(-(!!! rlang::syms(group_names))) %>% - dplyr::select(.groups_consolidated, lag, dplyr::everything()) %>% + dplyr::relocate(.groups_consolidated, lag) %>% tidyr::pivot_longer(cols = -c(.groups_consolidated, lag, .white_noise_upper, .white_noise_lower), values_to = "value", names_to = "name") %>% @@ -335,11 +335,11 @@ plot_acf_diagnostics.grouped_df <- function(.data, .date_var, .value, .ccf_vars if (.line_color == "scale_color") { g <- g + ggplot2::geom_line(ggplot2::aes(color = .groups_consolidated), - size = .line_size, alpha = .line_alpha) + + linewidth = .line_size, alpha = .line_alpha) + scale_color_tq() } else { g <- g + - ggplot2::geom_line(color = .line_color, size = .line_size, alpha = .line_alpha) + ggplot2::geom_line(color = .line_color, linewidth = .line_size, alpha = .line_alpha) } # Add points diff --git a/R/plot-anomaly_diagnostics.R b/R/plot-anomaly_diagnostics.R index a99034c1..13e411c6 100644 --- a/R/plot-anomaly_diagnostics.R +++ b/R/plot-anomaly_diagnostics.R @@ -166,7 +166,7 @@ plot_anomaly_diagnostics <- function( date_var_expr <- rlang::enquo(.date_var) if (!is.data.frame(.data)) { - rlang::abort(".data is not a data-frame or tibble. Please supply a data.frame or tibble.") + rlang::abort("`.data` must be a a data-frame or tibble. Please supply a data.frame or tibble.") } if (rlang::quo_is_missing(date_var_expr)) { rlang::abort(".date_var is missing. Please supply a date or date-time column.") @@ -301,10 +301,10 @@ plot_anomaly_diagnostics.data.frame <- function( # Add line g <- g + ggplot2::geom_line( - color = .line_color, - size = .line_size, - linetype = .line_type, - alpha = .line_alpha + color = .line_color, + linewidth = .line_size, + linetype = .line_type, + alpha = .line_alpha ) # Add Outliers diff --git a/R/plot-seasonal_diagnostics.R b/R/plot-seasonal_diagnostics.R index 4374fdc0..ce1f529e 100644 --- a/R/plot-seasonal_diagnostics.R +++ b/R/plot-seasonal_diagnostics.R @@ -272,8 +272,7 @@ plot_seasonal_diagnostics.data.frame <- function(.data, .date_var, .value, .face facet_ncol <- 1 } else { facet_ncol <- data_formatted %>% - dplyr::select(facet_names) %>% - dplyr::distinct() %>% + dplyr::distinct(dplyr::pick(dplyr::all_of(facet_names))) %>% nrow() } @@ -324,7 +323,7 @@ plot_seasonal_diagnostics.grouped_df <- function(.data, .date_var, .value, .face # ---- DATA SETUP ---- # Ungroup Data - data_formatted <- .data %>% dplyr::ungroup() + data_formatted <- dplyr::ungroup(.data) # ---- PLOT SETUP ---- plot_seasonal_diagnostics( diff --git a/R/plot-stl_diagnostics.R b/R/plot-stl_diagnostics.R index abc69dec..32749509 100644 --- a/R/plot-stl_diagnostics.R +++ b/R/plot-stl_diagnostics.R @@ -184,10 +184,10 @@ plot_stl_diagnostics.data.frame <- function(.data, .date_var, .value, .facet_var # Add line g <- g + ggplot2::geom_line( - color = .line_color, - size = .line_size, - linetype = .line_type, - alpha = .line_alpha + color = .line_color, + linewidth = .line_size, + linetype = .line_type, + alpha = .line_alpha ) # Add facets @@ -195,8 +195,7 @@ plot_stl_diagnostics.data.frame <- function(.data, .date_var, .value, .facet_var facet_ncol <- 1 } else { facet_ncol <- data_formatted %>% - dplyr::select(facet_names) %>% - dplyr::distinct() %>% + dplyr::distinct(dplyr::pick(dplyr::all_of(facet_names))) %>% nrow() } diff --git a/R/plot-time_series.R b/R/plot-time_series.R index 69e3a534..f614ebb8 100644 --- a/R/plot-time_series.R +++ b/R/plot-time_series.R @@ -361,19 +361,19 @@ plot_time_series.data.frame <- function( if (rlang::quo_is_null(color_var_expr)) { g <- g + ggplot2::geom_line( - color = .line_color, - size = .line_size, - linetype = .line_type, - alpha = .line_alpha + color = .line_color, + linewidth = .line_size, + linetype = .line_type, + alpha = .line_alpha ) } else { g <- g + ggplot2::geom_line( ggplot2::aes(color = .color_mod, group = .color_mod), - size = .line_size, - linetype = .line_type, - alpha = .line_alpha + linewidth = .line_size, + linetype = .line_type, + alpha = .line_alpha ) + scale_color_tq() } diff --git a/R/plot-time_series_boxplot.R b/R/plot-time_series_boxplot.R index 48125c41..d65f0db2 100644 --- a/R/plot-time_series_boxplot.R +++ b/R/plot-time_series_boxplot.R @@ -382,8 +382,7 @@ plot_time_series_boxplot.data.frame <- function( # If .value exists, remove it if (any(".value" %in% names(data_formatted))) { - data_formatted <- data_formatted %>% - dplyr::select(-.value) + data_formatted$`.value` <- NULL } @@ -397,21 +396,20 @@ plot_time_series_boxplot.data.frame <- function( if (rlang::quo_is_null(color_var_expr)) { g <- g + ggplot2::geom_boxplot( - ggplot2::aes(group = .box_group) - , - color = .line_color, - size = .line_size, - linetype = .line_type, - alpha = .line_alpha + ggplot2::aes(group = .box_group), + color = .line_color, + linewidth = .line_size, + linetype = .line_type, + alpha = .line_alpha ) } else { g <- g + ggplot2::geom_boxplot( ggplot2::aes(group = .box_group, color = .color_mod), - size = .line_size, - linetype = .line_type, - alpha = .line_alpha + linewidth = .line_size, + linetype = .line_type, + alpha = .line_alpha ) + scale_color_tq() } @@ -426,7 +424,7 @@ plot_time_series_boxplot.data.frame <- function( ggplot2::geom_line( ggplot2::aes(y = .value_smooth), color = .smooth_color, - size = .smooth_size, + linewidth = .smooth_size, alpha = .smooth_alpha, data = data_formatted_smooth ) @@ -436,7 +434,7 @@ plot_time_series_boxplot.data.frame <- function( ggplot2::geom_line( ggplot2::aes(y = .value_smooth, group = .color_mod), color = .smooth_color, - size = .smooth_size, + linewidth = .smooth_size, alpha = .smooth_alpha, data = data_formatted_smooth ) diff --git a/R/recipes-step_slidify_augment.R b/R/recipes-step_slidify_augment.R index b71233b0..336ac240 100644 --- a/R/recipes-step_slidify_augment.R +++ b/R/recipes-step_slidify_augment.R @@ -65,9 +65,10 @@ #' - `recipes::bake()` #' #' @examples -#' library(tidymodels) +#' # library(tidymodels) #' library(dplyr) -#' library(timetk) +#' library(recipes) +#' library(parsnip) #' #' m750 <- m4_monthly %>% #' filter(id == "M750") %>% @@ -76,7 +77,7 @@ #' m750_splits <- time_series_split(m750, assess = "2 years", cumulative = TRUE) #' #' # Make a recipe -#' recipe_spec <- recipe(value ~ date + value_2, training(m750_splits)) %>% +#' recipe_spec <- recipe(value ~ date + value_2, rsample::training(m750_splits)) %>% #' step_slidify_augment( #' value, value_2, #' period = c(6, 12, 24), @@ -87,7 +88,7 @@ #' #' recipe_spec %>% prep() %>% juice() #' -#' bake(prep(recipe_spec), testing(m750_splits)) +#' bake(prep(recipe_spec), rsample::testing(m750_splits)) #' #' #' @importFrom recipes rand_id diff --git a/R/rsample-plot_time_series_cv_plan.R b/R/rsample-plot_time_series_cv_plan.R index f32221bc..0a9c39d3 100644 --- a/R/rsample-plot_time_series_cv_plan.R +++ b/R/rsample-plot_time_series_cv_plan.R @@ -165,7 +165,6 @@ plot_ts_cv_dataframe <- function(.data, .date_var, .value, ..., if (!id_key_in_data) rlang::abort("The data frame must have 'id' and 'key' columns. Try using `tk_time_series_cv_plan()` to unpack the `.data`.") data_formatted %>% - dplyr::ungroup() %>% dplyr::group_by(.id) %>% plot_time_series( .date_var = !! date_var_expr, diff --git a/R/tidyquant-theme-compat.R b/R/tidyquant-theme-compat.R index 2fb917f9..a1973a68 100644 --- a/R/tidyquant-theme-compat.R +++ b/R/tidyquant-theme-compat.R @@ -15,10 +15,10 @@ theme_tq <- function(base_size = 11, base_family = "") { ggplot2::theme( # Base Inherited Elements - line = ggplot2::element_line(colour = blue, size = 0.5, linetype = 1, + line = ggplot2::element_line(colour = blue, linewidth = 0.5, linetype = 1, lineend = "butt"), rect = ggplot2::element_rect(fill = white, colour = blue, - size = 0.5, linetype = 1), + linewidth = 0.5, linetype = 1), text = ggplot2::element_text(family = base_family, face = "plain", colour = blue, size = base_size, lineheight = 0.9, hjust = 0.5, vjust = 0.5, angle = 0, @@ -27,14 +27,14 @@ theme_tq <- function(base_size = 11, base_family = "") { # Axes axis.line = ggplot2::element_blank(), axis.text = ggplot2::element_text(size = ggplot2::rel(0.8)), - axis.ticks = ggplot2::element_line(color = grey, size = ggplot2::rel(1/3)), + axis.ticks = ggplot2::element_line(color = grey, linewidth = ggplot2::rel(1/3)), axis.title = ggplot2::element_text(size = ggplot2::rel(1.0)), # Panel panel.background = ggplot2::element_rect(fill = white, color = NA), - panel.border = ggplot2::element_rect(fill = NA, size = ggplot2::rel(1/2), color = blue), - panel.grid.major = ggplot2::element_line(color = grey, size = ggplot2::rel(1/3)), - panel.grid.minor = ggplot2::element_line(color = grey, size = ggplot2::rel(1/3)), + panel.border = ggplot2::element_rect(fill = NA, linewidth = ggplot2::rel(1/2), color = blue), + panel.grid.major = ggplot2::element_line(color = grey, linewidth = ggplot2::rel(1/3)), + panel.grid.minor = ggplot2::element_line(color = grey, linewidth = ggplot2::rel(1/3)), panel.grid.minor.x = ggplot2::element_blank(), panel.spacing = ggplot2::unit(.75, "cm"), @@ -70,12 +70,12 @@ theme_tq_dark <- function(base_size = 11, base_family = "") { ggplot2::theme( # Axes - axis.ticks = ggplot2::element_line(color = blue, size = ggplot2::rel(1/3)), + axis.ticks = ggplot2::element_line(color = blue, linewidth = ggplot2::rel(1/3)), # Panel panel.background = ggplot2::element_rect(fill = grey, color = NA), - panel.grid.major = ggplot2::element_line(color = white, size = ggplot2::rel(1/3)), - panel.grid.minor = ggplot2::element_line(color = white, size = ggplot2::rel(1/3)), + panel.grid.major = ggplot2::element_line(color = white, linewidth = ggplot2::rel(1/3)), + panel.grid.minor = ggplot2::element_line(color = white, linewidth = ggplot2::rel(1/3)), # Complete theme complete = TRUE @@ -95,12 +95,12 @@ theme_tq_green <- function(base_size = 11, base_family = "") { ggplot2::theme( # Axes - axis.ticks = ggplot2::element_line(color = blue, size = ggplot2::rel(1/3)), + axis.ticks = ggplot2::element_line(color = blue, linewidth = ggplot2::rel(1/3)), # Panel panel.background = ggplot2::element_rect(fill = green, color = NA), - panel.grid.major = ggplot2::element_line(color = white, size = ggplot2::rel(1/3)), - panel.grid.minor = ggplot2::element_line(color = white, size = ggplot2::rel(1/3)), + panel.grid.major = ggplot2::element_line(color = white, linewidth = ggplot2::rel(1/3)), + panel.grid.minor = ggplot2::element_line(color = white, linewidth = ggplot2::rel(1/3)), # Complete theme complete = TRUE diff --git a/R/timetk-package.R b/R/timetk-package.R index ed0535da..cafca032 100644 --- a/R/timetk-package.R +++ b/R/timetk-package.R @@ -13,13 +13,9 @@ #' To learn more about `timetk`, start with the documentation: #' [https://business-science.github.io/timetk/](https://business-science.github.io/timetk/) #' -#' @docType package -#' @name timetk -#' -#' @aliases timetk-package +"_PACKAGE" #' @importFrom dplyr %>% #' @importFrom xts xts #' @import recipes #' @importFrom generics tidy - NULL diff --git a/R/utils-parse_period.R b/R/utils-parse_period.R index 9996ce12..5ebeaba5 100644 --- a/R/utils-parse_period.R +++ b/R/utils-parse_period.R @@ -98,11 +98,13 @@ parse_letter_period <- function(period) { # Check that the freq can be coerced to numeric assert_freq_coerce_to_numeric <- function(freq) { - assertthat::assert_that( - # Coercing to numeric should give a number, not NA - suppressWarnings(!is.na(as.numeric(freq))), - msg = "Frequency must be coercible to numeric." - ) + + problem <- suppressWarnings(anyNA(as.numeric(freq))) + + if (problem) { + stop("Frequency must be coercible to numeric.", call. = FALSE) + } + TRUE } # If sub-second resolution, change to correct second representation diff --git a/README.Rmd b/README.Rmd index d16dc1c3..37f5958c 100644 --- a/README.Rmd +++ b/README.Rmd @@ -13,17 +13,19 @@ knitr::opts_chunk$set( fig.path = "man/figures/README-", dpi = 100 ) -devtools::load_all() ``` # timetk for R + +[![R-CMD-check](https://github.com/business-science/timetk/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/business-science/timetk/actions/workflows/R-CMD-check.yaml) [![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/timetk)](https://cran.r-project.org/package=timetk) ![](http://cranlogs.r-pkg.org/badges/timetk?color=brightgreen) ![](http://cranlogs.r-pkg.org/badges/grand-total/timetk?color=brightgreen) -[![R-CMD-check](https://github.com/business-science/timetk/workflows/R-CMD-check/badge.svg)](https://github.com/business-science/timetk/actions) [![codecov](https://codecov.io/gh/business-science/timetk/branch/master/graph/badge.svg)](https://app.codecov.io/gh/business-science/timetk) + + > Making time series analysis in R easier. @@ -52,7 +54,7 @@ There are _many_ R packages for working with Time Series data. Here's how `timet
-| Task | [timetk](https://business-science.github.io/timetk/) | [tsibble](https://tsibble.tidyverts.org/index.html) | [feasts](https://feasts.tidyverts.org/index.html) | [tibbletime](https://business-science.github.io/tibbletime/) | +| Task | [timetk](https://business-science.github.io/timetk/) | [tsibble](https://tsibble.tidyverts.org/index.html) | [feasts](https://feasts.tidyverts.org/index.html) | [tibbletime (retired)](https://business-science.github.io/tibbletime/) | |------------------------------|--------|---------|---------|-------------| | __Structure__ | | | | | | Data Structure | tibble (tbl) | tsibble (tbl_ts)| tsibble (tbl_ts) | tibbletime (tbl_time) | @@ -160,7 +162,7 @@ The `timetk` package wouldn't be possible without other amazing time series pack * [lubridate](https://lubridate.tidyverse.org/): `timetk` makes heavy use of `floor_date()`, `ceiling_date()`, and `duration()` for "time-based phrases". - Add and Subtract Time (`%+time%` & `%-time%`): `"2012-01-01" %+time% "1 month 4 days"` uses `lubridate` to intelligently offset the day * [xts](https://github.com/joshuaulrich/xts): Used to calculate periodicity and fast lag automation. -* [forecast (retired)](https://pkg.robjhyndman.com/forecast/): Possibly my favorite R package of all time. It's based on `ts`, and it's predecessor is the `tidyverts` (`fable`, `tsibble`, `feasts`, and `fabletools`). +* [forecast (retired)](https://pkg.robjhyndman.com/forecast/): Possibly my favorite R package of all time. It's based on `ts`, and its predecessor is the `tidyverts` (`fable`, `tsibble`, `feasts`, and `fabletools`). - The `ts_impute_vec()` function for low-level vectorized imputation using STL + Linear Interpolation uses `na.interp()` under the hood. - The `ts_clean_vec()` function for low-level vectorized imputation using STL + Linear Interpolation uses `tsclean()` under the hood. - Box Cox transformation `auto_lambda()` uses `BoxCox.Lambda()`. diff --git a/README.md b/README.md index 3b90aedf..28e1d13e 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,14 @@ # timetk for R + + +[![R-CMD-check](https://github.com/business-science/timetk/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/business-science/timetk/actions/workflows/R-CMD-check.yaml) [![CRAN_Status_Badge](http://www.r-pkg.org/badges/version/timetk)](https://cran.r-project.org/package=timetk) ![](http://cranlogs.r-pkg.org/badges/timetk?color=brightgreen) ![](http://cranlogs.r-pkg.org/badges/grand-total/timetk?color=brightgreen) -[![R-CMD-check](https://github.com/business-science/timetk/workflows/R-CMD-check/badge.svg)](https://github.com/business-science/timetk/actions) [![codecov](https://codecov.io/gh/business-science/timetk/branch/master/graph/badge.svg)](https://app.codecov.io/gh/business-science/timetk) + > Making time series analysis in R easier. @@ -37,41 +40,41 @@ data frames or tibbles).
-| Task | [timetk](https://business-science.github.io/timetk/) | [tsibble](https://tsibble.tidyverts.org/index.html) | [feasts](https://feasts.tidyverts.org/index.html) | [tibbletime](https://business-science.github.io/tibbletime/) | -|-------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------|-----------------------------------------------------|---------------------------------------------------|--------------------------------------------------------------| -| **Structure** | | | | | -| Data Structure | tibble (tbl) | tsibble (tbl_ts) | tsibble (tbl_ts) | tibbletime (tbl_time) | -| [**Visualization**](https://business-science.github.io/timetk/articles/TK04_Plotting_Time_Series.html) | | | | | -| Interactive Plots (plotly) | ✅ | :x: | :x: | :x: | -| Static Plots (ggplot) | ✅ | :x: | ✅ | :x: | -| [Time Series](https://business-science.github.io/timetk/articles/TK04_Plotting_Time_Series.html) | ✅ | :x: | ✅ | :x: | -| [Correlation, Seasonality](https://business-science.github.io/timetk/articles/TK05_Plotting_Seasonality_and_Correlation.html) | ✅ | :x: | ✅ | :x: | -| [**Data Wrangling**](https://business-science.github.io/timetk/articles/TK07_Time_Series_Data_Wrangling.html) | | | | | -| Time-Based Summarization | ✅ | :x: | :x: | ✅ | -| Time-Based Filtering | ✅ | :x: | :x: | ✅ | -| Padding Gaps | ✅ | ✅ | :x: | :x: | -| Low to High Frequency | ✅ | :x: | :x: | :x: | -| Imputation | ✅ | ✅ | :x: | :x: | -| Sliding / Rolling | ✅ | ✅ | :x: | ✅ | -| **Machine Learning** | | | | | -| [Time Series Machine Learning](https://business-science.github.io/timetk/articles/TK03_Forecasting_Using_Time_Series_Signature.html) | ✅ | :x: | :x: | :x: | -| [Anomaly Detection](https://business-science.github.io/timetk/articles/TK08_Automatic_Anomaly_Detection.html) | ✅ | :x: | :x: | :x: | -| [Clustering](https://business-science.github.io/timetk/articles/TK09_Clustering.html) | ✅ | :x: | :x: | :x: | -| [**Feature Engineering (recipes)**](https://business-science.github.io/timetk/articles/TK03_Forecasting_Using_Time_Series_Signature.html) | | | | | -| Date Feature Engineering | ✅ | :x: | :x: | :x: | -| Holiday Feature Engineering | ✅ | :x: | :x: | :x: | -| Fourier Series | ✅ | :x: | :x: | :x: | -| Smoothing & Rolling | ✅ | :x: | :x: | :x: | -| Padding | ✅ | :x: | :x: | :x: | -| Imputation | ✅ | :x: | :x: | :x: | -| **Cross Validation (rsample)** | | | | | -| [Time Series Cross Validation](https://business-science.github.io/timetk/reference/time_series_cv.html) | ✅ | :x: | :x: | :x: | -| [Time Series CV Plan Visualization](https://business-science.github.io/timetk/reference/plot_time_series_cv_plan.html) | ✅ | :x: | :x: | :x: | -| **More Awesomeness** | | | | | -| [Making Time Series (Intelligently)](https://business-science.github.io/timetk/articles/TK02_Time_Series_Date_Sequences.html) | ✅ | ✅ | :x: | ✅ | -| [Handling Holidays & Weekends](https://business-science.github.io/timetk/articles/TK02_Time_Series_Date_Sequences.html) | ✅ | :x: | :x: | :x: | -| [Class Conversion](https://business-science.github.io/timetk/articles/TK00_Time_Series_Coercion.html) | ✅ | ✅ | :x: | :x: | -| [Automatic Frequency & Trend](https://business-science.github.io/timetk/articles/TK06_Automatic_Frequency_And_Trend_Selection.html) | ✅ | :x: | :x: | :x: | +| Task | [timetk](https://business-science.github.io/timetk/) | [tsibble](https://tsibble.tidyverts.org/index.html) | [feasts](https://feasts.tidyverts.org/index.html) | [tibbletime (retired)](https://business-science.github.io/tibbletime/) | +|-------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------|-----------------------------------------------------|---------------------------------------------------|------------------------------------------------------------------------| +| **Structure** | | | | | +| Data Structure | tibble (tbl) | tsibble (tbl_ts) | tsibble (tbl_ts) | tibbletime (tbl_time) | +| [**Visualization**](https://business-science.github.io/timetk/articles/TK04_Plotting_Time_Series.html) | | | | | +| Interactive Plots (plotly) | ✅ | :x: | :x: | :x: | +| Static Plots (ggplot) | ✅ | :x: | ✅ | :x: | +| [Time Series](https://business-science.github.io/timetk/articles/TK04_Plotting_Time_Series.html) | ✅ | :x: | ✅ | :x: | +| [Correlation, Seasonality](https://business-science.github.io/timetk/articles/TK05_Plotting_Seasonality_and_Correlation.html) | ✅ | :x: | ✅ | :x: | +| [**Data Wrangling**](https://business-science.github.io/timetk/articles/TK07_Time_Series_Data_Wrangling.html) | | | | | +| Time-Based Summarization | ✅ | :x: | :x: | ✅ | +| Time-Based Filtering | ✅ | :x: | :x: | ✅ | +| Padding Gaps | ✅ | ✅ | :x: | :x: | +| Low to High Frequency | ✅ | :x: | :x: | :x: | +| Imputation | ✅ | ✅ | :x: | :x: | +| Sliding / Rolling | ✅ | ✅ | :x: | ✅ | +| **Machine Learning** | | | | | +| [Time Series Machine Learning](https://business-science.github.io/timetk/articles/TK03_Forecasting_Using_Time_Series_Signature.html) | ✅ | :x: | :x: | :x: | +| [Anomaly Detection](https://business-science.github.io/timetk/articles/TK08_Automatic_Anomaly_Detection.html) | ✅ | :x: | :x: | :x: | +| [Clustering](https://business-science.github.io/timetk/articles/TK09_Clustering.html) | ✅ | :x: | :x: | :x: | +| [**Feature Engineering (recipes)**](https://business-science.github.io/timetk/articles/TK03_Forecasting_Using_Time_Series_Signature.html) | | | | | +| Date Feature Engineering | ✅ | :x: | :x: | :x: | +| Holiday Feature Engineering | ✅ | :x: | :x: | :x: | +| Fourier Series | ✅ | :x: | :x: | :x: | +| Smoothing & Rolling | ✅ | :x: | :x: | :x: | +| Padding | ✅ | :x: | :x: | :x: | +| Imputation | ✅ | :x: | :x: | :x: | +| **Cross Validation (rsample)** | | | | | +| [Time Series Cross Validation](https://business-science.github.io/timetk/reference/time_series_cv.html) | ✅ | :x: | :x: | :x: | +| [Time Series CV Plan Visualization](https://business-science.github.io/timetk/reference/plot_time_series_cv_plan.html) | ✅ | :x: | :x: | :x: | +| **More Awesomeness** | | | | | +| [Making Time Series (Intelligently)](https://business-science.github.io/timetk/articles/TK02_Time_Series_Date_Sequences.html) | ✅ | ✅ | :x: | ✅ | +| [Handling Holidays & Weekends](https://business-science.github.io/timetk/articles/TK02_Time_Series_Date_Sequences.html) | ✅ | :x: | :x: | :x: | +| [Class Conversion](https://business-science.github.io/timetk/articles/TK00_Time_Series_Coercion.html) | ✅ | ✅ | :x: | :x: | +| [Automatic Frequency & Trend](https://business-science.github.io/timetk/articles/TK06_Automatic_Frequency_And_Trend_Selection.html) | ✅ | :x: | :x: | :x: |
@@ -174,7 +177,7 @@ series packages. - [xts](https://github.com/joshuaulrich/xts): Used to calculate periodicity and fast lag automation. - [forecast (retired)](https://pkg.robjhyndman.com/forecast/): Possibly - my favorite R package of all time. It’s based on `ts`, and it’s + my favorite R package of all time. It’s based on `ts`, and its predecessor is the `tidyverts` (`fable`, `tsibble`, `feasts`, and `fabletools`). - The `ts_impute_vec()` function for low-level vectorized imputation diff --git a/man/parse_date2.Rd b/man/parse_date2.Rd index b38bd28a..71f789f1 100644 --- a/man/parse_date2.Rd +++ b/man/parse_date2.Rd @@ -61,6 +61,6 @@ parse_datetime2("2011 Jan 1 12:35:21", tz = "Europe/London") } \references{ \itemize{ -\item This function wraps the \code{anytime::anytime()} and \code{anytime::anydate} functions developed by Dirk Eddelbuettel. +\item This function wraps the \code{anytime::anytime()} and \code{anytime::anydate()} functions developed by Dirk Eddelbuettel. } } diff --git a/man/plot_acf_diagnostics.Rd b/man/plot_acf_diagnostics.Rd index 16719105..ff7825b8 100644 --- a/man/plot_acf_diagnostics.Rd +++ b/man/plot_acf_diagnostics.Rd @@ -56,7 +56,7 @@ versus the \code{.value}. Useful for evaluating external lagged regressors.} \item{.line_color}{Line color. Use keyword: "scale_color" to change the color by the facet.} -\item{.line_size}{Line size} +\item{.line_size}{Line size (linewidth)} \item{.line_alpha}{Line opacity. Adjust the transparency of the line. Range: (0, 1)} diff --git a/man/step_slidify_augment.Rd b/man/step_slidify_augment.Rd index e1133861..6e491d01 100644 --- a/man/step_slidify_augment.Rd +++ b/man/step_slidify_augment.Rd @@ -119,9 +119,10 @@ If instability is not desirable for de-noising operations, a suitable alternativ is \code{\link[=step_smooth]{step_smooth()}}, which implements local polynomial regression. } \examples{ -library(tidymodels) +# library(tidymodels) library(dplyr) -library(timetk) +library(recipes) +library(parsnip) m750 <- m4_monthly \%>\% filter(id == "M750") \%>\% @@ -130,7 +131,7 @@ m750 <- m4_monthly \%>\% m750_splits <- time_series_split(m750, assess = "2 years", cumulative = TRUE) # Make a recipe -recipe_spec <- recipe(value ~ date + value_2, training(m750_splits)) \%>\% +recipe_spec <- recipe(value ~ date + value_2, rsample::training(m750_splits)) \%>\% step_slidify_augment( value, value_2, period = c(6, 12, 24), @@ -141,7 +142,7 @@ recipe_spec <- recipe(value ~ date + value_2, training(m750_splits)) \%>\% recipe_spec \%>\% prep() \%>\% juice() -bake(prep(recipe_spec), testing(m750_splits)) +bake(prep(recipe_spec), rsample::testing(m750_splits)) } diff --git a/man/time_series_cv.Rd b/man/time_series_cv.Rd index 80d45560..9234395b 100644 --- a/man/time_series_cv.Rd +++ b/man/time_series_cv.Rd @@ -44,7 +44,7 @@ which returns the maximum number of slices.} \item{point_forecast}{Whether or not to have the testing set be a single point forecast or to be a forecast horizon. The default is to be a forecast horizon. Default: \code{FALSE}} -\item{...}{Not currently used.} +\item{...}{These dots are for future extensions and must be empty.} } \value{ An tibble with classes \code{time_series_cv}, \code{rset}, \code{tbl_df}, \code{tbl}, diff --git a/man/time_series_split.Rd b/man/time_series_split.Rd index 67ce31b8..8ca5dd81 100644 --- a/man/time_series_split.Rd +++ b/man/time_series_split.Rd @@ -43,7 +43,7 @@ size specified by \code{initial} at each resample?.} \item{point_forecast}{Whether or not to have the testing set be a single point forecast or to be a forecast horizon. The default is to be a forecast horizon. Default: \code{FALSE}} -\item{...}{Not currently used.} +\item{...}{These dots are for future extensions and must be empty.} } \value{ An \code{rsplit} object that can be used with the \code{training} and \code{testing} diff --git a/man/timetk.Rd b/man/timetk-package.Rd similarity index 59% rename from man/timetk.Rd rename to man/timetk-package.Rd index 8510c324..0c9b1502 100644 --- a/man/timetk.Rd +++ b/man/timetk-package.Rd @@ -1,7 +1,7 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/timetk-package.R \docType{package} -\name{timetk} +\name{timetk-package} \alias{timetk} \alias{timetk-package} \title{timetk: Time Series Analysis in the Tidyverse} @@ -20,3 +20,21 @@ The \code{timetk} package has several benefits: To learn more about \code{timetk}, start with the documentation: \url{https://business-science.github.io/timetk/} } +\seealso{ +Useful links: +\itemize{ + \item \url{https://github.com/business-science/timetk} + \item \url{https://business-science.github.io/timetk/} + \item Report bugs at \url{https://github.com/business-science/timetk/issues} +} + +} +\author{ +\strong{Maintainer}: Matt Dancho \email{mdancho@business-science.io} + +Authors: +\itemize{ + \item Davis Vaughan \email{dvaughan@business-science.io} +} + +} diff --git a/man/tk_get_timeseries.Rd b/man/tk_get_timeseries.Rd index 26bc9112..2961f625 100644 --- a/man/tk_get_timeseries.Rd +++ b/man/tk_get_timeseries.Rd @@ -64,7 +64,7 @@ tk_get_timeseries_summary(idx_weekly) idx_yearmon <- seq.Date(from = ymd("2016-01-01"), by = "month", length.out = 12) \%>\% - as.yearmon() + zoo::as.yearmon() tk_get_timeseries_signature(idx_yearmon) tk_get_timeseries_summary(idx_yearmon) diff --git a/tests/testthat/test-dplyr-pad_by_time.R b/tests/testthat/test-dplyr-pad_by_time.R index 88230fa6..17507553 100644 --- a/tests/testthat/test-dplyr-pad_by_time.R +++ b/tests/testthat/test-dplyr-pad_by_time.R @@ -1,19 +1,19 @@ testthat::context("Pad By Time") +library(dplyr) +library(lubridate) - -testthat::test_that("Single Pad By Time Works", { - df <- tibble( +test_that("Single Pad By Time Works", { + df <- dplyr::tibble( date = c("2011-01-01", "2011-01-03") %>% parse_date2(), value = c(1, 3) - ) %>% pad_by_time(.by = "1 day", .pad_value = 2) expect_equal(df$value, 1:3) }) -testthat::test_that("Grouped Pad By Time Works", { - df <- tibble( +test_that("Grouped Pad By Time Works", { + df <- dplyr::tibble( group = c(rep("A", 2), rep("B", 2)), date = rep(c("2011-01-01", "2011-01-03"), 2) %>% parse_date2(), value = rep(c(1, 3), 2) @@ -24,5 +24,3 @@ testthat::test_that("Grouped Pad By Time Works", { expect_equal(df$value, c(1:3, 1:3)) }) - - diff --git a/tests/testthat/test-recipes-step_timeseries_signature.R b/tests/testthat/test-recipes-step_timeseries_signature.R index f7b97436..014f2c41 100644 --- a/tests/testthat/test-recipes-step_timeseries_signature.R +++ b/tests/testthat/test-recipes-step_timeseries_signature.R @@ -1,5 +1,6 @@ context("Test recipe: step_timeseries_signature()") - +library(dplyr) +library(recipes) FB_tbl <- FANG %>% dplyr::filter(symbol == "FB") %>% diff --git a/tests/testthat/test-tk_augment_timeseries.R b/tests/testthat/test-tk_augment_timeseries.R index 138c7fb2..da97cf65 100644 --- a/tests/testthat/test-tk_augment_timeseries.R +++ b/tests/testthat/test-tk_augment_timeseries.R @@ -46,7 +46,7 @@ test_that("tk_augment_timeseries_signature(default) test returns correct format. # Test back-ticked columns test_that("tk_augment_timeseries_signature() works with back ticked columns.", { - tib <- tibble( + tib <- dplyr::tibble( `date column` = seq.Date(from = as.Date("2017-01-01"), by = "day", length.out = 10), `my value` = 1:10 ) diff --git a/tests/testthat/test-tk_get_timeseries.R b/tests/testthat/test-tk_get_timeseries.R index 6071346a..bbf7aa90 100644 --- a/tests/testthat/test-tk_get_timeseries.R +++ b/tests/testthat/test-tk_get_timeseries.R @@ -1,5 +1,5 @@ context("Testing tk_get_timeseries functions") - +library(lubridate) n <- 29 # tk_get_timeseries_signature ----- @@ -32,7 +32,7 @@ test_yearmon <- c("2016-01-01", "2016-02-01", "2016-03-01") %>% ymd() %>% - as.yearmon() + zoo::as.yearmon() test_that("tk_get_timeseries_signature(yearmon) test returns correct format.", { test <- tk_get_timeseries_signature(test_yearmon) @@ -46,7 +46,7 @@ test_yearqtr <- c("2016-01-01", "2016-07-01", "2016-10-01") %>% ymd() %>% - as.yearqtr() + zoo::as.yearqtr() test_that("tk_get_timeseries_signature(yearqtr) test returns correct format.", { test <- tk_get_timeseries_signature(test_yearqtr) @@ -97,7 +97,7 @@ test_that("tk_get_timeseries_summary(date) test returns correct format.", { test_yearmon <- c("2016-01", "2016-02", "2016-03") %>% - as.yearmon() + zoo::as.yearmon() test_that("tk_get_timeseries_summary(yearmon) test returns correct format.", { test <- tk_get_timeseries_summary(test_yearmon) @@ -110,7 +110,7 @@ test_yearqtr <- c("2016 Q1", "2016 Q2", "2016 Q3", "2016 Q4") %>% - as.yearqtr() + zoo::as.yearqtr() test_that("tk_get_timeseries_summary(yearqtr) test returns correct format.", { test <- tk_get_timeseries_summary(test_yearqtr) @@ -138,9 +138,9 @@ test_date_vars <- tibble::tibble( my.date = ymd(c("2016-01-01", "2016-01-02")), my.chr = c("a", "b"), my.datetime = ymd_hms(c("2016-01-01 00:00:00", "2016-01-02 00:00:00")), - my.yearmon = as.yearmon(c("2016-01", "2016-01")), + my.yearmon = zoo::as.yearmon(c("2016-01", "2016-01")), more.chr = c("x", "y"), - my.yearqtr = as.yearqtr(c("2016 Q1", "2016 Q1")) + my.yearqtr = zoo::as.yearqtr(c("2016 Q1", "2016 Q1")) ) test_that("tk_get_timeseries_variables() test returns correct format.", { diff --git a/tests/testthat/test-tk_make_timeseries.R b/tests/testthat/test-tk_make_timeseries.R index 2a096e56..0a5ef8ca 100644 --- a/tests/testthat/test-tk_make_timeseries.R +++ b/tests/testthat/test-tk_make_timeseries.R @@ -2,7 +2,7 @@ context("Testing tk_make_timeseries") test_that("Date Sequences", { - + library(lubridate) # Daily seq_0 <- seq.Date(as.Date("2017-01-01"), as.Date("2017-12-31"), by = "day") seq_1 <- tk_make_timeseries("2017-01-01", "2017-12-31") @@ -47,7 +47,7 @@ test_that("Date Sequences", { test_that("Time Sequences", { - + library(lubridate) # Start + End, Guesses by second seq_0 <- seq.POSIXt(ymd_hms("2016-01-01 01:01:02"), ymd_hms("2016-01-01 01:01:04"), by = "sec") seq_1 <- tk_make_timeseries("2016-01-01 01:01:02", "2016-01-01 01:01:04") diff --git a/tests/testthat/test-tk_make_timeseries_future-OLD.R b/tests/testthat/test-tk_make_timeseries_future-OLD.R index d9ae66a3..7584e66f 100644 --- a/tests/testthat/test-tk_make_timeseries_future-OLD.R +++ b/tests/testthat/test-tk_make_timeseries_future-OLD.R @@ -225,24 +225,24 @@ test_that("tk_make_future_timeseries(date) test returns correct format.", { test_yearmon <- c("2016-01", "2016-02", "2016-03") %>% - as.yearmon() + zoo::as.yearmon() test_that("tk_make_future_timeseries(yearmon) test returns correct format.", { # No skip values expect_warning(test <- tk_make_future_timeseries(test_yearmon, n_future = 3)) expectation <- c("2016-04", "2016-05", "2016-06") %>% - as.yearmon() + zoo::as.yearmon() expect_equal(test, expectation) # Skip values - skip <- as.yearmon("2016-05") + skip <- zoo::as.yearmon("2016-05") expect_warning(test <- tk_make_future_timeseries(test_yearmon, n_future = 3, skip_values = skip)) expectation <- c("2016-04", "2016-06") %>% - as.yearmon() + zoo::as.yearmon() expect_equal(test, expectation) # Test when skip values are not within future index - skip <- as.yearmon(c("2016-10", "2016-11")) + skip <- zoo::as.yearmon(c("2016-10", "2016-11")) expect_message(expect_warning(tk_make_future_timeseries(test_yearmon, n_future = 3, skip_values = skip))) # Inspect validation of skip_values @@ -250,10 +250,10 @@ test_that("tk_make_future_timeseries(yearmon) test returns correct format.", { expect_equal(test, NA) # insert values - insert <- as.yearmon(c("2017-10", "2017-11")) + insert <- zoo::as.yearmon(c("2017-10", "2017-11")) expect_warning(test <- tk_make_future_timeseries(test_yearmon, n_future = 3, insert_values = insert)) expectation <- c("2016-04", "2016-05", "2016-06", " 2017-10", "2017-11") %>% - as.yearmon() + zoo::as.yearmon() expect_equal(test, expectation) }) @@ -262,27 +262,27 @@ test_yearqtr <- c("2016 Q1", "2016 Q2", "2016 Q3", "2016 Q4") %>% - as.yearqtr() + zoo::as.yearqtr() test_that("tk_make_future_timeseries(yearqtr) test returns correct format.", { # No skip values expect_warning(test <- tk_make_future_timeseries(test_yearqtr, n_future = 4)) expectation <- c("2017 Q1", "2017 Q2", "2017 Q3", "2017 Q4") %>% - as.yearqtr() + zoo::as.yearqtr() expect_equal(test, expectation) # Skip values - skip <- as.yearqtr("2017 Q1") + skip <- zoo::as.yearqtr("2017 Q1") expect_warning(test <- tk_make_future_timeseries(test_yearqtr, n_future = 4, skip_values = skip)) expectation <- c("2017 Q2", "2017 Q3", "2017 Q4") %>% - as.yearqtr() + zoo::as.yearqtr() expect_equal(test, expectation) # Test when skip values are not within future index - skip <- as.yearqtr(c("2017 Q1", "2018 Q2")) + skip <- zoo::as.yearqtr(c("2017 Q1", "2018 Q2")) expect_warning(expect_message(test <- tk_make_future_timeseries(test_yearqtr, n_future = 4, skip_values = skip))) expectation <- c("2017 Q2", "2017 Q3", "2017 Q4") %>% - as.yearqtr() + zoo::as.yearqtr() expect_equal(test, expectation) # Inspect validation of skip_values diff --git a/tests/testthat/test-tk_make_timeseries_future.R b/tests/testthat/test-tk_make_timeseries_future.R index 90ade561..05387612 100644 --- a/tests/testthat/test-tk_make_timeseries_future.R +++ b/tests/testthat/test-tk_make_timeseries_future.R @@ -250,23 +250,23 @@ test_that("tk_make_future_timeseries(yearmon) test returns correct format.", { test_yearmon <- c("2016-01", "2016-02", - "2016-03") %>% as.yearmon() + "2016-03") %>% zoo::as.yearmon() # No skip values test <- tk_make_future_timeseries(test_yearmon, length_out = "3 months") expectation <- c("2016-04", "2016-05", "2016-06") %>% - as.yearmon() + zoo::as.yearmon() expect_equal(test, expectation) # Skip values - skip <- as.yearmon("2016-05") + skip <- zoo::as.yearmon("2016-05") test <- tk_make_future_timeseries(test_yearmon, length_out = 2, skip_values = skip) expectation <- c("2016-04", "2016-06") %>% - as.yearmon() + zoo::as.yearmon() expect_equal(test, expectation) # Test when skip values are not within future index - skip <- as.yearmon(c("2016-10", "2016-11")) + skip <- zoo::as.yearmon(c("2016-10", "2016-11")) expect_message(tk_make_future_timeseries(test_yearmon, length_out = 3, skip_values = skip)) # Inspect validation of skip_values @@ -274,10 +274,10 @@ test_that("tk_make_future_timeseries(yearmon) test returns correct format.", { expect_equal(test, NA) # insert values - insert <- as.yearmon(c("2017-10", "2017-11")) + insert <- zoo::as.yearmon(c("2017-10", "2017-11")) test <- tk_make_future_timeseries(test_yearmon, length_out = 3, insert_values = insert) expectation <- c("2016-04", "2016-05", "2016-06") %>% - as.yearmon() + zoo::as.yearmon() expect_equal(test, expectation) }) @@ -290,26 +290,26 @@ test_that("tk_make_future_timeseries(yearqtr) test returns correct format.", { test_yearqtr <- c("2016 Q1", "2016 Q2", "2016 Q3", - "2016 Q4") %>% as.yearqtr() + "2016 Q4") %>% zoo::as.yearqtr() # No skip values test <- tk_make_future_timeseries(test_yearqtr, length_out = "1 year") expectation <- c("2017 Q1", "2017 Q2", "2017 Q3", "2017 Q4") %>% - as.yearqtr() + zoo::as.yearqtr() expect_equal(test, expectation) # Skip values - skip <- as.yearqtr("2017 Q1") + skip <- zoo::as.yearqtr("2017 Q1") test <- tk_make_future_timeseries(test_yearqtr, length_out = 4, skip_values = skip) expectation <- c("2017 Q2", "2017 Q3", "2017 Q4", "2018 Q1") %>% - as.yearqtr() + zoo::as.yearqtr() expect_equal(test, expectation) # Test when skip values are not within future index - skip <- as.yearqtr(c("2017 Q1", "2018 Q2")) + skip <- zoo::as.yearqtr(c("2017 Q1", "2018 Q2")) expect_message(test <- tk_make_future_timeseries(test_yearqtr, length_out = 4, skip_values = skip)) expectation <- c("2017 Q2", "2017 Q3", "2017 Q4", "2018 Q1") %>% - as.yearqtr() + zoo::as.yearqtr() expect_equal(test, expectation) # Inspect validation of skip_values diff --git a/tests/testthat/test-tk_xts.R b/tests/testthat/test-tk_xts.R index be0695e1..1546fda6 100644 --- a/tests/testthat/test-tk_xts.R +++ b/tests/testthat/test-tk_xts.R @@ -35,11 +35,11 @@ test_that("tbl to xts test returns xts with correct rows and columns.", { expect_equal(colnames(test_xts_3), select) # Test back-ticked columns - tib <- tibble( + tib <- dplyr::tibble( `date column` = seq.Date(from = as.Date("2017-01-01"), by = "day", length.out = 10), `my value` = 1:10 ) - test <- tk_xts(tib, silent = T) + test <- tk_xts(tib, silent = TRUE) expect_equal(nrow(test), 10) expect_equal(ncol(test), 1) expect_is(test, "xts") diff --git a/timetk.Rproj b/timetk.Rproj index 0d1fde21..cf7e751b 100644 --- a/timetk.Rproj +++ b/timetk.Rproj @@ -19,3 +19,5 @@ BuildType: Package PackageUseDevtools: Yes PackageInstallArgs: --no-multiarch --with-keep.source PackageRoxygenize: rd,collate,namespace + +SpellingDictionary: en_US diff --git a/vignettes/TK03_Forecasting_Using_Time_Series_Signature.Rmd b/vignettes/TK03_Forecasting_Using_Time_Series_Signature.Rmd index 67a86b36..1828121b 100644 --- a/vignettes/TK03_Forecasting_Using_Time_Series_Signature.Rmd +++ b/vignettes/TK03_Forecasting_Using_Time_Series_Signature.Rmd @@ -40,11 +40,12 @@ In this vignette, the user will learn methods to implement machine learning to p Before we get started, load the following packages. ```{r, message = FALSE} -library(tidymodels) -library(modeltime) library(dplyr) library(timetk) - +library(recipes) +library(parsnip) +library(workflows) +library(rsample) # Used to convert plots from interactive to static interactive = FALSE ``` @@ -58,8 +59,7 @@ _Source: Fanaee-T, Hadi, and Gama, Joao, 'Event labeling combining ensemble dete ```{r} # Read data bike_transactions_tbl <- bike_sharing_daily %>% - select(dteday, cnt) %>% - set_names(c("date", "value")) + select(date = dteday, value = cnt) bike_transactions_tbl ``` @@ -111,6 +111,7 @@ The first step is to add the _time series signature_ to the training set, which - The `timetk` has `step_timeseries_signature()`, which is used to add a number of features that can help machine learning models. ```{r} +library(recipes) # Add time series signature recipe_spec_timeseries <- recipe(value ~ ., data = training(splits)) %>% step_timeseries_signature(date) @@ -166,7 +167,9 @@ workflow_lm The workflow can be trained with the `fit()` function. ```{r} -workflow_fit_lm <- workflow_lm %>% fit(data = training(splits)) +if (requireNamespace("glmnet")) { + workflow_fit_lm <- workflow_lm %>% fit(data = training(splits)) +} ``` @@ -192,20 +195,23 @@ __The Modeltime Workflow__ is designed to speed up model evaluation and selectio __The Modeltime Table__ organizes the models with IDs and creates generic descriptions to help us keep track of our models. Let's add the models to a `modeltime_table()`. ```{r, paged.print = F} -model_table <- modeltime_table( +if (rlang::is_installed("modeltime")) { + model_table <- modeltime::modeltime_table( workflow_fit_lm ) model_table +} + ``` ## Calibration -__Model Calibration__ is used to quantify error and estimate confidence intervals. We'll perform model calibration on the out-of-sample data (aka. the Testing Set) with the `modeltime_calibrate()` function. Two new columns are generated (".type" and ".calibration_data"), the most important of which is the ".calibration_data". This includes the actual values, fitted values, and residuals for the testing set. +__Model Calibration__ is used to quantify error and estimate confidence intervals. We'll perform model calibration on the out-of-sample data (aka. the Testing Set) with the `modeltime::modeltime_calibrate()` function. Two new columns are generated (".type" and ".calibration_data"), the most important of which is the ".calibration_data". This includes the actual values, fitted values, and residuals for the testing set. -```{r, paged.print = F} +```{r, paged.print = F, eval=rlang::is_installed("modeltime")} calibration_table <- model_table %>% - modeltime_calibrate(testing(splits)) + modeltime::modeltime_calibrate(testing(splits)) calibration_table ``` @@ -214,27 +220,27 @@ calibration_table With calibrated data, we can visualize the testing predictions (forecast). -- Use `modeltime_forecast()` to generate the forecast data for the testing set as a tibble. -- Use `plot_modeltime_forecast()` to visualize the results in interactive and static plot formats. +- Use `modeltime::modeltime_forecast()` to generate the forecast data for the testing set as a tibble. +- Use `modeltime::plot_modeltime_forecast()` to visualize the results in interactive and static plot formats. -```{r} +```{r, eval=rlang::is_installed("modeltime")} calibration_table %>% - modeltime_forecast(actual_data = bike_transactions_tbl) %>% - plot_modeltime_forecast(.interactive = interactive) + modeltime::modeltime_forecast(actual_data = bike_transactions_tbl) %>% + modeltime::plot_modeltime_forecast(.interactive = interactive) ``` ### Accuracy (Testing Set) Next, calculate the testing accuracy to compare the models. -- Use `modeltime_accuracy()` to generate the out-of-sample accuracy metrics as a tibble. -- Use `table_modeltime_accuracy()` to generate interactive and static +- Use `modeltime::modeltime_accuracy()` to generate the out-of-sample accuracy metrics as a tibble. +- Use `modeltime::table_modeltime_accuracy()` to generate interactive and static -```{r} +```{r, eval=rlang::is_installed("modeltime")} calibration_table %>% - modeltime_accuracy() %>% - table_modeltime_accuracy(.interactive = interactive) + modeltime::modeltime_accuracy() %>% + modeltime::table_modeltime_accuracy(.interactive = interactive) ``` @@ -242,14 +248,14 @@ calibration_table %>% __Refitting__ is a best-practice before forecasting the future. -- `modeltime_refit()`: We re-train on full data (`bike_transactions_tbl`) -- `modeltime_forecast()`: For models that only depend on the "date" feature, we can use `h` (horizon) to forecast forward. Setting `h = "12 months"` forecasts then next 12-months of data. +- `modeltime::modeltime_refit()`: We re-train on full data (`bike_transactions_tbl`) +- `modeltime::modeltime_forecast()`: For models that only depend on the "date" feature, we can use `h` (horizon) to forecast forward. Setting `h = "12 months"` forecasts then next 12-months of data. -```{r} +```{r, eval=rlang::is_installed("modeltime")} calibration_table %>% - modeltime_refit(bike_transactions_tbl) %>% - modeltime_forecast(h = "12 months", actual_data = bike_transactions_tbl) %>% - plot_modeltime_forecast(.interactive = interactive) + modeltime::modeltime_refit(bike_transactions_tbl) %>% + modeltime::modeltime_forecast(h = "12 months", actual_data = bike_transactions_tbl) %>% + modeltime::plot_modeltime_forecast(.interactive = interactive) ``` diff --git a/vignettes/TK07_Time_Series_Data_Wrangling.Rmd b/vignettes/TK07_Time_Series_Data_Wrangling.Rmd index b7fb2f6e..0c6c5bdc 100644 --- a/vignettes/TK07_Time_Series_Data_Wrangling.Rmd +++ b/vignettes/TK07_Time_Series_Data_Wrangling.Rmd @@ -200,7 +200,7 @@ FANG %>% group_by(symbol) %>% # Apply Sliding Function mutate(rolling_avg_30 = roll_avg_30(adjusted)) %>% - pivot_longer(cols = c(adjusted, rolling_avg_30)) %>% + tidyr::pivot_longer(cols = c(adjusted, rolling_avg_30)) %>% plot_time_series(date, value, .color_var = name, .facet_ncol = 2, .smooth = FALSE, .interactive = FALSE)