R语言扩展包dplyr笔记
引言
2014年刚到, 就在 Feedly 订阅里看到 RStudio Blog 介绍 dplyr 包已发布 (Introducing dplyr), 此包将原本 plyr 包中的 ddply() 等函数进一步分离强化, 专注接受dataframe对象, 大幅提高了速度, 并且提供了更稳健的与其它数据库对象间的接口. 既然是 Hadley Wickham 的新作, 并自称 a grammar of data manipulation, 当然要先学为快了, 正好新申了域名, 就把原本记在 Rmd 里的笔记组织一下, 放在这里, 算是个简短的教程吧, 仅供入门.
正文: 学习笔记
以下内容主要参照 Introducing dplyr 和 dplyr 包自带的简介 (Introduction to dplyr), 复制了原文对应代码, 并夹杂了个人理解和观点 (多附于括号内).
0 初始化
0.1 安装
install.packages("dplyr")
0.2 示范数据
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)
用 - 来排除列名:
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))
等同于 plyr::summarise(), 原文说该函数功能尚不是非常有用, 大概以后的更新会加强吧.
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[n]
注意: 分组计算得到的统计量要清楚样本已经发生了变化, 此时的中位数是不可靠的
3 连接符 %.%
包里还新引进了一个操作符, 使用时把数据名作为开头, 然后依次对此数据进行多步操作.
比如:
Batting %.%
group_by(playerID) %.%
summarise(total = sum(G)) %.%
arrange(desc(total)) %.%
head(5)
这样可以按进行数据处理时的思路写代码, 一步步深入, 既易写又易读, 接近于从左到右的自然语言顺序, 对比一下用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倍. (当然这只是一例, 还有其它更大的数字.)
更多请 ?"%.%", 至于这个新鲜的概念会不会和 ggplot2 里的 + 连接号一样, 发挥出种种奇妙的功能呢? 还是在实际使用中多体验感受吧.
感想
可以看到, 用 dplyr 所含函数实现的代码都要简洁易读得多, 说到底, R语言只是一个工具, 作为工具, 就是要拿来用的, 越称手越便利越简洁越好, 可是, 正如 Hadley Wickham 在2013年的访谈中提到的那样:
如果你用了8小时进行数据清理和数据整理,而只用了2小时进行建模,那么很明显,你希望了解如何将数据清理和整理的时间尽可能缩短。
反思之下, 本人也是将大把的时间花在了对数据的反复调整上, 或许是手生, 当然R语言在这方面也确实有一定不足, 大神又说了:
数据分析有两个瓶颈,一是我们的目标是什么,二是我们如何用计算机去实现。我现有的很多作品,如 ggplot2,plyr 和 reshape2,更关注的是如何更简单地表达你的目标,而不是如何让计算机算得更快。
这种内在的理念正是要将工具工具化, 把无谓的时间减少, 让精力用在真正需要考虑的地方. 正如 Vim 一样, 在投入一定的学习成本后, 继续用继续学, 不知不觉地就能心手如一, 想做什么, 就已经按下去了, 从而更多地思考要编辑什么, 而不必纠结于光标移动选择等细节. 这其中的巧妙之处在于: 实现过程要以人脑的思维运作方式为标准, 让工具来适应人, 以实现目的为导向, ggplot2 的图形图层语法也是如此. 不管是软件也好, 编程语言也好, 高效的方法都是相通的, 这也正是许多人努力的方向, 另外平素语出惊人的王垠最近也表达了类似观点.
顺便肖凯老师在网易云课堂新开的R语言初级教程里提到了十大必学R包的说法, 并把 plyr 列为之一, 有趣的是居然还有人在问答平台上求详情, 好奇之下放狗一搜, 原来出处在此 (脱水版), 其中 ggplot2 和 reshape2 是平时都有在用的, 还有实用的 knitr 和 Slidify , 其它就没什么发言权了.
深入学习
暂时没有太多的相关资料, 如欲进一步学习, 可参阅:
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笔记的更多相关文章
- R语言扩展包dplyr——数据清洗和整理
R语言扩展包dplyr——数据清洗和整理 标签: 数据R语言数据清洗数据整理 2015-01-22 18:04 7357人阅读 评论(0) 收藏 举报 分类: R Programming(11) ...
- R语言数据处理包dplyr、tidyr笔记
dplyr包是Hadley Wickham的新作,主要用于数据清洗和整理,该包专注dataframe数据格式,从而大幅提高了数据处理速度,并且提供了与其它数据库的接口:tidyr包的作者是Hadley ...
- 安装R语言扩展包diveRsity-1
今天去了学院的运动会呢-扮熊本熊超开心-写完这篇我补上我的图么么哒 ××××××××××××文末高能预警!!!!!这个包的安装并不是本周的任务!!!!!我真是萌萌哒×××××××××××××× ××× ...
- 安装R语言扩展包vegan
这周的作业我开始得好迟啊...然而还是要努力做啊... ××××××××××××××我是萌萌哒分割线×××××××××××××××××××××××××××××××××××× 首先,百度进入官方页面,看 ...
- R语言 ggplot2包
R语言 ggplot2包的学习 分析数据要做的第一件事情,就是观察它.对于每个变量,哪些值是最常见的?值域是大是小?是否有异常观测? ggplot2图形之基本语法: ggplot2的核心理念是将 ...
- R语言与机器学习学习笔记
人工神经网络(ANN),简称神经网络,是一种模仿生物神经网络的结构和功能的数学模型或计算模型.神经网络由大量的人工神经元联结进行计算.大多数情况下人工神经网络能在外界信息的基础上改变内部结构,是一种自 ...
- R语言函数化学习笔记3
R语言函数化学习笔记3 R语言常用的一些命令函数 1.getwd()查看当前R的工作目录 2.setwd()修改当前工作目录 3.str()可以输出指定对象的结构(类型,位置等),同理还有class( ...
- R语言函数化编程笔记1
R语言函数化编程笔记1 notes:有一个不错的网站叫做stack overflow,有问题可以从上面找或者搜索答案,会有大佬相助. 在github上面可以找到很多R的扩展包,如果自己额修改被接受,那 ...
- #r语言(二)笔记
#r语言(二)笔记 #早复习 #概述:R是用于统计分析.绘图的语言和操作环境 #对象: #数据类型--统称为对象 #向量(vector):用于存储数值型.字符型或逻辑型数据的一维数组. #定义向量: ...
随机推荐
- 仿京东左侧菜单 hover效果-简易demo
简单描述: 用到的知识点 css 中的绝对定位 以及 Js 中的事件冒泡(或事件委托) .cont{display:inline-block;width:200px;height:200px;bord ...
- 关于Andorid的RecyclerView在V7包下找不到的解决办法
关于Andorid的RecyclerView在V7包下找不到的解决办法 最近在学习使用RecyclerView替换现有的ListView,看了几篇文章.当准备自己动手实现的时候发现,V7包下找不到 ...
- GraphX实现N度关系
背景 本文给出了一个简单的计算图中每一个点的N度关系点集合的算法,也就是N跳关系. 之前通过官方文档学习和理解了一下GraphX的计算接口. N度关系 目标: 在N轮里.找到某一个点的N度关系的点集合 ...
- hdu 1213 How Many Tables(并查集求无向图有几个连通分量)
代码: #include<cstdio> #include<cstring> using namespace std; int n,m; int father[1005]; i ...
- [原创]JAVA技巧:去除ArrayList<Object>里面的重复记录
简单说明 ArrayList中保存的是某种类型的对象,如User,现在需要将对象属性userid重复的都去掉,使userid唯一,要如何处理? 实现步骤 代码如下方所示,实现一个Comparator的 ...
- linux内存管理之DMA
说起DMA我们并不陌生,但是实际编程中去用的人不多吧,最多就是网卡驱动里的环形buffer,再有就是设备的dma,下面我们就分析分析. DMA用来在设备内存和内存之间直接数据交互.而无需cpu干预 ...
- 如何让div在整个页面中居中?
参考必应主页的样式,在页面中放置一个表格,100%宽高,然后表格内部是一个单元格,在单元格内部放置div,使其margin为auto即可. <table style="height: ...
- 转载:Jmeter教程索引
摘自: 阳光温暖了心情 的 http://www.cnblogs.com/yangxia-test/category/431240.html 1 JMeter学习(一)工具简单介绍 2 JMeter学 ...
- WSAAsyncSelect 模型
WSAAsyncSelect模型是winsock编程模型的一种,它提供了socket异步编程的方便,其实现是基于Windows消息机制的,最主要的就是下面这个函数: int PASCAL FAR WS ...
- ARM获得PC指针为何PC=PC+8
http://blog.csdn.net/sddzycnqjn/article/details/7691534 R15(PC)总是指向“正在取指”的指令,而不是指向“正在执行”的指令或正在“译码”的指 ...