4

Since scale_x_date is for "date" and scale_x_datetime is for "POSIXct", is it possible to have a wrapper to automatically decide which of the two to choose, since both even have the same function arguments.

Similar to this but with its arguments (the data) taken from the aestetics of my geoms:

scale_x_date_flex <- function(date_labels = "%B",date_breaks = "months")){

    if(any(class(DF$Date) =="POSIXct")){
        return(scale_x_datetime(date_labels = date_labels ,date_breaks = date_breaks))
    }else{
        return(scale_x_date(date_labels = date_labels ,date_breaks = date_breaks))
    }
}
Squeezie
  • 361
  • 2
  • 14

1 Answers1

2

It's possible. But since you can't access the data of a plot when using the + (as far as I know) we have to use the magrittr pipe instead to be able to test the class of the x aesthetic.

Function

scale_x_date_flex <- function(plot,
                              date_labels = "%B", 
                              date_breaks = "months") {

  if ("POSIXct" %in% class(plot$data[[quo_name(plot$mapping$x)]])) {
    message("scale_x_datetime")
    return(plot + scale_x_datetime(date_labels = date_labels, date_breaks = date_breaks))
  } else {
    message("scale_x_date")
    return(plot + scale_x_date(date_labels = date_labels, date_breaks = date_breaks))
  }

}

Example

library(ggplot2)
library(magrittr)

last_month_date <- Sys.Date() - 0:29
last_day_time <- Sys.time() - 0:29 * (60 * 60)

df <- data.frame(
  date = last_month_date,
  time = last_day_time,
  price = runif(30)
)


base_d <- ggplot(df, aes(date, price)) +
  geom_line()

base_t <- ggplot(df, aes(time, price)) +
  geom_line()



base_d %>% scale_x_date_flex(date_labels = "%d", date_breaks = "5 days")
#> scale_x_date

base_t %>% scale_x_date_flex(date_labels = "%d %H:%M", date_breaks = "5 hour")
#> scale_x_datetime

But you can still use it in the middle of a ggplot command chain. So this will work:

base_d %>% scale_x_date_flex(date_labels = "%d", date_breaks = "5 days") + theme_bw()

Created on 2019-09-13 by the reprex package (v0.3.0)

JBGruber
  • 11,727
  • 1
  • 23
  • 45