Nothing
      #' Standardize the time series data frame
#' Value column is renamed to `values`
#' @noRd
standardize_ts_tbl <- function(ts_data) {
  tsbox::ts_tbl(ts_data) %>%
    dplyr::rename(values = dplyr::any_of(c("value", "values"))) %>%
    suppressMessages()
}
#' Define a custom function for frequency labeling
#' @noRd
label_frequency <- function(frequency) {
  dplyr::case_when(
    round(frequency) == 365 ~ "day",
    round(frequency) == 52 ~ "week",
    round(frequency) == 35 ~ "week",
    round(frequency) == 12 ~ "month",
    round(frequency) == 4 ~ "quarter",
    round(frequency) == 1 ~ "year",
    TRUE ~ NA_character_  # Default to NA if no match
  )
}
#' Helper function for generating starts and forecasting date
#' @noRd
get_final_date <- function(freq, target_start, target_end, h) {
  if (freq == 1) {
    target_start <- lubridate::year(target_start)
    final_date <- target_end %m+% lubridate::years(h) %>%
      lubridate::ceiling_date("year") %m-% lubridate::days(1)
  } else if (freq == 4) {
    target_start <- paste0(lubridate::year(target_start), "Q", lubridate::quarter(target_start))
    final_date <- target_end %m+% months(3 * h) %>%
      lubridate::ceiling_date("quarter") %m-% lubridate::days(1)
  } else if (freq == 12) {
    target_start <- paste0(lubridate::year(target_start), "-", lubridate::month(target_start))
    final_date <- target_end %m+% months(h) %>%
      lubridate::ceiling_date("month") %m-% lubridate::days(1)
  } else if (round(freq) %in% c(35, 52)) {
    target_start <- paste0(lubridate::year(target_start), "-", lubridate::week(target_start))
    final_date <- target_end %m+% lubridate::weeks(h) %>%
      lubridate::ceiling_date("week") %m-% lubridate::days(1)
  } else {
    stop("Unsupported frequency.")
  }
  list(target_start = target_start, final_date = final_date)
}
#' Exponential almon polynomial
#' @noRd
exp_almon <- function(p, K) {
  # p: vector of parameters (length corresponds to the order of the polynomial + 1)
  # K: number of lags
  if (length(p) < 2) {
    rlang::abort("The parameter vector 'p' must have at least 2 elements.")
  }
  # Create a sequence of lag indices
  k <- 0:(K - 1)
  # Compute the exponential Almon weights
  polynomial_terms <- sapply(0:(length(p) - 1), function(i) p[i + 1] * k^i)
  numerator <- exp(rowSums(polynomial_terms))
  denominator <- sum(numerator)
  weights <- numerator / denominator
  return(weights)
}
#' Define the objective function for expalmon regression
#' @noRd
expalmon_objective <- function(p, y, x, K, target_freq_label) {
  target_name <- y$id[1]
  indic_name <- x$id[1]
  # Compute the weights
  weights <- exp_almon(p, K)
  # Aggregate high-frequency data into low-frequency predictors
  aggregated_x <- x %>%
    dplyr::mutate(period = lubridate::floor_date(time, rlang::syms(target_freq_label))) %>%
    tsbox::ts_na_omit() %>% suppressMessages() %>%
    dplyr::group_by(period) %>% # Group by the start of each period
    dplyr::slice_tail(n = K) %>% # Select the last K obs of each group
    # calculated weighted sum
    dplyr::summarise(dplyr::across(dplyr::where(is.numeric), ~ sum(weights * ., na.rm=T))) %>%
    dplyr::ungroup() %>%
    dplyr::mutate(
      time = period,
      id = indic_name) %>%
    dplyr::select(-period)
  data <- dplyr::bind_rows(aggregated_x, y) %>%
    tsbox::ts_wide() %>% suppressMessages() %>%
    stats::na.omit()
  # fit the model
  model <- stats::lm(stats::as.formula(paste0(target_name, " ~ ", indic_name)), data = data)
  fitted_values <- stats::predict(model)
  # Compute residuals
  residuals <- data[target_name] - fitted_values
  # Return the sum of squared residuals
  return(sum(residuals^2))
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.