R/time_2transform.R

Defines functions pad2 format_duration split_interval time_2transform

Documented in format_duration pad2 split_interval time_2transform

#' Pad 2
#'
#' @param x string to pad

pad2 <- function(x) stringr::str_pad(x, 2, "left", "0")


#' Format durations
#'
#' @param duration_in vector of periods to transform
#' @param time_ind indicator - truncate times longer than 24 hours?
#' @export

format_duration <- function(duration_in, time_ind = FALSE){
  # Return error if class isn't duration or numeric
  if (class(duration_in) == "Duration")
    duration_num <- as.numeric(duration_in)
  else if (class(duration_in) == "numeric")
    duration_num <- duration_in
  else
    stop("Argument class must be duration or numeric")
  # Convert to numeric - seconds
  duration_num <- as.numeric(duration_in)
  # Extract hours - integer part of quotient with 3600 sec (1 hour)
  hr <- duration_num %/% 3600
  # Extract minutes - part left over from above, then integer quotient with
  # 60 sec (1 min)
  min <- (duration_num %% 3600) %/% 60
  # Output string
  # If time_ind, take off days and pad, otherwise, add colon.
  if (time_ind)
    stringr::str_c(pad2(hr %% 24), pad2(min))
  else
    stringr::str_c(hr, ":", pad2(min))
}


#' Split an interval at midnight
#'
#' @param start_in date to start
#' @param end_in date to end
#' @importFrom lubridate %--%

split_interval <- function(start_in, end_in){
  # Create the vector
  out_vec <- start_in
  # Set up the while loop to populate the vector
  midnight <- lubridate::floor_date(start_in - lubridate::minutes(), unit = "days") + lubridate::days()
  while (midnight < end_in) {
    out_vec <- c(out_vec, midnight)
    midnight <- midnight + lubridate::days()
  }
  # Add the end
  out_vec <- c(out_vec, end_in)
  # Convert back to an interval
  int_out <- lubridate::int_diff(out_vec)

  # The following is a workaround, as tibbles don't take intervals and data.frames munge them
  # Use base::rev to reverse order
  data.frame(start_dttm_comp = lubridate::int_start(int_out),
             end_dttm_comp   = lubridate::int_end(int_out))
}

#' Transform TimetrackIO Report
#'
#' @param df_in time tracking data to transform
#' @importFrom magrittr %>%
#' @importFrom rlang .data
#' @importFrom dplyr n
#' @export

time_2transform <- function(df_in){
  # Transform data
  df_text <- df_in %>%
    dplyr::mutate(
      # Get the total duration
      duration_total = lubridate::as.duration(.data$start_dttm %--% .data$end_dttm),
      # Split the interval on midnight
      interval_split = purrr::map2(.data$start_dttm, .data$end_dttm, split_interval)
    ) %>%
    tidyr::unnest(cols = c(.data$interval_split)) %>%
    dplyr::mutate(
      # Create duration objects for plot text
      duration_comp = lubridate::as.duration(.data$start_dttm_comp %--% .data$end_dttm_comp),
      # Date to plot as datetime
      date_to_plot_dttm = lubridate::floor_date(.data$start_dttm_comp, "days"),
      # Date to plot
      date_to_plot = lubridate::as_date(.data$date_to_plot_dttm),
      # Create period objects for plotting
      start_period_plot = lubridate::as.period(.data$date_to_plot_dttm %--% .data$start_dttm_comp),
      end_period_plot = lubridate::as.period(.data$date_to_plot_dttm %--% .data$end_dttm_comp),
      # Convert period objects to durations
      start_duration_plot = lubridate::as.duration(.data$start_period_plot),
      end_duration_plot = lubridate::as.duration(.data$end_period_plot),
      mid_duration_plot = (.data$start_duration_plot + .data$end_duration_plot)/2,
      # Create text to plot
      plot_text = dplyr::if_else(
        .data$duration_comp < lubridate::as.duration("8M"), "",
        stringr::str_c(
          .data$activity, ": ", format_duration(.data$duration_comp),
          # If the activity was less than 15 minutes...
          dplyr::if_else(
            .data$duration_comp < lubridate::as.duration("15M"), "",
            stringr::str_c(
              # If the event straddles midnight, print the total
              dplyr::if_else(
                .data$duration_total == .data$duration_comp, "",
                stringr::str_c("\n(Total: ", format_duration(.data$duration_total), ")")
              ),
              dplyr::if_else(.data$notes == "", "", stringr::str_c("\n", .data$notes))
            )
          )
        )
      )
    )

  # Select only the appropriate variables
  df_text %>%
    dplyr::select(.data$date_to_plot, .data$start_duration_plot, .data$mid_duration_plot,
                  .data$end_duration_plot, .data$activity, .data$plot_text)
}
andrewjpfeiffer/timetrackr documentation built on Feb. 21, 2020, 4:22 a.m.