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)