I'm plotting some data with a time-duration in seconds on the x-axis using ggplot2. The data is the result of either a simulation or is computed on a monitored trace.
I'm using scale_x_time
to get proper labels. However, as the data spans a significant time frame, I would like to include the number of days and weeks in the labels. Minimal example:
library(ggplot2)
n = 100
d <- data.frame(
t = seq(from=0, to=100*24*60*60, length.out=n),
v = runif(n, min=10, max=20)
)
ggplot(d) + geom_point(aes(x=t, y=v)) + scale_x_time()
Is there a way to achieve just that using the hms
package and base R?
Optimally, I would like to just give a format string, e.g. "%Ww %dd %H:%M:%S"
.
The hms
package contains plenty of helper functions to extract information from hms
objects and format the objects. These functions are not exported. I had hoped to extract the number of days, format the number of days and weeks myself and then construct a new hms
object and use the shipped format
function. But I don't want to re-implement all the hms
package's logic in my own code.
- https://github.com/tidyverse/hms/blob/160630c7601b3494ed9f2690b8cccd443cf10e64/R/hms.R#L197-L206
- https://github.com/tidyverse/hms/blob/60e11f484d07d8cb1bbde000d8f062ca7074f0c0/R/arith.R
My workaround thus far has been to convert hms
objects to lubridate
period objects. lubridate
has plenty of functions to extract information from periods. But this seems way too complicated to me. Also, periods express "human" time spans which does not match the use-case.
library(lubridate)
format_dhms <- function(x) {
p <- as.period(x)
return(
format(p)
)
}
format_wdhms <- function(x) {
p <- as.period(x)
w <- floor(day(p) / 7)
return(
paste(
ifelse(w >= 1, paste(w, "w", sep=""), ""),
ifelse(w >= 1, format(p - weeks(w)), format(p))
)
)
}
ggplot(d) + geom_point(aes(x=t, y=v)) + scale_x_time(labels=format_wdhms)