【R数据科学 第13章】使用magrittr进行管道操作

1.简介

管道是一种强大的工具,可以清楚地表示由多个操作组成的一个操作序列。管道 %>% 来自于 Stefan Milton Bache 开发的 magrittr 包。因为 tidyverse 中的包会自动加载 %>%,所以通常你无须显式地加载 magrittr。不加载任何R包的话要library(magrittr)

2.管道

1.R会尽量在是数据框之间共享数据列。

ggplot2::diamonds

dplyr::mutate  # 包::函数,指定要的是哪个包里的函数,防止冲突

有关问题可以看这个:别人运行的好好的R代码,到我这怎么就冲突了?

                  还有这个:R语言中这些你想知道含义又不知道怎么查的特殊符号

pryr::object_size(diamonds)

2.管道优于中间步骤

#函数组合
bop( scoop(hop(foo_foo, through = forest),up = field_mice), on = head )

#管道
foo_foo %>%
    hop(through = forest) %>%
    scoop(up = field_mouse) %>%
    bop(on = head)

       

管道的工作原理就是进行“词法变换”。在这种方式背后,magrittr 会重新组合管道代码, 按照重写中间变量的方式来运行。当执行以上示例中的管道操作时,实际上 magrittr 执行 的是类似以下的代码:
 

   my_pipe <- function(.) {
       . <- hop(., through = forest)
       . <- scoop(., up = field_mice)
       bop(., on = head)
     }
     my_pipe(foo_foo)   

这意味着管道不能支持以下两类函数。

• 使用当前环境的函数

例如,assign() 函数会在当前环境中使用给定名称创建一个新变量:

assign("x", 10) 
#> [1] 10
"x" %>% assign(100)  

assign() 函数会在当前环境中使用给定名称创建一个新变量,而管道赋值操作是在由%>%建立的一个临时环境中进行的。如果要通过管道方式来使用assign(),必须显式地指定环境。

env <- environment()
"x" %>% assign(100, envir = env)

environment表示assign代表的当前环境,而不是管道创建的临时环境。 

get(),load()也存在同样的问题


• 使用惰性求值的函数

在 R 中,不会在函数调用前计算这种函数的参数,只在函数使用时才进行计算。管道依次计算每个参数,因此不能用在这种函数上。

try、suppressMessages、suppressWarnings、tryCatch

3.不适合使用管道的情形

不适合使用管道的情形

• 操作步骤超过 10(参考值)个。这种情况下,应该使用有意义的变量来保存中间结果。 这样会使得调试更加容易,因为你更容易检查中间结果;还可以使得代码更容易理解, 因为有意义的变量名称可以帮助别人明白你的代码意图。


• 有多个输入和输出。如果需要处理的不是一个基本对象,而是组合在一起的两个或多个 对象,就不要使用管道。

• 操作步骤构成一张具有复杂依赖关系的有向图。管道基本上是一种线性操作,如果使用 它来表示复杂的关系,通常会使得代码混乱不清。

4.magrittr中的其他工具

在使用比较复杂的管道操作时,有时会因为某个函数的副作用而调用它。比如,你可能 想要打印或绘制出当前对象,或者想将它保存在硬盘中。很多时候这种函数不会返回任何结果,只会有效地结束管道操作。

为了解决这个问题,你可以使用“T”管道操作符 %T>%。它的用法和 %>% 差不多,只是它返回的是左侧项而不是右侧项。之所以称它为“T”操作符,是因为它起的作用类似于 T 形三通管道。

如果使用的函数不是基于数据框的(也就是说,你必须传给这些函数一个独立的向量, 不能传给它们数据框或基于数据框求值的表达式),那么你就会发现爆炸操作符 %$% 的 妙处。它可以将数据框中的变量“炸出来”,让你显式地引用。当需要使用 R 基础包中 的很多函数时,这个操作符特别奏效。

magrittr 提供了 %<>% 操作符来执行赋值操作,它可以将以下代码: mtcars <- mtcars %>%
transform(cyl = cyl * 2) 替代为
     mtcars %<>% transform(cyl = cyl * 2)

%$%传递的不是前一行的输出结果本身,而是输出数据框的列名,可以允许后一行代码直接根据列名调用相应的数据。

%T>%会接受前一行的输出结果,但不会把自己的输出结果传入下一行,如果下一行继续使用%>%进行参数传递,那么传递进去的参数仍然是%T>%前一行的输出结果。

%T>%后的一个语句的结果不能以“文本”的形式输出出来,因此后面接的通常是绘图、导出数据等操作,并且这项操作并不会影响后面的语句继续继承%T>%前面语句的输出结果作为参数。

我们是在使用boxplot()观察了data中数据的分布状态后再决定了限制生成随机数的最小值和最大值,而不是直接使用boxplot()的输出结果,也就是中间出现了“停顿”,这时就可以使用%T>%进行改写:


library(magrittr)
mtcars %>%
pluck(1) %T>%
boxplot() %>%
length() %>%
runif(min = 10, max = 35)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

看星星的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值