dplyr包:plyr包的替代者,专门面对数据框,将ddplyr转变为更易用的接口
%>%来自dplyr包的管道函数,其作用是将前一步的结果直接传参给下一步的函数,从而省略了中间的赋值步骤,可以大量减少内存中的对象,节省内存,可惜的是应用范围还不是很广。
dplyr和data.table(易于操作数据)是R的两个高效数据处理包,这两个包有它们各自的优点。
data.table在语法灵活性和performance上面更深一筹,dplyr则在易学性和SQL语句转换方面有独到之处
首先dplyr提供了一个符号%>%,该符号将左边的对象作为第一个参数传递到右边的函数中,这样就实现类似unix管道的编程风格,代码更易读。
dplyr很好地解决了base包中的几个数据处理的痛点,具体可以参考本系列01。
首先,dplyr可以方便地抽取数据框的子集。抽取行的子集函数有filter,distinct,sample_frac,sample_n,slice,top_n。抽取列的子集函数是select,可通过列名或选项函数进行选择,常见的选项函数有contains(“.”),ends_with(“Length”),starts_with(“Sepal”),everything(),matches(“.t.”),num_range(“x”, 1:5),one_of(c(“Species”, “Genus”))。
其次,dplyr还提供了函数arrange,方便按照某一列进行数据排序。
1
|
arrange(mtcars, mpg) # 从低到高
|
然后,dplyr可以方便地进行数据集的合并,取代merge函数。
1
|
left_join(a, b, by="x1")
|
dplyr还提供了intersection、union和setdiff用于获得两个数据集的交集、并集和差集。
最后,dplyr可以方便地进行数据集的拼接。bind_rows(y, z)将数据集z按行拼接到数据集y中,bind_cols(y, z)将数据集z按列拼接到数据集y中。
本系列03介绍plyr时,知道这个包最主要地是用来做分组处理,dplyr对此功能进行了升级,详述如下。
dplyr可以方便地对数据框进行概述,相当于ddply中的summarize。summarise(iris, avg=mean(Sepal.Length))将数据概括为单行结果输出;summarise_each(iris, funs(mean))对每一列运行概述函数。支持的概述函数有first,last,nth,n,n_distinct,min,max,mean,median,var,sd。
dplyr可以方便地创建新变量,相当于ddply中的transform。mutate(iris, sepal=Sepal.Length+Sepal.Width)计算并添加一个或多个新列。mutate_each(iris, funs(min_rank))对每一列运行窗口函数。常见的窗口函数有row_number,min_rank,percent_rank,cumsum等。
dplyr提供了一个分组函数group_by,把分组依据相同的数据组合成行,相当于ddply中的group_vars。ungroup用于移出数据框的分组信息。配合上管道符号,可以方便地进行分组概述和分组计算。
1
|
iris %>% group_by(Species) %>% summarise(...)
|
强大的dplyr包实现数据预处理
工作中的数据分析或挖掘任务都需要进行各种各样的数据预处理,包括数据整合、关联、排序、筛选等。下面将介绍强大的dplyr包,其可以非常灵活、快速的实现数据的预处理。
select()
: 按列变量选择filter()
: 按行名称分片slice()
: 按行索引分片mutate()
: 在原数据集最后一列追加一些数据集summarise()
: 每组聚合为一个小数量的汇总统计,通常结合gruop_by()
使用arrange()
: 按行排序
#tbl对象
使用dplyr包预处理时建议使用tbl_df()函数或tbl_cube()函数或tbl_sql()函数将原数据转换为tbl对象,因为dplyr包用C语言开发,对处理tbl对象是非常迅速的。语法:
tbl_df(src, ...)
tbl_cube(dimensions, measures)
tbl_sql(subclass, src, from, ..., vars = attr(from, 'vars'))
#观测筛选
如果需要将数据集中的某些观测进行筛选的话,可以使用filter()函数,语法如下:
filter(.data, ...)
.data为tbl对象
...为观测筛选条件,类似于subset()函数中的用法,但不同的是filter()函数不能筛选某些变量。
例子:
df <- data.frame(x = c('a','b','c','a','b','e','d','f'), y = c(1,2,3,4,5,6,7,8))
df2tbl <- tbl_df(df)
filter(df2tbl,x %in% c('a','b'))
#变量选取
filter()函数只能将指定条件的观测筛选出来,并不能筛选出只关心的变量,为了弥补这个缺陷,可以使用select()函数筛选指定的变量,而且比subset()函数更灵活,而且选择变量的同时也可以重新命名变量。如果剔除某些变量的话,只需在变量前加上负号“-”。之所以说他比subset()函数灵活,是因为可以在select()函数传递如下参数:
starts_with(x, ignor.case = TRUE)#选择以字符x开头的变量
ends_with(x, ignor.case = TRUE)#选择以字符x结尾的变量
contains(x, ignor.case = TRUE)#选择所有包含x的变量
matches(x, ignor.case = TRUE)#选择匹配正则表达式的变量
num_range('x', 1:5, width = 2)#选择x01到x05的变量
one_of('x','y','z')#选择包含在声明变量中的
everything()#选择所有变量,一般调整数据集中变量顺序时使用
例子:
#将df2tbl数据集中的y变量放到x变量前
select(df2tbl,y,everything())
#筛选变量的同时,重新命名变量名
select(df2tbl, x1 = x, y1 = y)
#重命名变量
如果需要对数据集中的某些变量进行重命名的话,可直接使用rename()函数,语法如下:
rename(tbl, newname = oldname,...)
例子:
rename(df2tbl, x1 = x, y1 = y)
#数据排序
数据预处理过程中往往也需要按某些变量进行排序,dplyr包提供了非常便捷的arrange()函数实现排序功能,语法如下:
arrange(.data, ...)
arrange()函数默认以某个变量进行升序,如需降序则desc(var_name)即可。
例子:
arrange(df2tbl, y) #默认升序
arrange(df2tbl, desc(y)) #降序操作
#数据扩展
通过mulate()函数可以在原始数据集的基础上扩展新变量,类似于transform()函数,语法如下:
mutate(.data, ...)
例子:
mutate(df2tbl, z = y^2 + y - 10)
同样可以进行数据扩展的还有transmute()函数,与mutate()函数不同的是,该函数扩展新变量的同时,将删除所有原始变量。
例子:
transmute(df2tbl, z = y^2 + y - 10)
#数据聚合
在数据库操作中,往往需要进行聚合函数的应用,这里同样可以很方面使用summarize()函数实现数据集聚合操作,语法如下:
summarize(.data, ...)
可以用来聚合的函数有:
min():返回最小值
max():返回最大值
mean():返回均值
sum():返回总和
sd():返回标准差
median():返回中位数
IQR():返回四分位极差
n():返回观测个数
n_distinct():返回不同的观测个数
first():返回第一个观测
last():返回最后一个观测
nth():返回n个观测
例子:
summarize(df2tbl, max(y))
summarize(df2tbl, n())
而且该函数还可以结合group_by()函数实现分组聚合,group_by()函数语法:
group_by(.data, ..., add = FALSE)
例子:
summarize(group_by(df2tbl,x), sum(y))
#数据关连
我们知道,数据库中经常需要将多个表进行连接操作,如左连接、右连接、内连接等,这里dplyr包也提供了数据集的连接操作,具体如下:
inner_join#內连
left_join#左连
right_join#右连
full_join#全连
semi_join#返回能够与y表匹配的x表所有记录
anti_join#返回无法与y表匹配的x表的所记录
intersect(x, y): x 和 y 的交集(按行)
union(x, y): x 和 y 的并集(按行)
setdiff(x, y): x 和 y 的补集 (在x中不在y中)
例子:
df2 <- data.frame(x = c('a','b','c'), z = c('A','B','C'))
df2tbl2 <- tbl_df(df2)
inner_join(x = df2tbl, y = df2tbl2, by = 'x')
semi_join(x = df2tbl, y = df2tbl2, by = 'x')
anti_join(x = df2tbl, y = df2tbl2, by = 'x')
#数据合并
在R基础包里有cbind()函数和rbind()函数实现按列的方向进行数据合并和按行的方向进行数据合并,而在dplyr包中也添加了类似功能的函数,它们是bind_cols()函数和bind_rows()函数。
例子:
mydf1 <- data.frame(x = c(1,2,3,4), y = c(10,20,30,40))
mydf2 <- data.frame(x = c(5,6), y = c(50,60))
mydf3 <- data.frame(z = c(100,200,300,400))
bind_rows(mydf1, mydf2)
bind_cols(mydf1, mydf3)
需要说明的是,bind_rows()函数需要两个数据框或tbl对象有相同的列数,而bind_cols()函数则需要两个数据框或tbl对象有相同的行数。
#管道函数
这里介绍一种dplyr包中特有的管道函数,即通过%>%将上一个函数的输出作为下一个函数的输入。
例子:根据数据集df2tbl和df2tbl2,取出z变量对应的最大y值
inner_join(x = df2tbl, y = df2tbl2, by = 'x') %>% group_by(., z) %>% summarize(., max(y))
#连接数据库数据
如果需要获取MySQL数据库中的数据时,可以直接使用dplyr包中的src_mysql()函数,其功能类似于RMySQL包。src_mysql()函数语法如下:
src_mysql(dbname, host = NULL, port = 0L, user = "root", password = "",
...)
通过以上方式连接MySQL数据库后,使用tbl()函数获取数据集,tbl()函数语法如下:
tbl(src,from = '')
src为src_mysql()函数对象
from为SQL语句
例子:
src <- src_mysql('test', host = 'localhost', user = 'root', password = 'snake')
src
#获取指定表中的数据
tbl(src, from = 'diff')
转载自:强大的dplyr包实现数据预处理