Last active
November 13, 2019 15:02
-
-
Save moodymudskipper/455d9001bb22645d986535e6aad3395c to your computer and use it in GitHub Desktop.
scale_y_duration displays time in sec, min, hour or day depending on max value
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(ggplot2) | |
scale_y_duration <- function(..., units = c("s","min","h","day")){ | |
units <- match.arg(units, c("ms","seconds","minutes","hours","days", "weeks", "months", "years"), | |
several.ok = TRUE) | |
# to get them in the right order | |
units <- intersect(c("ms","seconds","minutes","hours","days", "weeks", "months", "years"), units) | |
ms <- 1/1000 | |
min <- 60 | |
h <- 60 *min | |
day <- 24 *h | |
week <- 7 * day | |
year <- 365.25 * day | |
month <- year / 12 | |
labels <- function(x){ | |
max_x <- max(x, na.rm=TRUE) | |
if("years" == units[[1]] || max_x > 3 * year && "years" %in% units){ | |
# > 3 year, use years | |
x <- x /year | |
x <- paste(round(x,2),"years") | |
} else if("months" == units[[1]] || max_x > 3 * month && "months" %in% units){ | |
# > 3 months, use months | |
x <- x /month | |
x <- paste(round(x,2),"months") | |
} else if("weeks" == units[[1]] || max_x > 3 * week && "weeks" %in% units){ | |
# > 3 weeks, use weeks | |
x <- x /week | |
x <- paste(round(x,2),"weeks") | |
} else if("days" == units[[1]] || max_x > 3 * day && "days" %in% units){ | |
# > 3 days, use days | |
x <- x /day | |
x <- paste(round(x,2),"days") | |
} else if("hours" == units[[1]] || max_x > 3 * h && "hours" %in% units){ | |
# > 3 h, use h | |
x <- x /h | |
x <- paste(round(x,2),"h") | |
} else if("minutes" == units[[1]] || max_x > 3 * min && "minutes" %in% units){ | |
# > 3 min, use min | |
x <- x /min | |
x <- paste(round(x,2),"min") | |
} else if("seconds" == units[[1]] || max_x > 3 * min && "seconds" %in% units){ | |
# > 3 min, use min | |
x <- paste(round(x,2),"s") | |
} else if("ms" %in% units){ | |
# > 3 min, use min | |
x <- x /min | |
x <- paste(round(x,2),"min") | |
} else { | |
stop("no unit was found for provided value of x") | |
} | |
} | |
breaks <- function(x){ | |
max_x <- max(x, na.rm=TRUE) | |
if("years" == units[[1]] || max_x > 3 * year && "years" %in% units){ | |
# > 3 year, use years | |
scales:::extended_breaks()(x/year) * year | |
} else if("months" == units[[1]] || max_x > 3 * month && "months" %in% units){ | |
# > 3 months, use months | |
scales:::extended_breaks()(x/month) * month | |
} else if("weeks" == units[[1]] || max_x > 3 * week && "weeks" %in% units){ | |
# > 3 weeks, use weeks | |
scales:::extended_breaks()(x/week) * week | |
} else if("days" == units[[1]] || max_x > 3 * day && "days" %in% units){ | |
# > 3 days, use days | |
scales:::extended_breaks()(x/day) * day | |
} else if("hours" == units[[1]] || max_x > 3 * h && "hours" %in% units){ | |
# > 3 h, use h | |
scales:::extended_breaks()(x/h) * h | |
} else if("minutes" == units[[1]] || max_x > 3 * min && "minutes" %in% units){ | |
# > 3 min, use min | |
scales:::extended_breaks()(x/min) * min | |
} else if("seconds" == units[[1]] || max_x > 3 && "seconds" %in% units){ | |
# > 3 s, use s | |
scales:::extended_breaks()(x) | |
} else if("ms" %in% units){ | |
scales:::extended_breaks()(x/ms) * ms | |
} else { | |
stop("no unit was found for provided value of x") | |
} | |
} | |
scale_y_continuous(..., labels = labels, breaks = breaks) | |
} | |
df <- data.frame(x=1:3, time = c(1,2,5)) | |
ggplot(df, aes(x, time)) + geom_point() + scale_y_duration() + ggtitle("seconds") | |
df <- data.frame(x=1:3, time = c(1,2,5) * 1000) | |
ggplot(df, aes(x, time)) + geom_point() + scale_y_duration() + ggtitle("min") | |
df <- data.frame(x=1:3, time = c(1,2,5) * 10000) | |
ggplot(df, aes(x, time)) + geom_point() + scale_y_duration() + ggtitle("hours") | |
df <- data.frame(x=1:3, time = c(1,2,5) * 100000) | |
ggplot(df, aes(x, time)) + geom_point() + scale_y_duration() + ggtitle("days") | |
df <- data.frame(x=1:3, time = c(1,2,5) * 1000) | |
ggplot(df, aes(x, time)) + geom_point() + scale_y_duration(units = "h") + ggtitle("force hours") | |
df <- data.frame(x=1:3, time = c(1,2,5) * 1000000) | |
ggplot(df, aes(x, time)) + geom_point() + scale_y_duration() + ggtitle("not weeks, by default") | |
ggplot(df, aes(x, time)) + geom_point() + scale_y_duration(units = c("day","week","month")) + ggtitle("weeks") | |
df <- data.frame(x=1:3, time = c(1,2,5) * 10000000) | |
ggplot(df, aes(x, time)) + geom_point() + scale_y_duration(units = c("day","week","month")) + ggtitle("months") | |
ggplot(df, aes(x, time)) + geom_point() + scale_y_duration(units = c("year")) + ggtitle("force year") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
more flexible now, we can choose a set of units.
Even more flexible would be to set the thresholds through the unit parameter, now it's always 3, meaning, if "hours" is part of units (as is by default) and max(ime) is more than 3 hours, we'll use hours.
A flexible argument would allow something lile
units = list("s","min", h = 10)