【问题标题】:Convert Daily Data into Weekly Data and summarize multiple columns in R将每日数据转换为每周数据并汇总 R 中的多个列
【发布时间】:2021-08-23 02:16:35
【问题描述】:

我想更改以下数据集:

date          A   B
01/01/2018  391 585
02/01/2018  420 595
03/01/2018  455 642
04/01/2018  469 654
05/01/2018  611 900
06/01/2018  449 640
07/01/2018  335 522
08/01/2018  726 955
09/01/2018  676 938
10/01/2018  508 740
11/01/2018  562 778
12/01/2018  561 761
13/01/2018  426 609
14/01/2018  334 508

我想要的输出如下:

date           A       B
07/01/2018  3130    4538
14/01/2018  3793    5289

其中,A 列和 B 列的数量是每周 7 天的总和。确实,我想将每日数据转换为每周数据。 我在 Stackoverflow 网站上找到了两个解决方案。 一种解决方案是使用库(tidyquant)和以下代码

library(tidyquant)
newfd<-df %>%
  tq_transmute(select     = A,
               mutate_fun = apply.weekly,
               FUN        = sum)

代码为 A 列生成每周数据,而我需要所有列。 (我有很多专栏)。 我还使用了以下代码。但是,我不知道如何为所有列开发代码。

library(slider)   
slide_period_dfr(.x = califo, .i=as.Date(califo$date), 
                 .period = "week", 
                 .f = ~data.frame(week_ending = tail(.x$ date,1),
                                  week_freq = sum(.x$A)),
                 .origin = as.Date("2018-01-01"))

【问题讨论】:

    标签: r aggregation summarize tidyquant


    【解决方案1】:

    您可以计算索引id = 0:(nrow(df) - 1),一旦系列按日期排列,并使用它来定义每个日期week = id %/% 7 属于哪个时期(周)。在date = max(date) 中选择链接到每周的日期作为一周的最后一个日期。其他选项也是可能的。

    library(dplyr)
    library(lubridate)
    
    df <- tribble(~date, ~A, ~B,
    "01/01/2018", 391, 585,
    "02/01/2018", 420, 595,
    "03/01/2018", 455, 642,
    "04/01/2018", 469, 654,
    "05/01/2018", 611, 900,
    "06/01/2018", 449, 640,
    "07/01/2018", 335, 522,
    "08/01/2018", 726, 955,
    "09/01/2018", 676, 938,
    "10/01/2018", 508, 740,
    "11/01/2018", 562, 778,
    "12/01/2018", 561, 761,
    "13/01/2018", 426, 609,
    "14/01/2018", 334, 508)
    
    df %>%
      mutate(date = dmy(date)) %>% 
      arrange(date) %>% 
      mutate(id = 0:(nrow(df) - 1), week = id %/% 7) %>%
      group_by(week) %>% 
      summarize(date = max(date), across(A:B, sum))
    
    #> # A tibble: 2 x 4
    #>    week date           A     B
    #>   <dbl> <date>     <dbl> <dbl>
    #> 1     0 2018-01-07  3130  4538
    #> 2     1 2018-01-14  3793  5289
    

    reprex package (v0.3.0) 于 2021-06-05 创建

    【讨论】:

      【解决方案2】:

      您可以使用ceiling_date 将日期设置为每周日期,并使用sumdplyr 中使用across 多个变量。

      library(dplyr)
      library(lubridate)
      
      df %>%
        group_by(date = ceiling_date(dmy(date), 'week', week_start = 1)) %>%
        summarise(across(A:B, sum))
      
      #  date           A     B
      #  <date>     <int> <int>
      #1 2018-01-08  3130  4538
      #2 2018-01-15  3793  5289
      

      数据

      df <- structure(list(date = c("01/01/2018", "02/01/2018", "03/01/2018", 
      "04/01/2018", "05/01/2018", "06/01/2018", "07/01/2018", "08/01/2018", 
      "09/01/2018", "10/01/2018", "11/01/2018", "12/01/2018", "13/01/2018", 
      "14/01/2018"), A = c(391L, 420L, 455L, 469L, 611L, 449L, 335L, 
      726L, 676L, 508L, 562L, 561L, 426L, 334L), B = c(585L, 595L, 
      642L, 654L, 900L, 640L, 522L, 955L, 938L, 740L, 778L, 761L, 609L, 
      508L)), class = "data.frame", row.names = c(NA, -14L))
      

      【讨论】:

      • 非常感谢。但是,还有一个小问题。日期列从 2018-01-08 开始,而我想从 2018-01-07 开始。
      • 你可以用mutate(date = date - 1)date中减去1天,得到想要的日期。
      【解决方案3】:

      您可以pivot_longer(),这样您只有一列数据要转换,将函数应用于该列,然后pivot_wider()

      这是mtcars 的一个简单示例:

      library(tidyverse)
      mtcars %>%
        rownames_to_column(var = "car") %>% 
        select(car, mpg, cyl) %>% 
        pivot_longer(cols = c(mpg, cyl), names_to = "var") %>% 
        mutate(value = value^2) %>% 
        pivot_wider(names_from = var, names_prefix = "squared_")
      
      # A tibble: 32 x 3
         car               squared_mpg squared_cyl
         <chr>                   <dbl>       <dbl>
       1 Mazda RX4                441           36
       2 Mazda RX4 Wag            441           36
       3 Datsun 710               520.          16
       4 Hornet 4 Drive           458.          36
       5 Hornet Sportabout        350.          64
       6 Valiant                  328.          36
       7 Duster 360               204.          64
       8 Merc 240D                595.          16
       9 Merc 230                 520.          16
      10 Merc 280                 369.          36
      # … with 22 more rows
      

      您的aggregation 将取代我的mutate 步骤。

      这是否比重复创建新变量更简洁取决于您要处理的变量数量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-13
        • 2021-04-28
        • 2013-05-02
        • 2018-02-15
        • 2020-07-15
        • 2020-07-06
        • 2023-03-08
        相关资源
        最近更新 更多