R语言管道符
R包
Package: magrittr介绍
- 一种高效的管道符操作工具包,让程序更加简洁和高效
- 主要包含4个常用的管道操作符
- %>% :向右操作符
- %T>% :向左操作符
- %$% :解释操作符(或者属性操作符)
- %<>% :复合赋值操作符
Package: magrittr安装
- install.packages(“magrittr”) # 安装
- library(magrittr) # 加载到当前环境
常用管道操作符的使用
向右操作符:%>%
- 原理:%>%左边的数据集或函数的结果(A)作为其右边函数(B)的第一个参数调用
# 设置随机种子
> set.seed(1)
# 开始
> rnorm(10000) %>%
+ abs %>% `*` (50) %>%
+ matrix(ncol=100) %>%
+ rowMeans %>% round %>%
+ `%%`(7) %>% hist
注意 :在链式操作中,运算符的使用方式,即使用的反引号 (`+`…);操作符的另一侧的数值使用了小括号 ()。
向左操作符:%T>%
- 原理:%T>%左侧的数据集或函数结果(A)作为右侧程序(函数)的第一个参数调用,B(程序)函数的结果数据集不再向右侧传递,而是把B左侧的A数据集(或函数结果)再次向右传递给C函数(作为第一个参数调用),最后完成数据计算。
rnorm(100) %>%
abs %>% `*` (50) %>%
matrix(ncol = 10) %>%
rowMeans %>%
round %>% `%%`(7) %T>% hist %>% sum
注释 :如果不适用 %T>% 操作符,即将hist绘图函数的结果传递给sum求和函数,进而引起错误
解释操作符(属性操作符):%$%
- 原理: %$% 把左侧数据集或函数结果(A)和属性名传给右侧程序或函数,而右侧的调用函数(或程序)直接通过属性名,获取左侧的数据子集。(与with函数存在相似的操作)
> data.frame(x = 1:10, y = rnorm(10), z = letters[1:10]) %$% .[which(x>5),]
x y z
6 6 0.16542301 f
7 7 -1.02208005 g
8 8 0.24783685 h
9 9 -0.42270195 i
10 10 0.02309803 j
> with(df, df[x >5,])
x y z
6 6 -1.01704356 f
7 7 0.23781779 g
8 8 1.43178677 h
9 9 -0.09676528 i
10 10 1.44733223 j
注释 : %$% 右侧的程序(或表达式)比较简洁(其实有点难理解),注意其表达式的 .[which(x>5),] 中中括号左侧有一个 逗号 存在;在 with 函数看起来比较好理解一些。
复合赋值操作符:%<>%
- 原理: %<>% 左侧的数据集或函数结果(A)作为右侧程序或函数的第一个参数调用,B程序或函数的结果数据集再向右侧传递给C函数(作为第一个参数调用),C程序或函数结果的数据集再 重新赋值 给A。
> x <- rnorm(100)
> x %<>% abs %>% sort %>% head
> x
[1] 0.02691459 0.03228899 0.04407453 0.05887155 0.06854365 0.08183674
注释 :(1) %<>% 只能放在表达式的第一个位置;(2)不能与复制运算符在同一个命令行中;(3)替换原始数据。
magrittr包扩展功能
符号操作符定义
magrittr对于常见的运算操作符进行的重新定义,让每个操作都对应用一个函数,这样所有的传递调用代码都是风格统一的。比如,add()函数和 “ `+` ” 是等价的。
在R中存在的一一对应关系如下
function | expression |
---|---|
extract | |
extract2 | `[[` |
inset | `[<-` |
inset2 | `[[<-` |
use_series | `$` |
add | `+` |
subtract | `-` |
multiply_by | `*` |
raise_to_power | `^` |
multiply_by_matrix | `%*%` |
divide_by | `/` |
divide_by_int | `%/%` |
mod | `%%` |
is_in | `%in%` |
and | `&` |
or | ` |
equals | `==` |
is_greater_than | `>` |
is_weakly_greater_than | `>=` |
is_less_than | `<` |
is_weakly_less_than | `<=` |
not (`n’est pas`) | `!` |
set_colnames | `colnames<-` |
set_rownames | `rownames<-` |
set_names | `names<-` |
示例操作,如下。
> rnorm(10) %>% `+`(10) %>% `/`(2)
[1] 5.114692 5.446174 5.009711 5.209725 5.176904 4.684421 5.055513 4.630852 4.123256 4.689387
> rnorm(10) %>% add(10) %>% divide_by(2)
[1] 4.530785 4.036988 4.942378 4.591788 4.861108 5.243556 4.951784 5.322956 5.524302 5.217512
%>%传递至代码块
当对 %>% 左侧数据集或函数结果进行多次处理时,需要一个代码块来进行处理。把数据集传递到 {} 代码块中,传入的数据集以点号( . ) 来表示,通过一段代码来完成操作。
> rnorm(100) %>%
+ multiply_by(5) %>%
+ add(5) %>%
+ {
+ cat("mean: ", mean(.),
+ "var: ", var(.), "\n")
+ x <- sort(.) %>% head
+ }
mean: 4.780373 var: 25.52519
> x
[1] 0.125 0.375 0.750 1.250 2.125
通过 {} 包装的代码块,可以很方便的完成执行多次处理的复杂操作。还可以在代码块中进行赋值,以保存数据。
%>% 传递到函数
传递到函数和传递到代码块设计是类似的,把一个数据集或左侧函数或程序输出结果传给一个 匿名函数 ( 此匿名函数用小括号包含 ),进行复杂的数据操作。
比如,对鸢尾花数据集进行处理,只保留第一行和最后一行作为结果。
> iris %>% (
+ function(x){
+ if (nrow(x) > 2)
+ rbind(head(x,1), tail(x,1))
+ else
+ x
+ }
+ )
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
150 5.9 3.0 5.1 1.8 virginica
致谢:毛里里求斯的整理和分享