R/covert_date_period.R

Defines functions convert_datim_pd_to_qtr convert_qtr_to_date convert_date_to_qtr

Documented in convert_date_to_qtr convert_datim_pd_to_qtr convert_qtr_to_date

#' Convert Date to FY Quarter/Period
#'
#' @param date date formatted like 2021-10-01
#'
#' @return vector of FY period, eg FY22Q1
#' @export
#'
#' @family period
#'
#' @examples
#' \dontrun{
#' dates <- c("2021-10-01", "2021-11-15")
#' convert_date_to_qtr(dates) }
#'
convert_date_to_qtr <- function(date){
  pd <- lubridate::quarter(date,
                           with_year = TRUE,
                           fiscal_start = 10)

  pd <- stringr::str_replace(pd, "20", "FY")

  pd <- stringr::str_replace(pd, "\\.", "Q")

  return(pd)
}


#' Convert FY Quarter/Period to Date
#'
#' @description
#' Convert a period (from reshape_msd()) in the format of FY22Q1 or FY22 (for
#' targets/cumulative).
#'
#' @param period period formated like FY22Q1 or FY22
#' @param type start or end date of quarter/period, default = "start"
#'
#' @return date vector
#' @export
#'
#' @family period
#'
#' @examples
#' \dontrun{
#' df <- read_msd(path)
#' df <- df %>%
#'   filter(df,
#'          operatingunit == "Jupiter",
#'          indicator == "TX_NEW",
#'          standarddisaggregate == "Total Numerator") %>%
#'   group_by(fiscal_year, primepartner) %>%
#'   summarize(across(start_with("qtr"), sum, na.rm = TRUE)) %>%
#'   ungroup()
#' df <- df %>%
#'   reshape_msd() %>%
#'   mutate(date = convert_qtr_to_date(period), .after = period) }
#'
convert_qtr_to_date <- function(period, type = "start"){

  if(stringr::str_detect(period, "(FY[:digit:]{2}Q[:digit:]{1}|FY[:digit:]{2})", negate = TRUE))
    stop("Expecting a period to be formatted like FY22Q1 or FY22")

  if(stringr::str_detect(period, "Q", negate = TRUE)){
    q <- ifelse(type == "start", 1, 4)
    period <- glue::glue("{period}Q{q}")
  }

  period <- stringr::str_remove(period, "FY")

  cy_date <- lubridate::yq(period)

  if(type == "start"){
    date <- cy_date - months(3)
  } else {
    date <- cy_date - 1
  }

  return(date)

}


#' Convert DATIM CY Quarter/Period to FY Quarter
#'
#' Convert a period a DATIM API in the format of FY22Q1 or FY22 (for
#' targets/cumulative). This function is built into `extract_datim`.
#'
#' @param df dataframe from DATIM API, \code{grabr::extract_datim()}
#' @param pd_col name of the period column, default = "Period"
#'
#' @return Convert periods from long CY dates to PEPFAR standard FY
#' @export
#' @seealso [set_datim()] to store DATIM authentication;
#' [load_secrets()] to store DATIM authentication
#'
#' @family period
#'
#' @examples
#' \dontrun{
#' df <- tibble::tibble(Periods = c("October - December 2023",
#'                                  "January - March 2024",
#'                                  "October 2023 to September 2024"))
#' df <- convert_datim_pd_to_qtr(df) }

convert_datim_pd_to_qtr <- function(df, pd_col = "Period"){

  if(!"Period" %in% names(df)){
    usethis::ui_warn("DATIM period not converted. Cannot find `{usethis::ui_field(pd_col)}` in the dataframe.")
    return(df)
  }

  suppressWarnings(
    df <- df %>%
      dplyr::mutate(Period = dplyr::case_when(
        stringr::str_detect(Period, "^\\w+ (-|to) \\w+ \\d{4}")
        ~ Period %>%
          stringr::str_replace("(to|-) \\w+", "1,") %>%
          lubridate::mdy() %>%
          lubridate::quarter(with_year = TRUE, fiscal_start = 10) %>%
          stringr::str_replace("20", "FY") %>%
          stringr::str_replace("\\.", "Q"),
        stringr::str_detect(Period, "^Oct.* \\d{4} (-|to) Sep.* \\d{4}$")
        ~ Period %>%
          stringr::str_sub(-2)%>%
          paste0("FY", .),
        TRUE ~ Period))
  )

  return(df)

}


#' Convert Fiscal Year and Quarter into Period
#'
#' Using `gophr::reshape_msd()` often creates the a perfable long dataset when
#' working with the MSD, but may restrict the user to certain default during the
#' process. Creating a clean period  (eg FY22Q1) requires a number of lines of
#' code to get right, so this function provides stopgap when you are working
#' with a long dataset that has a fiscal year and quarter column and desire a
#' period variable.
#'
#' @param df MSD data frame reshaped long, eg `pivot_longer`
#' @param fy_ind indicator name in df for the fiscal year, default = "fiscal_year"
#' @param qtr_ind indicator name in the df for quarters, default = "qtrs"
#'
#' @return united period column combining and cleaning fiscal year and quarter
#' @export
#'
#' @family period
#'
#' @examplesIf FALSE
#'
#' df_summary <- df_msd %>%
#'        filter(indicator == "TX_CURR",
#'               standardizeddisaggregate == "Total Numerator",
#'               operatingunit == "Jupiter") %>%
#'        group_by(mech_code, fiscal_year) %>%
#'        summarise(across(starts_with("qtr"), sum, na.rm = TRUE),
#'                  .groups = "drop")
#'
#' df_summary <- df_summary %>%
#'        pivot_longer(-c(mech_code, fiscal_year), names_to = "qtrs")
#'
#' df_summary <- convert_fy_qtr_to_pd(df_summary)

convert_fy_qtr_to_pd <- function(df, fy_ind = "fiscal_year", qtr_ind = "qtr"){

  if(!fy_ind %in% names(df))
    usethis::ui_stop("Cannot find '{fy_ind}' in data frame provided.")

  if(!qtr_ind %in% names(df))
    usethis::ui_stop("Cannot find '{qtr_ind}' in data frame provided.")

  #clean up period
  df <- df %>%
    tidyr::unite(period, c(!!fy_ind, !!qtr_ind), sep = "") %>%
    dplyr::mutate(period = period %>%
                    stringr::str_remove("^20(?=[:digit:{2}])") %>%
                    stringr::str_remove("(targets|cumulative|tr)") %>%
                      toupper %>% paste0("FY", .))

  return(df)

}
USAID-OHA-SI/glamr documentation built on July 6, 2024, 6:39 a.m.