1
什么是管道操作?
举个栗子
#以R自带的iris数据为例
pacman::p_load(tidyverse, magrittr)
data <- iris
#顺序写法
data <- filter(data, Sepal.Length > 7) #筛选Sepal.Length > 7的行
data <- select(data, -Species) #剔除Species列
data <- map_df(data, mean) #求所有列均值
#函数嵌套写法
data <- map_df(select(filter(data, Sepal.Length > 7), -Species), mean)
#管道符写法
data %>%
filter(Sepal.Length > 7) %>% #筛选Sepal.Length > 7的行
select(-Species) %>% #剔除Species列
map_df(mean) #求所有列均值
几种写法的比较
普通顺序写法下data变量被声明了6次,并每次都需要对data重新赋值。函数嵌套写法下data虽然被声明了2次,但其逻辑复杂,同时很难对指定函数去注释。
管道符写法下data变量仅被声明1次,同时计算逻辑按行排列层层递进,更方便添加注释。
2
管道操作符讲解
1
%>% - 向右操作符
data %>%
filter(Sepal.Length > 7) %>% #筛选Sepal.Length > 7的行
select(-Species) %>% #剔除Species列
map_df(mean) #求所有列均值
# A tibble: 1 x 4
Sepal.Length Sepal.Width Petal.Length Petal.Width
<dbl> <dbl> <dbl> <dbl>
1 7.48 3.12 6.3 2.05
#把左侧准备的数据或表达式,传递给右侧的函数调用或表达式进行运行
2
%T>% - 向左操作符
data %>%
filter(Sepal.Length > 7) %>%
select(-Species) %T>% #在这里!!!
print() %>%
map_df(mean)
Sepal.Length Sepal.Width Petal.Length Petal.Width
1 7.1 3.0 5.9 2.1
2 7.6 3.0 6.6 2.1
3 7.3 2.9 6.3 1.8
4 7.2 3.6 6.1 2.5
5 7.7 3.8 6.7 2.2
6 7.7 2.6 6.9 2.3
7 7.7 2.8 6.7 2.0
8 7.2 3.2 6.0 1.8
9 7.2 3.0 5.8 1.6
10 7.4 2.8 6.1 1.9
11 7.9 3.8 6.4 2.0
12 7.7 3.0 6.1 2.3
# A tibble: 1 x 4
Sepal.Length Sepal.Width Petal.Length Petal.Width
<dbl> <dbl> <dbl> <dbl>
1 7.48 3.12 6.3 2.05
#插入到链条中的单独事件,不影响后续链条(运行并跳过)
#这里的 %T>% print() 可以理解为:
在对print函数的上一个函数的结果做print输出的同时
print函数的下一个函数代入值print的上一个函数的结果
3
%$% - 解释操作符
iris %$%
str_detect(Species, "a") #查看iris内Species变量中每行是否包含“a”字符
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[20] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[39] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[58] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[77] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[96] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[115] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[134] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#把左侧数据的变量名传给右侧,让右侧的调用函数直接通过变量名,就可以获取左侧的数据中对应的变量
4
%<>% - 复合赋值操作符
data %<>%
filter(Sepal.Length > 7) %>%
select(-Species) %>%
map_df(mean)
> data
# A tibble: 1 x 4
Sepal.Length Sepal.Width Petal.Length Petal.Width
<dbl> <dbl> <dbl> <dbl>
1 7.48 3.12 6.3 2.05
# 将后续链条的结果回馈赋值给 %<>% 前的变量
### %<>% 必须要用在第一个管道的对象处,才能完成赋值的操作,如果不是左侧第一个位置,那么赋值将不起作用
最后
管道操作符的使用,大幅度简化了代码复杂度的同时可以减少不必要的内存消耗。
祝大家在管道中happy coding
·END·
R语言与数据分析
生产力干货
微信号:RforData