【问题标题】:Convert Daily Data into Weekly Data in R在 R 中将每日数据转换为每周数据
【发布时间】:2020-06-13 22:52:14
【问题描述】:

我有 7 年的每日数据。我想将其分组为每周数据(基于实际日期)并对频率求和。

Date Frequency
1   2014-01-01  179
2   2014-01-02  82  
3   2014-01-03  89  
4   2014-01-04  109 
5   2014-01-05  90  
6   2014-01-06  66  
7   2014-01-07  75  
8   2014-01-08  106 
9   2014-01-09  89  
10  2014-01-10  82

实现这一目标的最佳方法是什么?谢谢

【问题讨论】:

标签: r date frequency


【解决方案1】:

我会使用library(lubridate)

df <- read.table(header = TRUE,text = "date Frequency
2014-01-01  179
2014-01-02  82  
2014-01-03  89  
2014-01-04  109 
2014-01-05  90  
2014-01-06  66  
2014-01-07  75  
2014-01-08  106 
2014-01-09  89  
2014-01-10  82")

你可以使用base R或者library(dplyr):

基础 R: 确保日期确实是日期:

df$date <- ymd(df$date)
df$week <- week(df$date)

或简称:

df$week <- week(ymd(df$date))

或 dplyr:

library(dplyr)
df %>% 
  mutate(week = week(ymd(date))) %>% 
  group_by(week)

输出:

【讨论】:

    【解决方案2】:

    来自 RStudio 的新包 slider 直接解决了这个问题,包括每周周期开始的规范。假设每周周期从星期一开始,因此第一周的开始时间为Monday, 2013-12-30。那么滑块解决方案将是

    library(slider)   
    slide_period_dfr(.x = DF, .i=as.Date(DF$Date), 
                     .period = "week", 
                     .f = ~data.frame(week_ending = tail(.x$Date,1),
                                       week_freq = sum(.x$Frequency)),
                     .origin = as.Date("2013-12-30"))
    

    结果

     week_ending week_freq
    1  2014-01-05       549
    2  2014-01-10       418
    

    【讨论】:

      【解决方案3】:

      这些解决方案都使用基数 R,仅在周的定义和标签上有所不同。

      1) cut 将日期转换为周,然后汇总这些周。周从星期一开始,但如果您愿意,可以将 start.on.monday=FALSE 添加到 cut 以在星期日开始。

      Week <- as.Date(cut(DF$Date, "week"))
      aggregate(Frequency ~ Week, DF, sum)
      ##         Week Frequency
      ## 1 2013-12-30       549
      ## 2 2014-01-06       418
      

      2) 如果您希望将一周定义为从 DF$Date[1] 开始的 7 天,并根据该周的第一个日期对其进行标记,请使用它。 (如果您更喜欢一周中的最后一个日期,请将 6 添加到 Week。)

      weekno <- as.numeric(DF$Date - DF$Date[1]) %/% 7
      Week <- DF$Date[1] + 7 * weekno
      aggregate(Frequency ~ Week, DF, sum)
      ##         Week Frequency
      ## 1 2014-01-01       690
      ## 2 2014-01-08       277
      

      3) 或者如果您更喜欢使用该周DF 中存在的第一个日期来标记它,那么使用它。如果没有像这里的情况那样缺少日期,则此定义和上一个 Week 定义给出相同的结果。 (如果您想要一周中的最后一个现有日期而不是第一个日期,请将 match 替换为 findInterval。)

      weekno <- as.numeric(DF$Date - DF$Date[1]) %/% 7
      Week <- DF$Date[match(weekno, weekno)]
      aggregate(Frequency ~ Week, DF, sum)
      ##         Week Frequency
      ## 1 2014-01-01       690
      ## 2 2014-01-08       277
      

      注意

      假设可重现形式的输入为:

      Lines <- "Date Frequency
      1 2014-01-01 179
      2 2014-01-02 82 
      3 2014-01-03 89 
      4 2014-01-04 109 
      5 2014-01-05 90 
      6 2014-01-06 66 
      7 2014-01-07 75 
      8 2014-01-08 106 
      9 2014-01-09 89 
      10 2014-01-10 82"
      DF <- read.table(text = Lines)
      DF$Date <- as.Date(DF$Date)
      

      【讨论】:

        【解决方案4】:

        也许您可以尝试使用aggregate + format 的基本 R 代码,即,

        dfout <- aggregate(Frequency ~ yearweek,within(df,yearweek <- format(Date,"%Y,%W")),sum)
        

        这样

        > dfout
          yearweek Frequency
        1  2014,00       549
        2  2014,01       418
        

        数据

        df <- structure(list(Date = structure(c(16071, 16072, 16073, 16074, 
        16075, 16076, 16077, 16078, 16079, 16080), class = "Date"), Frequency = c(179L, 
        82L, 89L, 109L, 90L, 66L, 75L, 106L, 89L, 82L)), row.names = c("1", 
        "2", "3", "4", "5", "6", "7", "8", "9", "10"), class = "data.frame")
        

        【讨论】:

        • 杰出的托马斯 :)
        【解决方案5】:

        除非有充分的理由不这样做,否则您应该确保使用 ISO weeks 以确保您的聚合间隔大小相同。

        data.table 使这项工作像这样:

        library(data.table)
        setDT(myDF) # convert to data.table
        
        myDF[ , .(weekly_freq = sum(Frequency)), by = isoweek(Date)]
        

        【讨论】:

          猜你喜欢
          • 2021-04-28
          • 2013-05-02
          • 2020-07-06
          • 2016-01-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-16
          • 1970-01-01
          相关资源
          最近更新 更多