将每日数据转换为每周数据并在 R 中汇总多列

问题描述

我想更改以下数据集:

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 网站上找到了两个解决方案。 一种解决方案是使用 library(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"))

解决方法

您可以使用 ceiling_date 将日期设为每周日期,并使用 sum 中的 acrossdplyr 多个变量设为。

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))
,

您可以计算索引 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,420,595,455,642,469,654,611,900,449,640,335,522,726,955,676,938,508,740,562,778,561,761,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 年 6 月 5 日创建

,

您可以 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 步骤。

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