【问题标题】:How to format difftime as hh:mm in ggplot2?如何在ggplot2中将difftime格式化为hh:mm?
【发布时间】:2018-12-16 17:15:51
【问题描述】:

我想用 ggplot2 显示 difftime 数据,我希望刻度格式为 hh:mm

library(ggplot2)  

a= as.difftime(c("0:01", "4:00"), "%H:%M", unit="mins")
b= as.difftime(c('0:01', "2:47"), "%H:%M", unit="mins")

ggplot(data=NULL, aes(x=b, y=a)) + geom_point(shape=1) +    
                  scale_x_time(labels = date_format("%H:%M"), 
                               breaks = "1 hour")

但我收到以下警告:

Don't know how to automatically pick scale for object of type difftime. Defaulting to continuous.
Warning message:
In structure(as.numeric(x), names = names(x)) : NAs introduced by coercion

这是一个图表:

更新: 我的例子太小了,我还需要能够显示负面差异,所以这将是更好的数据:

a= as.difftime(c(-60, -4*60),  unit="mins")
b= as.difftime(c(-60, 2*60+47), unit="mins")
ggplot(data=NULL, aes(x=b, y=a)) + geom_point(shape=1)

【问题讨论】:

标签: r ggplot2 difftime


【解决方案1】:

答案分为两部分。

绘制difftime 对象

根据help("scale_x_time")ggplot2 支持三个日期/时间类:scale_*_date 用于日期(Date 类),scale_*_datetime 用于日期时间(class POSIXct),scale_*_time 用于时间(类hms)。最后一个是我们这里需要的。

hms 类是 difftime 向量的自定义类。 as.hms() 有一个difftime 的方法。所以。 difftime 对象可以通过ggplot2 强制转换为hms 类来绘制:

a <- as.difftime(c(-60, -4 * 60),  unit = "mins")
b <- as.difftime(c(-60, 2 * 60 + 47), unit = "mins")
library(ggplot2)
ggplot(data = NULL, aes(x = hms::as.hms(b), y = hms::as.hms(a))) + 
  geom_point(shape = 1)

请注意,也会显示负时差。

格式化刻度标签

OP 已要求应以hh:mm 格式标记刻度线。显然,默认格式是hh:mm:ss。这可以通过指定一个函数来修改,该函数将中断作为输入并将标签作为输出返回给scale_x_time()scale_y_time() 函数的labels 参数:

format_hm <- function(sec) stringr::str_sub(format(sec), end = -4L)
ggplot(data = NULL, aes(x = hms::as.hms(b), y = hms::as.hms(a))) + 
  geom_point(shape = 1) +
  scale_x_time(name = "b", labels = format_hm) +
  scale_y_time(name = "a", labels = format_hm)

format_hm() 函数从默认格式截断:ss 部分。此外,轴标记得很好。

【讨论】:

    【解决方案2】:

    根据您的限制,您可能会考虑将 difftimes 转换为不同的日期时间,ggplot 可以很好地处理:

    library(lubridate)
    a_date_times <- floor_date(Sys.time(), "1 day") + a
    b_date_times <- floor_date(Sys.time(), "1 day") + b
    ggplot(data=NULL, aes(x=a_date_times, y=b_date_times)) + 
      geom_point(shape=1)
    

    【讨论】:

    • 谢谢,遗憾的是我的约束需要负时间,例如-1:00 虽然这个解决方案会给我23:00
    【解决方案3】:

    到目前为止我最好的方法是:

    library(ggplot2)  
    library(lubridate)
    
    a= as.difftime(c(-60, -4*60),  unit="mins")
    b= as.difftime(c(-60, 2*60+47), unit="mins")
    
    xbreaks = seq(ceiling(min(b)/60), floor(max(b)/60)) * 60
    ybreaks = seq(ceiling(min(a)/60), floor(max(a)/60)) * 60
    
    
    ggplot(data=NULL, aes(x=b, y=a)) + geom_point(shape=1) + 
                      scale_x_continuous(labels = f, breaks = xbreaks) +
                      scale_y_continuous(labels = f, breaks = ybreaks)
    
    
    
    f <- function(x){
      t = seconds_to_period(abs(x)*60)
      r = sprintf("% 2i:%02i", sign(x)*hour(t), minute(t))
      return(r)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-16
      • 1970-01-01
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      相关资源
      最近更新 更多