从数据框架中,有一种简单的方法可以同时聚合(sum
,mean
,max
等c)多个变量吗?
以下是一些示例数据:
library(lubridate)
days = 365*2
date = seq(as.Date("2000-01-01"), length = days, by = "day")
year = year(date)
month = month(date)
x1 = cumsum(rnorm(days, 0.05))
x2 = cumsum(rnorm(days, 0.05))
df1 = data.frame(date, year, month, x1, x2)
我想同时按年份和月份汇总x1
数据框中的x2
和df2
变量。以下代码汇总了x1
变量,但是是否也可以同时汇总x2
变量?
### aggregate variables by year month
df2=aggregate(x1 ~ year+month, data=df1, sum, na.rm=TRUE)
head(df2)
任何建议都将不胜感激。
答案 0 :(得分:177)
是的,在您的formula
中,您可以cbind
汇总数字变量:
aggregate(cbind(x1, x2) ~ year + month, data = df1, sum, na.rm = TRUE)
year month x1 x2
1 2000 1 7.862002 -7.469298
2 2001 1 276.758209 474.384252
3 2000 2 13.122369 -128.122613
...
23 2000 12 63.436507 449.794454
24 2001 12 999.472226 922.726589
请参阅?aggregate
,formula
参数和示例。
答案 1 :(得分:46)
使用data.table
包,这是快速的(对较大的数据集很有用)
https://github.com/Rdatatable/data.table/wiki
library(data.table)
df2 <- setDT(df1)[, lapply(.SD, sum), by=.(year, month), .SDcols=c("x1","x2")]
setDF(df2) # convert back to dataframe
使用plyr包
require(plyr)
df2 <- ddply(df1, c("year", "month"), function(x) colSums(x[c("x1", "x2")]))
使用Hmisc包中的summarize() (虽然我的例子中的列标题很混乱)
# need to detach plyr because plyr and Hmisc both have a summarize()
detach(package:plyr)
require(Hmisc)
df2 <- with(df1, summarize( cbind(x1, x2), by=llist(year, month), FUN=colSums))
答案 2 :(得分:43)
这个year()
函数在哪里?
您还可以使用reshape2
包执行此任务:
require(reshape2)
df_melt <- melt(df1, id = c("date", "year", "month"))
dcast(df_melt, year + month ~ variable, sum)
# year month x1 x2
1 2000 1 -80.83405 -224.9540159
2 2000 2 -223.76331 -288.2418017
3 2000 3 -188.83930 -481.5601913
4 2000 4 -197.47797 -473.7137420
5 2000 5 -259.07928 -372.4563522
答案 3 :(得分:42)
使用dplyr
包,您可以使用summarise_all
,summarise_at
或summarise_if
函数同时聚合多个变量。对于示例数据集,您可以按如下方式执行此操作:
library(dplyr)
# summarising all non-grouping variables
df2 <- df1 %>% group_by(year, month) %>% summarise_all(sum)
# summarising a specific set of non-grouping variables
df2 <- df1 %>% group_by(year, month) %>% summarise_at(vars(x1, x2), sum)
df2 <- df1 %>% group_by(year, month) %>% summarise_at(vars(-date), sum)
# summarising a specific set of non-grouping variables based on condition (class)
df2 <- df1 %>% group_by(year, month) %>% summarise_if(is.numeric, sum)
后两个选项的结果:
year month x1 x2
<dbl> <dbl> <dbl> <dbl>
1 2000 1 -73.58134 -92.78595
2 2000 2 -57.81334 -152.36983
3 2000 3 122.68758 153.55243
4 2000 4 450.24980 285.56374
5 2000 5 678.37867 384.42888
6 2000 6 792.68696 530.28694
7 2000 7 908.58795 452.31222
8 2000 8 710.69928 719.35225
9 2000 9 725.06079 914.93687
10 2000 10 770.60304 863.39337
# ... with 14 more rows
注意:不推荐使用summarise_each
,而是summarise_all
,summarise_at
和summarise_if
。
正如my comment above中所述,您还可以使用recast
包中的reshape2
函数:
library(reshape2)
recast(df1, year + month ~ variable, sum, id.var = c("date", "year", "month"))
会给你相同的结果。
答案 4 :(得分:3)
有趣的是,此处未展示基数R data.frame
的{{1}}方法,above使用了公式接口,因此出于完整性考虑:
aggregate(
x = df1[c("x1", "x2")],
by = df1[c("year", "month")],
FUN = sum, na.rm = TRUE
)
更普遍地使用汇总的data.frame方法:
由于我们提供了
data.frame
分别为x
和list
的{{1}}(data.frame
也是list
),如果我们需要以动态方式使用它,例如使用其他列进行汇总和汇总非常简单例如这样的
by
答案 5 :(得分:1)
要使用更灵活,更快速的数据聚合方法,请查看CRAN上 collapse R包中的collap
函数:
library(collapse)
# Simple aggregation with one function
head(collap(df1, x1 + x2 ~ year + month, fmean))
year month x1 x2
1 2000 1 -1.217984 4.008534
2 2000 2 -1.117777 11.460301
3 2000 3 5.552706 8.621904
4 2000 4 4.238889 22.382953
5 2000 5 3.124566 39.982799
6 2000 6 -1.415203 48.252283
# Customized: Aggregate columns with different functions
head(collap(df1, x1 + x2 ~ year + month,
custom = list(fmean = c("x1", "x2"), fmedian = "x2")))
year month fmean.x1 fmean.x2 fmedian.x2
1 2000 1 -1.217984 4.008534 3.266968
2 2000 2 -1.117777 11.460301 11.563387
3 2000 3 5.552706 8.621904 8.506329
4 2000 4 4.238889 22.382953 20.796205
5 2000 5 3.124566 39.982799 39.919145
6 2000 6 -1.415203 48.252283 48.653926
# You can also apply multiple functions to all columns
head(collap(df1, x1 + x2 ~ year + month, list(fmean, fmin, fmax)))
year month fmean.x1 fmin.x1 fmax.x1 fmean.x2 fmin.x2 fmax.x2
1 2000 1 -1.217984 -4.2460775 1.245649 4.008534 -1.720181 10.47825
2 2000 2 -1.117777 -5.0081858 3.330872 11.460301 9.111287 13.86184
3 2000 3 5.552706 0.1193369 9.464760 8.621904 6.807443 11.54485
4 2000 4 4.238889 0.8723805 8.627637 22.382953 11.515753 31.66365
5 2000 5 3.124566 -1.5985090 7.341478 39.982799 31.957653 46.13732
6 2000 6 -1.415203 -4.6072295 2.655084 48.252283 42.809211 52.31309
# When you do that, you can also return the data in a long format
head(collap(df1, x1 + x2 ~ year + month, list(fmean, fmin, fmax), return = "long"))
Function year month x1 x2
1 fmean 2000 1 -1.217984 4.008534
2 fmean 2000 2 -1.117777 11.460301
3 fmean 2000 3 5.552706 8.621904
4 fmean 2000 4 4.238889 22.382953
5 fmean 2000 5 3.124566 39.982799
6 fmean 2000 6 -1.415203 48.252283
注意:您可以将mean, max
等基本函数与collap
一起使用,但是fmean, fmax
等是 collapse 包,它们的速度明显更快(即大型数据聚合的性能与 data.table 相同,同时提供了更大的灵活性,这些快速分组的函数也可以不使用{{ 1}})。
Note2 :collap
还支持灵活的多类型数据聚合,您当然可以使用collap
参数来完成,但是您也可以将函数应用于数字和非半自动数字列:
custom
答案 6 :(得分:0)
晚了聚会,但最近发现了另一种获取摘要统计信息的方法。
library(psych)
describe(data)
将输出: 每个变量的平均值,最小值,最大值,标准差,n,标准误,峰度,偏度,中位数和范围。
答案 7 :(得分:0)
对于devel
版的dplyr
(版本-‘0.8.99.9000’
),我们还可以使用summarise
在across
的多列上应用函数>
library(dplyr)
df1 %>%
group_by(year, month) %>%
summarise(across(starts_with('x'), sum))
# A tibble: 24 x 4
# Groups: year [2]
# year month x1 x2
# <dbl> <dbl> <dbl> <dbl>
# 1 2000 1 11.7 52.9
# 2 2000 2 -74.1 126.
# 3 2000 3 -132. 149.
# 4 2000 4 -130. 4.12
# 5 2000 5 -91.6 -55.9
# 6 2000 6 179. 73.7
# 7 2000 7 95.0 409.
# 8 2000 8 255. 283.
# 9 2000 9 489. 331.
#10 2000 10 719. 305.
# … with 14 more rows