R - 折线图中项目的计数:将DateTime与项目数量

时间:2016-11-28 15:00:18

标签: r ggplot2

我有一个具有以下结构的数据框:

df <- structure(list(Name = structure(1:9, .Label = c("task 1", "task 2", 
"task 3", "task 4", "task 5", "task 6", "task 7", "task 8", "task 9"
), class = "factor"), Start = structure(c(1479799800, 1479800100, 
1479800400, 1479800700, 1479801000, 1479801300, 1479801600, 1479801900, 
1479802200), class = c("POSIXct", "POSIXt"), tzone = ""), End = structure(c(1479801072, 
1479800892, 1479801492, 1479802092, 1479802692, 1479803292, 1479803892, 
1479804492, 1479805092), class = c("POSIXct", "POSIXt"), tzone = "")), .Names = c("Name", 
"Start", "End"), row.names = c(NA, -9L), class = "data.frame")

现在我想计算“名称”列中的项目。它们都有一个开始和结束日期时间,形成POSIXct。

this solution here on SO的帮助下,我能够使用以下代码(或者至少我认为我是)这样做了:

library(data.table)
setDT(df)
dates = seq(min(df$Start), max(df$End), by = "min")
lookup = data.table(Start = dates, End = dates, key = c("Start", "End"))
ans = foverlaps(df, lookup, type = "any", which = TRUE)
library(ggplot2)
ggplot(ans[, .N, by = yid], aes(x = yid, y = N)) + geom_line()

现在出现问题:

如何将我的DateTime-scale与x轴上的整数值相匹配?或者是否有更快更好的解决方案来解决我的问题?

我尝试在x = as.POSIXct(yid, format = "%Y-%m-%dT%H:%M:%S", origin = min(df$Start))的{​​{1}}内使用aes。但那没用。

编辑:

当使用解决方案解决这个问题时,我面对另一个问题。没有计数的项目与图表中最新可计数项目的计数一起显示。这就是为什么我们必须使用所有日期时间的完整序列再次合并(leftjoin)表和计数(ggplot()),并为每个ants添加0。因此,我们为每个必要的数据点获得显式值。 像这样:

NA

1 个答案:

答案 0 :(得分:1)

tidyverse框架中,这是一个稍微不同的任务 -

  1. 生成您拥有的dates变量。
  2. 构建包含所有日期和所有时间的数据框(笛卡儿加入)
  3. 过滤掉不在每个任务的时间间隔内的行
  4. 添加剩余的每分钟的任务
  5. 剧情。
  6. 看起来像这样 -

    library(tidyverse)
    library(lubridate)
    
    dates = seq(min(df$Start), max(df$End), by = "min")
    df %>% 
      mutate(key = 1) %>% 
      left_join(data_frame(key = 1, times = dates)) %>% 
      mutate(include = times %within% interval(Start, End)) %>% 
      filter(include) %>% 
      group_by(times) %>% 
      summarise(count = n()) %>% 
      ggplot(aes(times, count)) +
      geom_line()
    #> Joining, by = "key"
    

    enter image description here

    如果您需要更快,使用原始data.table代码几乎肯定会更快。

    考虑一下。

    library(data.table)
    setDT(df)
    dates = seq(min(df$Start), max(df$End), by = "min")
    lookup = data.table(Start = dates, End = dates, key = c("Start", "End"))
    ans = foverlaps(df, lookup, type = "any", which = TRUE)
    
    ans[, .N, by = yid] %>%
      mutate(time = min(df$Start) + minutes(yid)) %>%
      ggplot(aes(time, N)) +
      geom_line()
    

    现在我们使用data.table来计算重叠,然后将起始分钟的时间编入索引。一旦我们添加了一个带有时间的新列,我们就可以绘制。

    enter image description here