R/plotTime.R

#' Plot workout counts over time
#'
#' This function plots workouts for different timespans. You can set the timespan as four different options; `Year`, `Month`, `Week` and `WeekdayName`. In weekdayview, days will start on Monday.
#'
#' @param df A dataframe
#' @param timespan one of `Year`, `Month`, `Week` and `WeekdayName`.
#'
#' @return ggplot object
#'
#' @export
#'
#' @importFrom magrittr '%>%'
#' @importFrom rlang syms
#' @importFrom ggplot2 ggplot aes geom_col geom_text theme position_stack element_text labs element_line scale_x_date
#' @importFrom dplyr select mutate group_by n
#' @importFrom lubridate wday
#'
#' @examples
#' df <- simData(25, 1)
#' plotTime(df)
plotTime <- function(df,
                     timespan = "Week") {
  group_vars <- rlang::syms(c(timespan, "workoutName"))
  gg <- df %>%
    # Select only date and workoutName
    dplyr::select(date, workoutName) %>%
    # Group by date, and count the quantities of Workout names per date
    dplyr::group_by(date) %>%
    dplyr::mutate(Quantity = n()) %>%
    # Keep only the first record, as we just need quantity and the name of the workout
    dplyr::slice(1) %>%
    # Ungroup and continue
    dplyr::ungroup() %>%
    dplyr::mutate(Year = as.Date(cut(date, breaks = "year"))) %>%
    dplyr::mutate(Month = as.Date(cut(date, breaks = "month"))) %>%
    dplyr::mutate(Week = as.Date(cut(
      date,
      breaks = "week", start.on.monday = TRUE
    ))) %>%
    dplyr::mutate(DayWeekName = lubridate::wday(
      date,
      label = T,
      abbr = F,
      week_start = getOption("lubridate.week.start", 1)
    )) %>%
    dplyr::group_by(!!!group_vars) %>%
    dplyr::summarise(Count = dplyr::n()) %>%
    ggplot2::ggplot(., aes(
      y = Count,
      fill = workoutName,
      label = ..y..,
      group = workoutName
    )) +
    scale_fill_HS() +
    ggplot2::theme(
      axis.text.x = ggplot2::element_text(
        angle = 90,
        hjust = 0.95,
        vjust = 0.2
      ),
      axis.line = ggplot2::element_line(colour = "black"),
      panel.grid.minor = ggplot2::element_blank(),
      legend.position = "top"
    ) +
    # ggplot2::guides(fill = ggplot2::guide_legend(nrow = 1)) +
    ggplot2::labs(
      title = paste("Workouts per", timespan),
      x = NULL,
      y = "Number of workouts"
    )

  # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # Year
  if (timespan == "Year") {
    gg <-
      gg + ggplot2::stat_summary(aes(x = Year),
        fun.y = sum,
        geom = "bar",
        position = "stack"
      ) +
      ggplot2::geom_text(aes(x = Year, label = Count),
        position = position_stack(vjust = 0.5)
      ) +
      ggplot2::scale_x_date(date_labels = "%Y", breaks = "1 year")

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Month
  } else if (timespan == "Month") {
    gg <-
      gg + ggplot2::stat_summary(aes(x = Month),
        fun.y = sum,
        geom = "bar",
        position = "stack"
      ) +
      ggplot2::geom_text(aes(x = Month, label = Count),
        position = position_stack(vjust = 0.5)
      ) +
      ggplot2::scale_x_date(date_labels = "%Y %b", breaks = "1 month")

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # Week
  } else if (timespan == "Week") {
    gg <-
      gg + ggplot2::stat_summary(aes(x = Week),
        fun.y = sum,
        geom = "bar",
        position = "stack"
      ) +
      ggplot2::geom_text(aes(x = Week, label = Count),
        position = position_stack(vjust = 0.5)
      ) +
      ggplot2::scale_x_date(date_labels = "%Y %V", breaks = "4 weeks")

    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    # DayWeekName
  } else if (timespan == "DayWeekName") {
    gg <-
      gg + ggplot2::stat_summary(aes(x = DayWeekName),
        fun.y = sum,
        geom = "col",
        position = "stack"
      ) +
      ggplot2::geom_text(aes(x = DayWeekName, label = Count),
        position = position_stack(vjust = 0.5)
      )
  } else {
    futile.logger::flog.error("Timespan is not one of `Year`, `Month`, `Week` or `DayWeekName.")
  }
  return(gg)
}

#' Plot all timespans
#'
#' This function returns 4 plots, showing your workout counts over time in years, months, weeks and per weekdays.
#'
#' @param df A dataframe
#'
#' @return ggplot object
#'
#' @export
#'
#' @importFrom ggplot2 theme
#' @importFrom cowplot get_legend plot_grid
#'
#' @examples
#' df <- simData(25, 1)
#' plotTimespans(df)
plotTimespans <- function(df) {
  legend <- cowplot::get_legend(plotTime(df, timespan = "Year"))
  cowplot::plot_grid(
    legend,
    cowplot::plot_grid(
      plotTime(df, timespan = "Year") +
        theme(legend.position = "none"),
      plotTime(df, timespan = "Month") +
        theme(legend.position = "none"),
      plotTime(df, timespan = "Week") +
        theme(legend.position = "none"),
      plotTime(df, timespan = "DayWeekName") +
        theme(legend.position = "none"),
      align = "vh"
    ),
    nrow = 2,
    rel_heights = c(1, 10)
  )
}
MarijnJABoer/HeavySetR documentation built on May 22, 2019, 5:31 p.m.