[20] 《R数据科学》使用summarize()进行分组摘要
group_by()
和summarize()
的组合构成了使用dplyr包时最常用的操作之一:分组摘要。
summarize()
,可以将数据框折叠成一行,比如我们求flights数据集中变量dep_delay的平均值:
library(dplyr)
library(nycflights13)
summarize(flights,delay=mean(dep_delay,na.rm=TRUE))
分组摘要group_by()和summarize()
如果对按日期分组的一个数据框应用与上面完全相同的代码,那么我们就可以得到每日平均延误时间:
by_day <- group_by(flights,year,month,day)
summarise(by_day,delay=mean(dep_delay,na.rm=TRUE))
# A tibble: 365 x 4
# Groups: year, month [12]
year month day delay
<int> <int> <int> <dbl>
1 2013 1 1 11.5
2 2013 1 2 13.9
3 2013 1 3 11.0
4 2013 1 4 8.95
5 2013 1 5 5.73
6 2013 1 6 7.15
7 2013 1 7 5.42
8 2013 1 8 2.55
9 2013 1 9 2.28
10 2013 1 10 2.84
# ... with 355 more rows
使用管道组合多种操作
library(ggplot2)
by_dest <- group_by(flights,dest)
delay <- summarise(by_dest,count=n(),dist=mean(distance,na.rm = TRUE),delay=mean(arr_delay,na.rm = TRUE))
delay <- filter(delay,count>20,dest!='HNL')
ggplot(delay,aes(dist,delay))+geom_point(aes(size=count),alpha=1/3)+geom_smooth(se=FALSE)
image.png
为了增加代码的可读性,可以将上面的中间变量省去,使用管道符号
%>%
来传递,%>%
符号可以读作“然后”。
delays <- flights %>% group_by(dest) %>% summarise(count=n(),dist=mean(distance,na.rm = TRUE),delay=mean(arr_delay,na.rm = TRUE)) %>% filter(count >20 ,dest!='HNL')
ggplot(delays,aes(dist,delay))+geom_point(aes(size=count),alpha=1/3)+geom_smooth(se=FALSE)
缺失值
在前面的代码中我们使用了参数na.rm,如果不使用会发生什么?效果如下:
flights %>% group_by(year,month,day) %>% summarise(mean=(mean(dep_delay)))
# A tibble: 365 x 4
# Groups: year, month [12]
year month day mean
<int> <int> <int> <dbl>
1 2013 1 1 NA
2 2013 1 2 NA
3 2013 1 3 NA
4 2013 1 4 NA
5 2013 1 5 NA
6 2013 1 6 NA
7 2013 1 7 NA
8 2013 1 8 NA
9 2013 1 9 NA
10 2013 1 10 NA
# ... with 355 more rows
这时会得到很多缺失值,这是因为聚合函数遵循一般的缺失规则:如果输入中有缺失值,那么输出也会是缺失值,而使用na.rm=TRUE
可以在计算前去除缺失值。
当然,也可以通过去除取消的航班以剔除缺失值:
not_cancelled <- flights %>% filter(!is.na(dep_delay),!is.na(arr_delay))
not_cancelled %>% group_by(year,month,day) %>% summarize(mean=mean(dep_delay))
# A tibble: 365 x 4
# Groups: year, month [12]
year month day mean
<int> <int> <int> <dbl>
1 2013 1 1 11.4
2 2013 1 2 13.7
3 2013 1 3 10.9
4 2013 1 4 8.97
5 2013 1 5 5.73
6 2013 1 6 7.15
7 2013 1 7 5.42
8 2013 1 8 2.56
9 2013 1 9 2.30
10 2013 1 10 2.84
# ... with 355 more rows
计数
聚合操作中包括一个计数(n())
或非缺失值计数(sum(!is.na()))
是个好主意。这样就可以检查是不是基于非常少的数据做出结论。例如,查看具有最长平均延误时间的飞机:
delays <- not_cancelled %>% group_by(tailnum) %>% summarise(delay=mean(arr_delay))
ggplot(delays,aes(delay))+geom_freqpoly(binwidth = 10)
image.png
绘制航班数量和平均延误时间的散点图可以获得更深刻的理解:
delays <- not_cancelled %>% group_by(tailnum) %>% summarise(delay=mean(arr_delay,na.rm = TRUE),n=n())
ggplot(delays,aes(n,delay))+geom_point(alpha=1/3)
image.png
结果显示,航班数量非常少时,平均延误时间变动特别大。
将ggplot2集成到dplyr工作流中:
delays %>% filter(n >25) %>% ggplot(aes(n,delay))+geom_point(alpha=1/10)
image.png
常用摘要函数
位置度量
mean(x)
,median(x)
,均值和中位数
分散程度度量
sd(x)
,IQR(x)
,mad(x)
,标准误差,四分位距,绝对中位差
秩的度量
min(x)
,quantile(x,0.25)
,max(x)
quantile(x,0.25)
会找出顺序大于25%而小于后75%的值。
定位度量
first(x)
,nth(x,2)
,last(x)
上面函数的作用与x[1]
,x[2]
和x[length(x)]
相同。
计数
n(x)
,sum(!is.na(x))
n_distinct(x)
计算唯一值的数量
逻辑值的计数和比例
sum(x >10 )
和mean(y == 0)
sum(x)
可以找出x中TRUE的数量,mean(x)
则可以找出比例。