代码之家  ›  专栏  ›  技术社区  ›  PatrickT

R:GG带持续时间的绘图

  •  2
  • PatrickT  · 技术社区  · 6 年前

    问:你的处理建议 持续时间 具有 ggplot2 (作者:哈德利·威克姆)。具体地说:用自定义中断和合适的标签复制下面的图。对最少使用自定义函数和/或重构数据的偏好。欢迎对我未引用的文件包提出建议。

    数据以秒为单位存储(参见 df 下面)。我想显示人眼可读的中断和标签,例如,天而不是几千秒,其中中断发生在0,1,2。。。而不是尴尬的分数。

    努力证明:下面的第一个例子将持续时间作为整数处理,并通过适当的逐例除以60/24/365的倍数等来实现目标。第二个例子使用基数 R difftime strptime 函数与减法 1 . 我错过什么了吗?第三个示例使用 duration 来自 lubridate 包裹。而使用 day() seconds_to_period() 功能,我在设置自定义中断方面做得不是很好。第四个示例使用 hms 班级。我设法指定了中断,但没有标签。对于如何为下面的每个示例编写较短的代码行,也欢迎提出任何建议。

    # Data
    df = data.frame(x = 1:6, 
        num = c(374400, 343500, 174000, 193500, 197700, 270300))
    
    # base/difftime
    df$difftime <- as.difftime(df$num, units = "secs")
    
    # lubridate/duration
    library("lubridate")  # devtools::install_github("tidyverse/lubridate") # the dev version fixes a bug
    df$duration <- duration(df$num, units = "seconds")
    
    # hms/hms
    library("hms")
    df$hms <- as.hms(df$num) 
    
    library("ggplot2")
    library("scales")
    
    # 1: data is base/numeric
    # Pro: no package dependence
    # Con: Hard work 
    breaks = seq(0, 100*60*60, 20*60*60)
    labels = function(x) round(x/60/60/24, 0)
    ggplot(data = df, aes(x = x, y = num)) +
        geom_bar(stat = "identity", fill = "lightblue") +
        scale_y_continuous(name = "Duration (Days)", 
                           breaks = breaks,
                           labels = labels) +
        labs(title = "Data stored as numeric (seconds)", 
             subtitle = "breaks = seq(0, 100*60*60, 20*60*60)\nlabels = function(x) round(x/60/60/24, 0)",
             x = NULL) 
    ggsave("base-num.png")
    

    enter image description here

    # 2: data is base/difftime
    # Pro: simple once you get over the ``strftime(x, "%d")`` syntax.
    # Unresolved: Why do I need to subtract a day?
    labels = function(x) as.integer(strftime(x, "%d"))-1
    ggplot(data = df, aes(x = x, y = difftime)) +
        geom_bar(stat = "identity", fill = "lightblue") +
        scale_y_time(name = "Duration (Days)", 
            labels = labels) +
        labs(title = "Data stored as difftime (seconds)", 
             subtitle = "default breaks\nlabels = function(x) as.integer(strftime(x, '%d'))-1",
             x = NULL) 
    ggsave("base-difftime.png")
    

    enter image description here

    # 3: data is lubridate/duration
    # Pro: intuitive combination of day() and seconds_to_period() functions
    # Unresolved: a better way to make own breaks?
    breaks = as.duration(seq(0, 5, 1)*60*60*24)
    labels = function(x) day(seconds_to_period(x))
    ggplot(data = df, aes(x = x, y = duration)) +
        geom_bar(stat = "identity", fill = "lightblue") +
        scale_y_continuous(name = "Duration (Days)", 
            breaks = breaks,
            labels = labels) +
        labs(title = "Data stored as duration (seconds)", 
             subtitle = "breaks = as.duration(seq(0, 5, 1)*60*60*24)\nlabels = function(x)lubridate::day(lubridate::seconds_to_period(x))",
             x = NULL) 
    ggsave("lubridate-duration.png")
    

    enter image description here

    # 4: data is hms/hms
    # Pro: Immediately generates plot with acceptable labels
    # Unresolved: how to make own labels:  Failed attempts:
    labels = 0:(length(breaks)-1)
    labels = function(x)lubridate::day(x)
    
    breaks = seq(0, 5, 1)*60*60*24
    ggplot(data = df, aes(x = x, y = hms)) +
        geom_bar(stat = "identity", fill = "lightblue") +
        scale_y_continuous(name = "Duration (Seconds)",
            breaks = breaks) +
        labs(title = "Data stored as hms (seconds)", 
             subtitle = "breaks = seq(0, 5, 1)*60*60*24\ndefault labels",
             x = NULL) 
    ggsave("hms-hms.png")
    

    enter image description here

    按照Axeman在评论部分的建议,这是如何组合的 ggplot hms公司 物体。在我看来,这是4种方法中最方便的一种,尽管必须承认这是必须减去的 1 这是出乎意料的。阿克斯曼,你想把这个作为答案吗?

    breaks = hms::hms(days = 0:4)
    labels = function(x) lubridate::day(x)-1
    

    enter image description here

    1 回复  |  直到 6 年前
        1
  •  2
  •   Uwe    6 年前

    我觉得提议的解决方案太复杂了。

    aes() :

    df = data.frame(x = 1:6, 
                    num = c(374400, 343500, 174000, 193500, 197700, 270300))
    library("ggplot2")
    ggplot(data = df, aes(x = x, y = num / (24*60*60))) +
      geom_col(fill = "lightblue") +
      labs(title = "Data stored as numeric (seconds)",
           y = "Duration (Days)",
           x = NULL) 
    

    enter image description here

    geom_col() 是对 geom_bar(stat = "identity") .