[学习分享] R语言扩展包dplyr笔记 (转载)
2018-01-21 16:56
288 查看
2014年刚到,
就在 Feedly 订阅里看到 RStudio
Blog 介绍 dplyr 包已发布 (Introducing
dplyr), 此包将原本 plyr 包中的 ddply()
等函数进一步分离强化, 专注接受dataframe对象, 大幅提高了速度,
并且提供了更稳健的与其它数据库对象间的接口。
0.1 安装
install.packages("dplyr")
0.2 示范数据
library(Lahman) : Lahman 包里的棒球比赛数据集
Batting
library(hflights) : hflights 包里的飞机航班数据
0.3 数据集类型
## 将过长过大的数据集转换为显示更友好的 tbl_df 类型:
hflights_df <- tbl_df(hflights)
## 可以 hflights_df 感受一下不再被刷屏的感觉.
1 基本操作
把常用的数据操作行为归纳为以下五种:
1.1 筛选: filter()
按给定的逻辑判断筛选出符合要求的子数据集, 类似于base::subset()
函数
例如:
filter(hflights_df, Month == 1, DayofMonth == 1)
## 用R自带函数实现:
hflights[hflights$Month == 1 & hflights$DayofMonth
== 1, ] ;
除了代码简洁外, 还支持对同一对象的任意个条件组合, 如:
filter(hflights_df, Month == 1 | Month == 2)
## 注意: 表示 AND 时要使用&
而避免 &&
1.2 排列: arrange()
按给定的列名依次对行进行排序.
例如:
arrange(hflights_df, DayofMonth, Month, Year)
对列名加 desc() 进行倒序:
arrange(hflights_df, desc(ArrDelay))
## 这个函数和 plyr::arrange() 是一样的, 类似于 order()
## 用R自带函数实现:
hflights[order(hflights$DayofMonth,hflights$Month, hflights$Year),] ;
hflights[order(desc(hflights$ArrDelay)), ] ;
1.3 选择: select()
用列名作参数来选择子数据集:
select(hflights_df, Year, Month, DayOfWeek)
还可以用 :来连接列名, 没错, 就是把列名当作数字一样使用
select(hflights_df, Year : DayOfWeek)
## 选择从Year列(第一列)到DayOfWeek列(第四列)
用 - 来排除列名:
select(hflights_df, -(Year : DayOfWeek))
## 减号后面的列将不会被选择
同样类似于R自带的
subset() 函数 (但不用再写一长串的 c("colname1", "colname2") 或者 which(colname(data) == "colname3"), 甚至还要去查找列号)
1.4 变形: mutate()
对已有列进行数据运算并添加为新列:
mutate(hflights_df, gain = ArrDelay - DepDelay, speed = Distance / AirTime * 60)
## 作用与 plyr::mutate() 相同, 与 base::transform() 相似,优势在于可以在同一语句中对刚增加的列进行操作
mutate(hflights_df, gain = ArrDelay - DepDelay, gain_per_hour = gain / (AirTime / 60))
## 而同样操作用R自带函数 transform() 的话就会报错
transform(hflights, gain = ArrDelay - DepDelay, gain_per_hour = gain / (AirTime / 60))1.5
汇总: summarise()
对数据框调用其它函数进行汇总操作, 返回一维的结果:
summarise(hflights_df, delay = mean(DepDelay, na.rm = TRUE))
## 该函数功能尚不是非常有用
2 分组动作 group_by()
以上5个动词函数已经很方便了,
但是当它们跟分组操作这个概念结合起来时, 那才叫真正的强大!
当对数据集通过
group_by() 添加了分组信息后,mutate(),arrange()
和summarise() 函数会自动对这些 tbl 类数据执行分组操作 (R语言泛型函数的优势).
例如: 对飞机航班数据按飞机编号
(TailNum) 进行分组, 计算该飞机航班的次数 (count = n()), 平均飞行距离 (dist = mean(Distance, na.rm = TRUE)) 和 延时 (delay = mean(ArrDelay, na.rm = TRUE)) .
planes <- group_by(hflights_df, TailNum);
delay <- summarise(planes, count = n(), dist = mean(Distance, na.rm = TRUE), delay = mean(ArrDelay, na.rm = TRUE));
delay <- filter(delay, count > 20, dist < 2000);
## 用 ggplot2 包作个图观察一下, 发现飞机延时不延时跟飞行距离没太大相关性
ggplot(delay, aes(dist, delay)) + geom_point(aes(size = count), alpha = 1/2) + geom_smooth() + scale_size_area()
![](https://img-blog.csdn.net/20180121162728088?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VpeGluXzQxNTc3Mjkx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
## 更多例子见 vignette("introduction", package = "dplyr")
另: 一些汇总时的小函数
n(): 计算个数
n_distinct(): 计算 x 中唯一值的个数. (原文为 count_distinct(x), 测试无用)
first(x), last(x) 和 nth(x, n): 返回对应秩的值, 类似于自带函数 x[1], x[length(x)], 和 x
## 注意: 分组计算得到的统计量要清楚样本已经发生了变化, 此时的中位数是不可靠的
3连接符 %.%
包里还新引进了一个操作符, 使用时把数据名作为开头, 然后依次对此数据进行多步操作.
Batting %.% group_by(playerID) %.% summarise(total = sum(G)) %.% arrange(desc(total)) %.% head(5)
## 在R中试了一下上面的代码,显示报错如下,没有找到原因,在help里也搜索不到%.%函数,不晓得是不是dplyr包中这个函数已经取消了,如有问题,欢迎批评指正:
Batting %.%
+ group_by(playerID) %.%
+ summarise(total = sum(G)) %.%
+ arrange(desc(total)) %.%
+ head(5)
Error in Batting %.% group_by(playerID) %.% summarise(total = sum(G)) %.% :
could not find function "%.%"
? "%.%"
No documentation for ‘%.%’ in specified packages and libraries:
you could try ‘??%.%’
## 这样可以按进行数据处理时的思路写代码, 一步步深入, 既易写又易读, 接近于从左到右的自然语言顺序, 对比一下用R自带函数实现的
head(arrange(summarise(group_by(Batting, playerID), total = sum(G)) , desc(total)), 5)
## 或者像下面方法
totals <- aggregate(. ~ playerID, data=Batting[,c("playerID","R")], sum)
ranks <- sort.list(-totals$R)totals[ranks[1:5],]
## 文章里还表示: 用他的 MacBook Air 跑 %.% 那段代码用了 0.036 秒, 跑上面这段代码则用了 0.266 秒, 运算速度提升了近7倍. (当然这只是一例, 还有其它更大的数字.)
**************** 感想 ****************************************************************************
可以看到, 用 dplyr 所含函数实现的代码都要简洁易读得多, 说到底, R语言只是一个工具, 作为工具, 就是要拿来用的, 越称手越便利越简洁越好, 反思之下,
本人也是将大把的时间花在了对数据的反复调整上, 或许是手生, 当然R语言在这方面也确实有一定不足, 大神又说了:
数据分析有两个瓶颈,一是我们的目标是什么,二是我们如何用计算机去实现。我现有的很多作品,如 ggplot2,plyr
和 reshape2,更关注的是如何更简单地表达你的目标,而不是如何让计算机算得更快。
这种内在的理念正是要将工具工具化, 把无谓的时间减少, 让精力用在真正需要考虑的地方. 正如 Vim 一样, 在投入一定的学习成本后,
继续用继续学, 不知不觉地就能心手如一, 想做什么, 就已经按下去了, 从而更多地思考要编辑什么, 而不必纠结于光标移动选择等细节. 这其中的巧妙之处在于: 实现过程要以人脑的思维运作方式为标准, 让工具来适应人, 以实现目的为导向, ggplot2 的图形图层语法也是如此. 不管是软件也好, 编程语言也好, 高效的方法都是相通的, 这也正是许多人努力的方向, 另外平素语出惊人的王垠最近也表达了类似观点.
深入学习
暂时没有太多的相关资料, 如欲进一步学习, 可参阅:
dplyr 包自带的60页详细文档
其余几个vignettes (网页) 或 vignette(package = "dplyr") , 包含了数据库相关,
混合编程, 运算性能比较, 以及新的 window-functions 等内容.
简单看了下vignette("window-functions", package = "dplyr"), 提供了一系列函数, 扩展了原来只能返回一个数值的聚焦类函数(如sum(), mean())至返回等长度的值, 变成 cumsum()和 cummean(), 以及 n(), lead() 和 lag()等便捷功能.
plyr 包的相关文档
还有 data.table 包也是很强大的哦, 空下来可以学一学
就在 Feedly 订阅里看到 RStudio
Blog 介绍 dplyr 包已发布 (Introducing
dplyr), 此包将原本 plyr 包中的 ddply()
等函数进一步分离强化, 专注接受dataframe对象, 大幅提高了速度,
并且提供了更稳健的与其它数据库对象间的接口。
0.1 安装
install.packages("dplyr")
0.2 示范数据
library(Lahman) : Lahman 包里的棒球比赛数据集
Batting
library(hflights) : hflights 包里的飞机航班数据
0.3 数据集类型
## 将过长过大的数据集转换为显示更友好的 tbl_df 类型:
hflights_df <- tbl_df(hflights)
## 可以 hflights_df 感受一下不再被刷屏的感觉.
1 基本操作
把常用的数据操作行为归纳为以下五种:
1.1 筛选: filter()
按给定的逻辑判断筛选出符合要求的子数据集, 类似于base::subset()
函数
例如:
filter(hflights_df, Month == 1, DayofMonth == 1)
## 用R自带函数实现:
hflights[hflights$Month == 1 & hflights$DayofMonth
== 1, ] ;
除了代码简洁外, 还支持对同一对象的任意个条件组合, 如:
filter(hflights_df, Month == 1 | Month == 2)
## 注意: 表示 AND 时要使用&
而避免 &&
1.2 排列: arrange()
按给定的列名依次对行进行排序.
例如:
arrange(hflights_df, DayofMonth, Month, Year)
对列名加 desc() 进行倒序:
arrange(hflights_df, desc(ArrDelay))
## 这个函数和 plyr::arrange() 是一样的, 类似于 order()
## 用R自带函数实现:
hflights[order(hflights$DayofMonth,hflights$Month, hflights$Year),] ;
hflights[order(desc(hflights$ArrDelay)), ] ;
1.3 选择: select()
用列名作参数来选择子数据集:
select(hflights_df, Year, Month, DayOfWeek)
还可以用 :来连接列名, 没错, 就是把列名当作数字一样使用
select(hflights_df, Year : DayOfWeek)
## 选择从Year列(第一列)到DayOfWeek列(第四列)
用 - 来排除列名:
select(hflights_df, -(Year : DayOfWeek))
## 减号后面的列将不会被选择
同样类似于R自带的
subset() 函数 (但不用再写一长串的 c("colname1", "colname2") 或者 which(colname(data) == "colname3"), 甚至还要去查找列号)
1.4 变形: mutate()
对已有列进行数据运算并添加为新列:
mutate(hflights_df, gain = ArrDelay - DepDelay, speed = Distance / AirTime * 60)
## 作用与 plyr::mutate() 相同, 与 base::transform() 相似,优势在于可以在同一语句中对刚增加的列进行操作
mutate(hflights_df, gain = ArrDelay - DepDelay, gain_per_hour = gain / (AirTime / 60))
## 而同样操作用R自带函数 transform() 的话就会报错
transform(hflights, gain = ArrDelay - DepDelay, gain_per_hour = gain / (AirTime / 60))1.5
汇总: summarise()
对数据框调用其它函数进行汇总操作, 返回一维的结果:
summarise(hflights_df, delay = mean(DepDelay, na.rm = TRUE))
## 该函数功能尚不是非常有用
2 分组动作 group_by()
以上5个动词函数已经很方便了,
但是当它们跟分组操作这个概念结合起来时, 那才叫真正的强大!
当对数据集通过
group_by() 添加了分组信息后,mutate(),arrange()
和summarise() 函数会自动对这些 tbl 类数据执行分组操作 (R语言泛型函数的优势).
例如: 对飞机航班数据按飞机编号
(TailNum) 进行分组, 计算该飞机航班的次数 (count = n()), 平均飞行距离 (dist = mean(Distance, na.rm = TRUE)) 和 延时 (delay = mean(ArrDelay, na.rm = TRUE)) .
planes <- group_by(hflights_df, TailNum);
delay <- summarise(planes, count = n(), dist = mean(Distance, na.rm = TRUE), delay = mean(ArrDelay, na.rm = TRUE));
delay <- filter(delay, count > 20, dist < 2000);
## 用 ggplot2 包作个图观察一下, 发现飞机延时不延时跟飞行距离没太大相关性
ggplot(delay, aes(dist, delay)) + geom_point(aes(size = count), alpha = 1/2) + geom_smooth() + scale_size_area()
## 更多例子见 vignette("introduction", package = "dplyr")
另: 一些汇总时的小函数
n(): 计算个数
n_distinct(): 计算 x 中唯一值的个数. (原文为 count_distinct(x), 测试无用)
first(x), last(x) 和 nth(x, n): 返回对应秩的值, 类似于自带函数 x[1], x[length(x)], 和 x
## 注意: 分组计算得到的统计量要清楚样本已经发生了变化, 此时的中位数是不可靠的
3连接符 %.%
包里还新引进了一个操作符, 使用时把数据名作为开头, 然后依次对此数据进行多步操作.
Batting %.% group_by(playerID) %.% summarise(total = sum(G)) %.% arrange(desc(total)) %.% head(5)
## 在R中试了一下上面的代码,显示报错如下,没有找到原因,在help里也搜索不到%.%函数,不晓得是不是dplyr包中这个函数已经取消了,如有问题,欢迎批评指正:
Batting %.%
+ group_by(playerID) %.%
+ summarise(total = sum(G)) %.%
+ arrange(desc(total)) %.%
+ head(5)
Error in Batting %.% group_by(playerID) %.% summarise(total = sum(G)) %.% :
could not find function "%.%"
? "%.%"
No documentation for ‘%.%’ in specified packages and libraries:
you could try ‘??%.%’
## 这样可以按进行数据处理时的思路写代码, 一步步深入, 既易写又易读, 接近于从左到右的自然语言顺序, 对比一下用R自带函数实现的
head(arrange(summarise(group_by(Batting, playerID), total = sum(G)) , desc(total)), 5)
## 或者像下面方法
totals <- aggregate(. ~ playerID, data=Batting[,c("playerID","R")], sum)
ranks <- sort.list(-totals$R)totals[ranks[1:5],]
## 文章里还表示: 用他的 MacBook Air 跑 %.% 那段代码用了 0.036 秒, 跑上面这段代码则用了 0.266 秒, 运算速度提升了近7倍. (当然这只是一例, 还有其它更大的数字.)
**************** 感想 ****************************************************************************
可以看到, 用 dplyr 所含函数实现的代码都要简洁易读得多, 说到底, R语言只是一个工具, 作为工具, 就是要拿来用的, 越称手越便利越简洁越好, 反思之下,
本人也是将大把的时间花在了对数据的反复调整上, 或许是手生, 当然R语言在这方面也确实有一定不足, 大神又说了:
数据分析有两个瓶颈,一是我们的目标是什么,二是我们如何用计算机去实现。我现有的很多作品,如 ggplot2,plyr
和 reshape2,更关注的是如何更简单地表达你的目标,而不是如何让计算机算得更快。
这种内在的理念正是要将工具工具化, 把无谓的时间减少, 让精力用在真正需要考虑的地方. 正如 Vim 一样, 在投入一定的学习成本后,
继续用继续学, 不知不觉地就能心手如一, 想做什么, 就已经按下去了, 从而更多地思考要编辑什么, 而不必纠结于光标移动选择等细节. 这其中的巧妙之处在于: 实现过程要以人脑的思维运作方式为标准, 让工具来适应人, 以实现目的为导向, ggplot2 的图形图层语法也是如此. 不管是软件也好, 编程语言也好, 高效的方法都是相通的, 这也正是许多人努力的方向, 另外平素语出惊人的王垠最近也表达了类似观点.
深入学习
暂时没有太多的相关资料, 如欲进一步学习, 可参阅:
dplyr 包自带的60页详细文档
其余几个vignettes (网页) 或 vignette(package = "dplyr") , 包含了数据库相关,
混合编程, 运算性能比较, 以及新的 window-functions 等内容.
简单看了下vignette("window-functions", package = "dplyr"), 提供了一系列函数, 扩展了原来只能返回一个数值的聚焦类函数(如sum(), mean())至返回等长度的值, 变成 cumsum()和 cummean(), 以及 n(), lead() 和 lag()等便捷功能.
plyr 包的相关文档
还有 data.table 包也是很强大的哦, 空下来可以学一学
相关文章推荐
- 【转载】R语言扩展包dplyr笔记
- JavaScript 学习笔记之二:编写自己的jQuery扩展分页插件(分享yQuery)
- 【转载】R语言与数据挖掘学习笔记
- R第五问 R语言扩展包dplyr笔记
- R语言扩展包dplyr笔记
- 『应用机器学习的建议』的学习笔记 2015/04/12 · IT技术 · 机器学习 分享到: 45 本文由 伯乐在线 - mathshelly 翻译,toolate 校稿。未经许可,禁止转载! 英
- R语言扩展包dplyr笔记
- R语言扩展包dplyr笔记
- 【转载】windows phone7 学习笔记14——地理位置服务与反应性扩展框架
- R语言扩展包dplyr笔记
- Objective-C 学习笔记3 类的扩展(category)
- 应用统计学与R语言实现学习笔记(八)——方差分析
- R语言可视化学习笔记之ggrepel包
- ASP.Net MVC开发基础学习笔记(2):HtmlHelper与扩展方法
- R语言学习笔记:分析学生的考试成绩
- 【转载】ASP.NET MVC Web API 学习笔记---联系人增删改查
- [原]Java程序员的JavaScript学习笔记(12——jQuery-扩展选择器)
- 英语学习经验分享——转载
- 分布式架构系统学习笔记(七)-系统可扩展架构
- python学习笔记三之深浅copy,扩展数据类型(基础篇)