【问题标题】:Aggregate Daily Data to Month/Year intervals将每日数据汇总到月/年间隔
【发布时间】:2011-08-28 12:00:26
【问题描述】:

我不需要经常在 R 中处理日期,但我想这相当容易。我有一列表示数据框中的日期。我只是想创建一个新的数据框,使用日期按月/年汇总第二列。最好的方法是什么?

我想要第二个数据框,以便将其提供给绘图。

您能提供的任何帮助将不胜感激!

编辑:供参考:

> str(temp)
'data.frame':   215746 obs. of  2 variables:
 $ date  : POSIXct, format: "2011-02-01" "2011-02-01" "2011-02-01" ...
 $ amount: num  1.67 83.55 24.4 21.99 98.88 ...

> head(temp)
        date amount
1 2011-02-01  1.670
2 2011-02-01 83.550
3 2011-02-01 24.400
4 2011-02-01 21.990
5 2011-02-03 98.882
6 2011-02-03 24.900

【问题讨论】:

  • @Bibert3 你能告诉我们你的日期是什么格式的吗? POSIX?角色?

标签: datetime r


【解决方案1】:

我会用 lubridateplyr 来做,将日期四舍五入到最近的月份,以便更容易绘制:

library(lubridate)
df <- data.frame(
  date = today() + days(1:300),
  x = runif(300)
)
df$my <- floor_date(df$date, "month")

library(plyr)
ddply(df, "my", summarise, x = mean(x))

【讨论】:

  • 或者使用 dplyr,最后一行是 summarise(df, x = mean(my))
  • 如果你想要一个包含这样几列的数据框:plyr::ddply(df, "my", numcolwise(mean))
【解决方案2】:

可能有一个更优雅的解决方案,但是用strftime()aggregate()ing 分成几个月和几年应该可以做到。然后重新组合日期进行绘图。

x <- as.POSIXct(c("2011-02-01", "2011-02-01", "2011-02-01"))
mo <- strftime(x, "%m")
yr <- strftime(x, "%Y")
amt <- runif(3)
dd <- data.frame(mo, yr, amt)

dd.agg <- aggregate(amt ~ mo + yr, dd, FUN = sum)
dd.agg$date <- as.POSIXct(paste(dd.agg$yr, dd.agg$mo, "01", sep = "-"))

【讨论】:

    【解决方案3】:

    游戏有点晚了,但另一种选择是使用data.table

    library(data.table)
    setDT(temp)[, .(mn_amt = mean(amount)), by = .(yr = year(date), mon = months(date))]
    
    # or if you want to apply the 'mean' function to several columns:
    # setDT(temp)[, lapply(.SD, mean), by=.(year(date), month(date))]
    

    这给出了:

         yr      mon mn_amt
    1: 2011 februari 42.610
    2: 2011    maart 23.195
    3: 2011    april 61.891
    

    如果您想要月份的名称而不是数字,您可以使用:

    setDT(temp)[, date := as.IDate(date)
                ][, .(mn_amt = mean(amount)), by = .(yr = year(date), mon = months(date))]
    

    这给出了:

         yr      mon mn_amt
    1: 2011 februari 42.610
    2: 2011    maart 23.195
    3: 2011    april 61.891
    

    如您所见,这将以您的系统语言(在我的情况下为荷兰语)给出月份名称。


    或者使用lubridatedplyr的组合:

    temp %>% 
      group_by(yr = year(date), mon = month(date)) %>% 
      summarise(mn_amt = mean(amount))
    

    使用过的数据:

    # example data (modified the OP's data a bit)
    temp <- structure(list(date = structure(1:6, .Label = c("2011-02-01", "2011-02-02", "2011-03-03", "2011-03-04", "2011-04-05", "2011-04-06"), class = "factor"), 
                           amount = c(1.67, 83.55, 24.4, 21.99, 98.882, 24.9)), 
                      .Names = c("date", "amount"), class = c("data.frame"), row.names = c(NA, -6L))
    

    【讨论】:

      【解决方案4】:

      你可以这样做:

      short.date = strftime(temp$date, "%Y/%m")
      aggr.stat = aggregate(temp$amount ~ short.date, FUN = sum)
      

      【讨论】:

      • short.date 部分非常实用。谢谢@Galina-Alperovich 的好建议!
      【解决方案5】:

      只需为此使用 xts 包。

      library(xts)
      ts <- xts(temp$amount, as.Date(temp$date, "%Y-%m-%d"))
      
      # convert daily data
      ts_m = apply.monthly(ts, FUN)
      ts_y = apply.yearly(ts, FUN)
      ts_q = apply.quarterly(ts, FUN)
      

      其中 FUN 是一个用于聚合数据的函数(例如 sum)

      【讨论】:

      • 为什么要单独回答?最好将此添加为您以前的答案imo的替代方法
      【解决方案6】:

      我有一个函数 monyr 用于此类事情:

      monyr <- function(x)
      {
          x <- as.POSIXlt(x)
          x$mday <- 1
          as.Date(x)
      }
      
      n <- as.Date(1:500, "1970-01-01")
      nn <- monyr(n)
      

      您可以将末尾的 as.Date 更改为 as.POSIXct 以匹配数据中的日期格式。然后按月汇总只是使用聚合/按/等的问题。

      【讨论】:

        【解决方案7】:

        这是一个dplyr 选项:

        library(dplyr)
        
        df %>% 
          mutate(date = as.Date(date)) %>% 
          mutate(ym = format(date, '%Y-%m')) %>% 
          group_by(ym) %>% 
          summarize(ym_mean = mean(x))
        

        【讨论】:

          【解决方案8】:

          另一种解决方案:

           rowsum(temp$amount, format(temp$date,"%Y-%m"))
          

          情节你可以使用barplot:

          barplot(t(rowsum(temp$amount, format(temp$date,"%Y-%m"))), las=2)
          

          【讨论】:

            【解决方案9】:

            此外,鉴于您的时间序列似乎是 xts 格式,您可以使用如下均值函数将您的每日时间序列聚合为每月时间序列:

            d2m <- function(x) {
              aggregate(x, format(as.Date(zoo::index(x)), "%Y-%m"), FUN=mean)
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-02-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-06-27
              • 2021-02-23
              • 1970-01-01
              相关资源
              最近更新 更多