每周聚合包含许多列的数据框
Aggregate dataframe with many columns per week
我有一个包含许多列和时间戳的大型数据框 (see picture)
我要做的是每周汇总所有列的数据。有什么建议吗?
亲切的问候,
丹尼尔
如果没有最小的可重现示例,则很难确切知道使用哪个函数来汇总数据(总和、平均值、中位数等)。
现在我们假设每一行代表一天或更细粒度的单位(因为日期列称为 Timestamp
,我们看不到该字段中是否有实际时间值) .
我们使用 tidyr
、dplyr
和 lubridate
的组合来创建汇总数据框,对列中的数据求和。
首先,我们生成了一些格式类似于屏幕截图中数据的原始数据,并将其读入 R。
rawData <- "Timestamp,Var.2,Amazonas,Antioquia,Arauca
2022-01-01,0,0,0,1
2022-01-02,0,0,1,3
2022-01-03,0,1,1,2
2022-01-04,0,0,1,0
2022-01-05,0,2,0,0
2022-01-06,3,0,2,2
2022-01-07,2,3,0,2
2022-01-08,1,0,0,0
2022-01-09,0,1,3,0
2022-01-10,0,0,0,0
2022-01-11,0,2,0,5
2022-01-12,0,0,3,0
2022-01-13,0,3,0,4
2022-01-14,0,0,4,0
2022-01-15,0,0,0,3
2022-01-16,0,0,0,0
2022-01-17,0,3,0,0
2022-01-18,0,0,2,3
2022-01-19,0,0,0,0
2022-01-20,0,2,0,0
2022-01-21,0,0,5,2
2022-01-22,0,0,0,0
2022-01-23,0,1,0,0
2022-01-24,0,0,3,1
2022-01-25,0,1,0,1
2022-01-26,0,0,0,1
2022-01-27,0,2,0,0
2022-01-28,0,2,0,1
2022-01-29,0,0,1,0
2022-01-30,0,0,1,0"
df <- read.csv(text = rawData,
colClasses = c("Date","numeric","numeric","numeric","numeric"))
接下来,我们加载所需的库。在 lubridate
包中,我们将使用 year()
和 week()
函数按一年中的一周对数据进行分组。
library(lubridate)
library(tidyr)
library(dplyr)
最后,我们使用 tidyr::pivot_longer()
创建长格式整洁数据,其中每一行代表宽格式数据框中一列一天的观察结果,创建 Year
和 Week
列,以及 summarise()
数据框中的其余列。
df %>% pivot_longer(-Timestamp,names_to="Area") %>%
mutate(Year = year(Timestamp),
Week = week(Timestamp)) %>%
group_by(Year,Week,Area) %>%
summarise(summedValue = sum(value)) -> summarisedData
head(summarisedData)
...以及输出的前几行:
> head(summarisedData)
# A tibble: 6 × 4
# Groups: Year, Week [2]
Year Week Area summedValue
<dbl> <dbl> <chr> <dbl>
1 2022 1 Amazonas 6
2 2022 1 Antioquia 5
3 2022 1 Arauca 10
4 2022 1 Var.2 5
5 2022 2 Amazonas 6
6 2022 2 Antioquia 10
>
如果我们需要原始格式的数据(宽格式整洁数据),我们可以使用pivot_wider()
将数据恢复到原来的形状。
# if necessary, pivot_wider() to restore data to original format
summarisedData %>%
pivot_wider(id_cols=c("Year","Week"),
names_from=Area,
values_from=summedValue)
...以及输出:
# A tibble: 5 × 6
# Groups: Year, Week [5]
Year Week Amazonas Antioquia Arauca Var.2
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2022 1 6 5 10 5
2 2022 2 6 10 9 1
3 2022 3 5 7 8 0
4 2022 4 6 3 4 0
5 2022 5 0 2 0 0
>
两件事:
[1] 绝不提供数据图片;提供数据。
[2] 答案取决于你如何定义“周”。例如,2022-01-01 是星期六。 ISO 8601 标准定义了从星期一开始的一周,因此 2022 年的第 1 周从 1 月 3 日开始。从技术上讲,1 月 1 日和 2 日是 2021 年最后一周的一部分。lubridate 中的 week(...)
函数以 7 天为增量计数从一年的第一天开始。所以很明显你会得到不同的答案。
这是使用 data.table 执行此操作的一种非常简单的方法,借用了@LenGreski 友情提供的最小可重现示例(你 应该这样做)。
library(data.table)
setDT(df)[, lapply(.SD, sum), by=.(year=year(Timestamp), week=isoweek(Timestamp))]
## year week Var.2 Amazonas Antioquia Arauca
## 1: 2022 52 0 0 1 4
## 2: 2022 1 6 7 7 6
## 3: 2022 2 0 5 7 12
## 4: 2022 3 0 6 7 5
## 5: 2022 4 0 5 5 4
第一个子句 setDT(df)
将 df
转换为 data.table。其余部分将 sum(...)
函数应用于 .SD
引用的 data.table 中的列子集。默认子集是除 by=...
子句中引用的列之外的所有列(因此,除 Timestamp
之外的所有列)。
我有一个包含许多列和时间戳的大型数据框 (see picture) 我要做的是每周汇总所有列的数据。有什么建议吗?
亲切的问候, 丹尼尔
如果没有最小的可重现示例,则很难确切知道使用哪个函数来汇总数据(总和、平均值、中位数等)。
现在我们假设每一行代表一天或更细粒度的单位(因为日期列称为 Timestamp
,我们看不到该字段中是否有实际时间值) .
我们使用 tidyr
、dplyr
和 lubridate
的组合来创建汇总数据框,对列中的数据求和。
首先,我们生成了一些格式类似于屏幕截图中数据的原始数据,并将其读入 R。
rawData <- "Timestamp,Var.2,Amazonas,Antioquia,Arauca
2022-01-01,0,0,0,1
2022-01-02,0,0,1,3
2022-01-03,0,1,1,2
2022-01-04,0,0,1,0
2022-01-05,0,2,0,0
2022-01-06,3,0,2,2
2022-01-07,2,3,0,2
2022-01-08,1,0,0,0
2022-01-09,0,1,3,0
2022-01-10,0,0,0,0
2022-01-11,0,2,0,5
2022-01-12,0,0,3,0
2022-01-13,0,3,0,4
2022-01-14,0,0,4,0
2022-01-15,0,0,0,3
2022-01-16,0,0,0,0
2022-01-17,0,3,0,0
2022-01-18,0,0,2,3
2022-01-19,0,0,0,0
2022-01-20,0,2,0,0
2022-01-21,0,0,5,2
2022-01-22,0,0,0,0
2022-01-23,0,1,0,0
2022-01-24,0,0,3,1
2022-01-25,0,1,0,1
2022-01-26,0,0,0,1
2022-01-27,0,2,0,0
2022-01-28,0,2,0,1
2022-01-29,0,0,1,0
2022-01-30,0,0,1,0"
df <- read.csv(text = rawData,
colClasses = c("Date","numeric","numeric","numeric","numeric"))
接下来,我们加载所需的库。在 lubridate
包中,我们将使用 year()
和 week()
函数按一年中的一周对数据进行分组。
library(lubridate)
library(tidyr)
library(dplyr)
最后,我们使用 tidyr::pivot_longer()
创建长格式整洁数据,其中每一行代表宽格式数据框中一列一天的观察结果,创建 Year
和 Week
列,以及 summarise()
数据框中的其余列。
df %>% pivot_longer(-Timestamp,names_to="Area") %>%
mutate(Year = year(Timestamp),
Week = week(Timestamp)) %>%
group_by(Year,Week,Area) %>%
summarise(summedValue = sum(value)) -> summarisedData
head(summarisedData)
...以及输出的前几行:
> head(summarisedData)
# A tibble: 6 × 4
# Groups: Year, Week [2]
Year Week Area summedValue
<dbl> <dbl> <chr> <dbl>
1 2022 1 Amazonas 6
2 2022 1 Antioquia 5
3 2022 1 Arauca 10
4 2022 1 Var.2 5
5 2022 2 Amazonas 6
6 2022 2 Antioquia 10
>
如果我们需要原始格式的数据(宽格式整洁数据),我们可以使用pivot_wider()
将数据恢复到原来的形状。
# if necessary, pivot_wider() to restore data to original format
summarisedData %>%
pivot_wider(id_cols=c("Year","Week"),
names_from=Area,
values_from=summedValue)
...以及输出:
# A tibble: 5 × 6
# Groups: Year, Week [5]
Year Week Amazonas Antioquia Arauca Var.2
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2022 1 6 5 10 5
2 2022 2 6 10 9 1
3 2022 3 5 7 8 0
4 2022 4 6 3 4 0
5 2022 5 0 2 0 0
>
两件事:
[1] 绝不提供数据图片;提供数据。
[2] 答案取决于你如何定义“周”。例如,2022-01-01 是星期六。 ISO 8601 标准定义了从星期一开始的一周,因此 2022 年的第 1 周从 1 月 3 日开始。从技术上讲,1 月 1 日和 2 日是 2021 年最后一周的一部分。lubridate 中的 week(...)
函数以 7 天为增量计数从一年的第一天开始。所以很明显你会得到不同的答案。
这是使用 data.table 执行此操作的一种非常简单的方法,借用了@LenGreski 友情提供的最小可重现示例(你 应该这样做)。
library(data.table)
setDT(df)[, lapply(.SD, sum), by=.(year=year(Timestamp), week=isoweek(Timestamp))]
## year week Var.2 Amazonas Antioquia Arauca
## 1: 2022 52 0 0 1 4
## 2: 2022 1 6 7 7 6
## 3: 2022 2 0 5 7 12
## 4: 2022 3 0 6 7 5
## 5: 2022 4 0 5 5 4
第一个子句 setDT(df)
将 df
转换为 data.table。其余部分将 sum(...)
函数应用于 .SD
引用的 data.table 中的列子集。默认子集是除 by=...
子句中引用的列之外的所有列(因此,除 Timestamp
之外的所有列)。