magrittr管道操作符使用解释(一)
使用管道操作符提高代码简洁性
在编写R语言代码时,有时候需要对一个变量进行一系列的运算,例如对于一个同时包含数值列和字符串列的数据框,如果要计算所有数值列之间的相关系数,一般要分两步,第一步首先筛选数据框中的数值列,第二步计算数值列之间的相关系数。
x=data.frame(x1=c(1,34,22),x2=c(4,6,29),x3=c('a','b','c'))
- 1
假设我们需要计算上数据框x中数值列的相关系数,通常有两种做法:
- 分步进行
x_num=x[,unlist(lapply(x,function(i){is.numeric(i)==TRUE}))]
cor(x_num)
- 1
- 2
## x1 x2
## x1 1.0000000 0.2262448
## x2 0.2262448 1.0000000
- 1
- 2
- 3
在分步进行的方法中,我们需要保存每一步产生的中间结果,用于下一步的计算,对于包含多步骤连续运算的计算问题,分步进行将会变得非常繁琐。
- 嵌套函数
cor(x[,unlist(lapply(x,function(i){is.numeric(i)==TRUE}))])
- 1
## x1 x2
## x1 1.0000000 0.2262448
## x2 0.2262448 1.0000000
- 1
- 2
- 3
以上展示了嵌套函数的写法,嵌套函数通过逐层向外扩充表示对数据进行从内到外的不断依次计算,通常对于一两步连续运算,嵌套函数的写法还可以接受,但是超过三步的运算,如果不断向外嵌套,对于他人阅读理解代码以及代码的整洁性是非常不理想的,此外,嵌套写法不利于代码的修改。
以上两种写法是初学者在学习R语言执行多步计算时经常采用的写法,一种更为简洁明了、便于维护的写作方式便是今天讲的管道操作符。如果有人之前用过dplyrdplyr这个程序包,想必已经对于管道操作符的高效有了一定的了解和掌握。事实上,dplyrdplyr中管道符的实现是依赖于另一个函数包magrittrmagrittr,此处主要讲解该软件包中对于管道操作符的一些常用用法。
magrittrmagrittr包含四种管道操作符”%>%”,”%T>%”,”%<>%”,”%$%”,其中最重要最常用的是第一个”%>%”操作符。管道操作符是通过一种流程式的书写方式来表达一系列依次进行的运算操作,逻辑清晰且书写简便,下面通过一系列实际例子讲解管道操作符”%>%”的使用。
管道操作符”%>%”的基本用法
library(magrittr)
x[,unlist(lapply(x,function(i){is.numeric(i)==TRUE}))]%>%cor()
- 1
- 2
## x1 x2
## x1 1.0000000 0.2262448
## x2 0.2262448 1.0000000
- 1
- 2
- 3
注意到上式中管道操作符的写法”%>%cor()”,事实上,管道操作符的实质就是将左边表达式(前一步运算)返回的结果默认地传给后续要执行的函数,因此管道操作符的实质可以用如下表达式清晰地表示为:
管道操作符:x%>%f1()%>%f2()
嵌套表达式:f2(f1(x))
分步书写: res_1=x
res_2=f1(res_1)
res_3=f2(res_2)
- 1
- 2
- 3
- 4
- 5
可以看出,使用管道操作符具有逻辑清晰,书写方便的优点,此外管道操作符的表达方式允许我们方便地增加或删除其中一步的运算。
管道操作符中‘.’号的用法
在使用管道操作符时,默认地实际上是将左边表达式的结果作为右边函数的第一个参数传入的,如果右边函数只有一个参数,那自然无需考虑,但对于右边函数有多个参数,我们并不希望表达式的结果作为第一个参数时,就需要考虑更换默认的参数位置了。如何更换呢?这就需要了解‘.’在管道操作符中的用法。‘.’表达的即是左边表达式返回的结果,请观察下例:
x[,unlist(lapply(x,function(i){is.numeric(i)==TRUE}))]%>%cor(.)
- 1
## x1 x2
## x1 1.0000000 0.2262448
## x2 0.2262448 1.0000000
- 1
- 2
- 3
注意到,在右边函数中有一个‘.’,这表示的即是左边筛选的数据框结果,对于右边函数只有一个参数或者只需要将表达式作为第一个参数传入的情形,我们可以不用显示地将这个‘.’号写出来,但对于需要更改表达式结果作为函数其他位置的参数或者需要将表达式结果的其他形式作为函数参数的情形,则需要使用‘.’号来显示地表达上一表达式返回的结果。下面通过实例分别讲解这两种情况:
– 将表达式结果作为其他位置的参数传入
假设需要通过sum函数计算一系列向量的和,通常我们会制定na.rm参数来设定是否忽略缺失值。如果我们需要根据前面表达式的结果(TRUE or FALSE)来决定是否忽略缺失值NA,便会遇到一个问题,na.rm参数并不是sum函数的第一个参数,为了正确地执行,我们需要修改表达式参数的默认位置,这一需求便可通过‘.’来实现
TRUE%>%sum(c(1,2,3,NA),na.rm = .)
- 1
## [1] 6
- 1
可以看到,通过显示地制定‘.’的位置,我们可以更改参数的默认位置,‘.’号可以在函数中出现在任意多次任意位置,表示其他参数设定需要依赖该结果。
– 将表达式结果的其他形式作为函数参数
第二种用法实际上和第一种用法是一致的,在此单一列出只是为了更清楚的展示。借助tidyr中的fill函数来说明这一用法。tidyr中的fill函数可以用来根据前一行的值填充后一行的缺失值。
x=data.frame(x1=c(1,NA,3),x2=c(12.3,34,NA))
x
- 1
- 2
## x1 x2
## 1 1 12.3
## 2 NA 34.0
## 3 3 NA
- 1
- 2
- 3
- 4
这种填充缺失值的方法对于一系列时间上连续的采样样本应用较为合适。使用tidyr时,需要指定哪一列需要填充,如果我们需要填充函数的所有列,则需要在传入所有的列名称。由于列名称是数据框的某一属性,因此此时我们的函数既需要表达式的结果(即数据框)作为函数的第一个参数,又需要表达式结果的其他属性或者变形作为函数的另外参数,这一问题的解决可以依靠‘.’号来实现。
library(tidyr)
x%>%fill(names(.))
- 1
- 2
## x1 x2
## 1 1 12.3
## 2 1 34.0
## 3 3 34.0
- 1
- 2
- 3
- 4
更为具体的,可以写成
x%>%fill(.,names(.))
- 1
## x1 x2
## 1 1 12.3
## 2 1 34.0
## 3 3 34.0
- 1
- 2
- 3
- 4
以上便是‘.’号的用法。
magrittr管道操作符使用解释(一)的更多相关文章
- R语言中的管道操作符 %>% %T>% %$% %<>%
magrittr 包的官网 https://magrittr.tidyverse.org/ magrittr 包的 github 主页 https://github.com/tidyverse/mag ...
- Linux - 命令行 管道(Pipelines) 详细解释
命令行 管道(Pipelines) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24249529 管道操作符" ...
- Linux - 命令行 管道(Pipelines) 具体解释
命令行 管道(Pipelines) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24249529 管道操作符" ...
- MongoDB入门---聚合操作&管道操作符&索引的使用
经过前段时间的学习呢,我们对MongoDB有了一个大概的了解,接下来就要开始使用稍稍深入一点的东西了,首先呢,就是MongoDB中的聚合函数,跟mysql中的count等函数差不多.话不多说哈,我们先 ...
- SQL Server 运行计划操作符具体解释(2)——串联(Concatenation )
本文接上文:SQL Server 运行计划操作符具体解释(1)--断言(Assert) 前言: 依据计划.本文開始讲述另外一个操作符串联(Concatenation).读者能够依据这个词(中英文均可) ...
- SQL Server 运行计划操作符具体解释(3)——计算标量(Compute Scalar)
接上文:SQL Server 运行计划操作符详细解释(2)--串联(Concatenation ) 前言: 前面两篇文章介绍了关于串联(Concatenation)和断言(Assert)操作符,本文介 ...
- (数据科学学习手札144)使用管道操作符高效书写Python代码
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,一些比较熟悉pandas的读者 ...
- SQL Server 运行计划操作符具体解释(1)——断言(Assert)
前言: 非常多非常多地方对于语句的优化,一般比較靠谱的回复即使--把运行计划发出来看看.当然那些仅仅看语句就说怎样怎样改代码,我一直都是拒绝的,由于这样的算是纯蒙.依据本人经验,大量的性能问题单纯从语 ...
- RxJava系列之二 变换类操作符具体解释1
1.回想 上一篇文章我们主要介绍了RxJava , RxJava 的Observables和 RxJava的just操作符.以及RxJava一些经常使用的操作. 没看过的抓紧点我去看吧. 事实上RxJ ...
随机推荐
- golang学习笔记9 beego nginx 部署 nginx 反向代理 golang web
golang学习笔记9 beego nginx 部署 nginx 反向代理 golang web Nginx 部署 - beego: 简约 & 强大并存的 Go 应用框架https://bee ...
- QPointer,QSharedPointer,QWeakPointer的区别
QPointer,QSharedPointer,QWeakPointer的区别与使用例子(QSharedPointer类似Delphi里的引用计数,是强引用,而QWeakPointer是弱引用,不影响 ...
- python 图片
- 需求中碰到的简单Map集合 key相同合并 value的思路
从两个接口获取到了数据Map集合, 但是要展示到同一页面 根据了播控人为key 将两个返回的进行遍历 将他们存在新的map里面 只有单个key value 就存为(MAP<object,obje ...
- C++ 开源库列表
https://zh.cppreference.com/w/cpp/links/libs
- The logback manual #01# Introduction
依赖包如下pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...
- win10常见问题处理办法
1.当笔记本连接wifi时,提示,无internet,安全,而手机能正常连接wifi时: cmd(需管理员权限)执行命令 netsh winsock reset 出现已重置,重启电脑 解决方法 2.当 ...
- JavaWeb中的资源映射
一./与/* <url-pattern>/</url-pattern> 会匹配到/login这样的路径型url,不会匹配到模式为*.jsp这样的后缀型url< url- ...
- Java能抵挡住JavaScript的进攻吗?
JavaScript的进攻 公元2014年,Java 第八代国王终于登上了王位. 第一次早朝,国王坐在高高的宝座上,看着毕恭毕敬的大臣,第一次体会到了皇权的威力. 德高望重的IO大臣颤悠悠地走上前来: ...
- 01:CENTOS使用VIRTUALENV搭建独立的PYTHON环境-PYTHON虚拟环境
1.1 安装virtualenv环境 https://www.cnblogs.com/liuyansheng/p/6141197.html 1.安装virtualenv yum install pyt ...