【问题标题】:aggregate by date sequences and id variables in R在 R 中按日期序列和 id 变量聚合
【发布时间】:2021-11-18 20:27:57
【问题描述】:

我正在努力将每小时的温度汇总为 3 小时,同时保持车站 ID。这里是 df:

ID Date temp
1155 2012-01-01 00:00:00 -0.8
1155 2012-01-01 01:00:00 0.1
1155 2012-01-01 02:00:00 0.5

我正在努力做到:

ID Date temp
1155 2012-01-01 -0.2

我已经详细说明了这段代码:

library(dplyr)
  Temp_3h<- df %>%
    group_by(ID)%>%
    aggregate(.,by=list(Date=cut(as.POSIXct(df$Date), "3 hour")),mean)

但除了“temp”变量之外,它还倾向于聚合 ID(分类),因此它们成为 NA。而且我不知道如何将 ID 集成到“by=”参数中。任何帮助将不胜感激

【问题讨论】:

    标签: r dataframe date aggregate


    【解决方案1】:

    使用data.table

    library(data.table)
    library(lubridate)
    setDT(df1)[, .(temp = mean(temp, na.rm = TRUE)),
        .(ID, Date = floor_date(ymd_hms(Date), '3 hours'))]
    

    【讨论】:

      【解决方案2】:

      我其实很喜欢cut 方法。

      d |>
        transform(date_s=cut(as.POSIXct(d$Date), breaks="3 hours")) |>
        with(aggregate(list(mn_temp=temp), list(date=date_s, ID=ID), FUN=mean))
      #                  date   ID     mn_temp
      # 1 2012-01-01 00:00:00 1155 -0.06666667
      # 2 2012-01-01 03:00:00 1155  0.56666667
      # 3 2012-01-01 06:00:00 1155  0.93333333
      # 4 2012-01-01 09:00:00 1155  3.70000000
      

      如果我们想要显示时间间隔的结束而不是开始时间,我们可以这样做

      d |>
        transform(date_s=cut(
          as.POSIXct(d$Date), breaks="3 hours", 
          labels=(as.POSIXct(Date) + 10800)[(seq(Date) - 1) %% 3 == 0])) |>
        with(aggregate(list(mn_temp_lst3=temp), list(date=date_s, ID=ID), FUN=mean))
      #                  date   ID mn_temp_lst3
      # 1 2012-01-01 03:00:00 1155  -0.06666667
      # 2 2012-01-01 06:00:00 1155   0.56666667
      # 3 2012-01-01 09:00:00 1155   0.93333333
      # 4 2012-01-01 12:00:00 1155   3.70000000
      

      数据

      d <- structure(list(ID = c(1155L, 1155L, 1155L, 1155L, 1155L, 1155L, 
      1155L, 1155L, 1155L, 1155L), Date = c("2012-01-01 00:00:00", 
      "2012-01-01 01:00:00", "2012-01-01 02:00:00", "2012-01-01 03:00:00", 
      "2012-01-01 04:00:00", "2012-01-01 05:00:00", "2012-01-01 06:00:00", 
      "2012-01-01 07:00:00", "2012-01-01 08:00:00", "2012-01-01 09:00:00"
      ), temp = c(-0.8, 0.1, 0.5, 0.6, 0.6, 0.5, 0.7, 0.9, 1.2, 3.7
      )), row.names = c(NA, -10L), class = "data.frame")
      

      【讨论】:

      • 支持,但cut(as.POSIXct(d$Date), breaks="3 hours", etc) 似乎更直观,并且避免调用transform/factor。 pipe-to-with 的想法本身就值得一票。
      • 如果第一个transformdate = droplevels(.),你可以直接通过管道到with(aggregate(temp ~ date + ID, FUN = mean))
      • @RuiBarradas Thx,你说得对,我已经改变了它(不知何故 cut.Date 以前不起作用)。
      【解决方案3】:

      您可以确定日期并使用group_bysummarize 函数:

      library(lubridate)
      library(dplyr)
      library(plyr)
      summarise(group_by(df, ID, Date = floor_date(ymd_hms(Date), '3 hours')), first(Date), first(ID), sum(temp))
      

      输出:

        first(Date) first(ID) sum(temp)
      1  2012-01-01      1155      -0.2
      

      【讨论】:

        【解决方案4】:

        您可以使用 floor_date/ceiling_date 将每 3 小时一次的时间戳合并为一个,并为每个 IDtemp 值的平均值。

        library(dplyr)
        library(lubridate)
        
        Temp_3h <- df %>%
          group_by(ID, Date = floor_date(ymd_hms(Date), '3 hours')) %>%
          summarise(temp = mean(temp, na.rm = TRUE), .groups = 'drop')
        
        Temp_3h
        

        【讨论】:

        • 嘿@Ronak Shah,它有效!非常感谢
        猜你喜欢
        • 2012-03-25
        • 1970-01-01
        • 2015-05-05
        • 2021-06-16
        • 1970-01-01
        • 2017-07-27
        • 1970-01-01
        • 2018-08-11
        • 1970-01-01
        相关资源
        最近更新 更多