笔记说明
数据清理可能是数据分析中耗时占比最大的操作了。dplyr包是一个用于数据清理的高效r包,也是tidyverse
的核心包之一。
dplyr包的常用操作包括:
mutate()
adds new variables that are functions of existing variables
select()
picks variables based on their names.
filter()
picks cases based on their values.
summarise()
reduces multiple values down to a single summary.
arrange()
changes the ordering of the rows.
group_by()
allows you to perform any operation “by group”
上次笔记(用dplyr包进行数据清理-filter()和select())中介绍了filter()
和select()
,本次笔记介绍group_by()
和summarise()
主要参考:https://b-rodrigues.github.io/modern_R/descriptive-statistics-and-data-manipulation.html#the-tidyverses-enfant-prodige-dplyr
推荐阅读:https://dplyr.tidyverse.org/
准备工作
加载dplyr包
library(dplyr)
数据准备,我们使用plm
包中的Gasoline
数据集作为示例数据。该数据集包含1960至1978年间18个国家的汽油消耗量。原始数据是一个data.frame对象,我们用as_tibble()
将其转换为一个tibble对象。
可以把tibble理解成一个优化版的data.frame。dplyr包中的各个函数可以作用于data.frame对象,也可以作用于tibble对象。
# 数据准备
install.packages("plm")
data(Gasoline, package = "plm")
gasoline <- as_tibble(Gasoline)
用group_by()函数将数据分组
gasoline %>% group_by(country)
## # A tibble: 342 x 6
## # Groups: country [18]
## country year lgaspcar lincomep lrpmg lcarpcap
## <fct> <int> <dbl> <dbl> <dbl> <dbl>
## 1 AUSTRIA 1960 4.17 -6.47 -0.335 -9.77
## 2 AUSTRIA 1961 4.10 -6.43 -0.351 -9.61
## 3 AUSTRIA 1962 4.07 -6.41 -0.380 -9.46
## 4 AUSTRIA 1963 4.06 -6.37 -0.414 -9.34
## 5 AUSTRIA 1964 4.04 -6.32 -0.445 -9.24
## 6 AUSTRIA 1965 4.03 -6.29 -0.497 -9.12
## 7 AUSTRIA 1966 4.05 -6.25 -0.467 -9.02
## 8 AUSTRIA 1967 4.05 -6.23 -0.506 -8.93
## 9 AUSTRIA 1968 4.05 -6.21 -0.522 -8.85
## 10 AUSTRIA 1969 4.05 -6.15 -0.559 -8.79
## # … with 332 more rows
代码中管道操作符%>%
的作用就是把符号前的对象作为第一个参数传递给符号后的函数。x %>% f(y)
等价于f(x,y)
。
结果看似没有什么发生变化,但结果中第二行显示的Groups: country [18]
说明这个数据已经按country变量分组,接下来再进行的操作会在各组内进行。
group_by()
也可以按两个或以上变量分组:
gasoline %>% group_by(country, year)
如果想取消分组性质,可以使用ungroup()
:
gasoline %>% group_by(country, year) %>% ungroup()
用summarise()函数计算汇总统计量
summarise()
通常是搭配group_by()
一起使用来计算汇总统计量。用法是summarise(data, name=value...)
其中data是要操作的数据集,name是结果中显示的变量名,value是返回单一值的任何表达式。多个name-value之间用逗号分隔。举例:
gasoline %>%
group_by(country) %>%
summarise(mean_gaspcar = mean(lgaspcar),
sd_gaspcar = sd(lgaspcar),
max_gaspcar = max(lgaspcar),
min_gaspcar = min(lgaspcar))
## # A tibble: 18 x 5
## country mean_gaspcar sd_gaspcar max_gaspcar min_gaspcar
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 AUSTRIA 4.06 0.0693 4.20 3.92
## 2 BELGIUM 3.92 0.103 4.16 3.82
## 3 CANADA 4.86 0.0262 4.90 4.81
## 4 DENMARK 4.19 0.158 4.50 4.00
## 5 FRANCE 3.82 0.0499 3.91 3.75
## 6 GERMANY 3.89 0.0239 3.93 3.85
## 7 GREECE 4.88 0.255 5.38 4.48
## 8 IRELAND 4.23 0.0437 4.33 4.16
## 9 ITALY 3.73 0.220 4.05 3.38
## 10 JAPAN 4.70 0.684 6.00 3.95
## 11 NETHERLA 4.08 0.286 4.65 3.71
## 12 NORWAY 4.11 0.123 4.44 3.96
## 13 SPAIN 4.06 0.317 4.75 3.62
## 14 SWEDEN 4.01 0.0364 4.07 3.91
## 15 SWITZERL 4.24 0.102 4.44 4.05
## 16 TURKEY 5.77 0.329 6.16 5.14
## 17 U.K. 3.98 0.0479 4.10 3.91
## 18 U.S.A. 4.82 0.0219 4.86 4.79
与R自带的summary()
相比,dplyr
包的summarise()
的一大优势是:和其他dplyr
包中的verbs(如之前介绍的filter()
,select()
,group_by()
等)一样,函数运行的结果是一个tibble对象。我们可以对运行结果继续进行其他的数据操作。结合使用管道操作符%>%
,代码的可读性也非常好。比如:
gasoline %>%
group_by(country) %>%
summarise(mean_gaspcar = mean(lgaspcar),
sd_gaspcar = sd(lgaspcar),
max_gaspcar = max(lgaspcar),
min_gaspcar = min(lgaspcar)) %>%
filter(country == "FRANCE")
## # A tibble: 1 x 5
## country mean_gaspcar sd_gaspcar max_gaspcar min_gaspcar
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 FRANCE 3.82 0.0499 3.91 3.75
我们也可以把summarise()
的运行结果保存为一个变量:
desc_gasoline <- gasoline %>%
group_by(country) %>%
summarise(mean_gaspcar = mean(lgaspcar),
sd_gaspcar = sd(lgaspcar),
max_gaspcar = max(lgaspcar),
min_gaspcar = min(lgaspcar))