我应该避免使用管道操作员编程包吗?

Joh*_*son 22 r magrittr

是否有任何客观原因,为什么管道运营商从R包magrittr,比如%>%当我在编程R封装,应避免?

更具体地说,我想知道使用管道运算符是否会导致编码冲突或(正面或负面)影响性能.我正在寻找这类案件的具体具体例子.

edd*_*ddi 32

就像写在所有R先进的功能,%>%承载了太多的开销,所以在循环中不使用它(这包括隐含的循环,如*apply家庭,或每个组包循环像dplyrdata.table).这是一个例子:

library(magrittr)
x = 1:10

system.time({for(i in 1:1e5) identity(x)})
#   user  system elapsed 
#   0.07    0.00    0.08 
system.time({for(i in 1:1e5) x %>% identity})
#   user  system elapsed 
#  15.39    0.00   16.68 
Run Code Online (Sandbox Code Playgroud)

  • 现在,R 版本 4.1.0 中添加的原生管道运算符“|>”没有任何开销。 (6认同)
  • 从 magrittr 2.0.0 开始,管道操作符的性能得到了很大的提高。对于上面的两个基准,我现在分别得到 0.036 和 0.291 秒。 (2认同)

Gre*_*gor 17

不应该过于轻松地将依赖项添加到包中.一般而言,您的程序包所依赖的每个程序包都会在依赖项更新时或者在依赖关系停止维护时进行日常维护.它还使人们(稍微)更难以安装您的软件包 - 尽管在互联网连接不可靠的情况下才会显着增加.但是如果有人想将你的软件包放在拇指驱动器上安装某个地方,他们还需要确保它们具有所有依赖项(以及依赖项的依赖项......).

Base R和默认包具有很长的历史,R-Core非常清楚不会引入会破坏下游依赖关系的更改.magrittr更新,看起来它是2014年2月首次在CRAN上.

实际上,magrittr一直稳定,似乎是低风险依赖.特别是如果你是刚刚进口%>%,而忽略它提供了更深奥的运营商(如通过做dplyr,tidyr等.),你可能是相当安全的.它的受欢迎程度几乎可以保证即使它的创建者放弃它,也会有人接管维护.

  • 同样,从教学的角度来看,更多的依赖关系会导致更多的平台特定加载问题(Mac vs PC vs Linux、当前操作系统 vs 旧操作系统、不同芯片等)、有关警告和错误消息的问题等。我教 vanilla R,并且查看我考虑使用的包的依赖关系 (2认同)

42-*_*42- 7

与"标准函数编程"相比,管道范例颠倒了功能应用的明显顺序.这是否有不良后果取决于功能符号学(我原来的错误选择意图是'语义',但spielchucker虽然我的意思semiotics,似乎没问题).我碰巧认为管道创建的代码可读性较差,但这是因为我训练了我的大脑从"由内到外"查看编码.相比:

 y <- func3 ( func2( func1( x) ) )

 y <- x %>% func1 %>% func2 %>% func3
Run Code Online (Sandbox Code Playgroud)

按照我的思维方式,第一个更具可读性,因为信息"向外流动"(并且始终向左)并最终位于最左边的位置y,而第二个中的信息向右流动,然后"转向并且是"管道范例也允许无参数函数应用程序,我认为这增加了错误的可能性.仅使用位置参数匹配的R编程通常会产生完全不可思议的错误消息,而将自己训练为总是(或几乎总是)使用参数名称具有更多信息性错误消息的好处.

我倾向于采用具有一致方向的管道范例:

 y <- func3 %<% func2 %<% func1 %<% x
 # Or
 x %>% func1 %>% func2 %>% func3 -> y
Run Code Online (Sandbox Code Playgroud)

而且我认为这实际上是pkg原始设计的一部分 - magrittr我认为它包括"左管"和"右管".所以这可能是一个人为因素设计问题.R具有左右相关性,dplyr/magrittr管道范例的典型用户通常遵循该规则.我可能患有僵硬脑综合症,所有年轻人都可能是未来,所以你做出了选择.我真的很佩服Hadley合理化数据输入和处理的目标,以便将文件和SQL服务器视为通用串行设备.

大卫罗宾逊提供的例子表明,跟踪争论是一个大问题,我完全同意.我通常的方法是使用制表符和空格来突出显示层次结构:

func3 ( func2( 
           func1(x, a),    # think we need an extra comma here
               b, c),       # and here
        d, e, f) 

x %>% func1(a) %>% func2(b, c) %>% func3(d, e, f)
Run Code Online (Sandbox Code Playgroud)

不可否认,在检查缺少的逗号或括号时,使用语法识别编辑器可以更容易地实现这一点,但在上面的示例中,没有使用逗号或者括号,堆叠/间距方法确实突出了我认为的语法错误.(当遇到困难时,我也会迅速添加参数名称,但我认为这同样适用于管道代码策略.)

  • 我认为列出的示例确实堆叠了一个平台,每个函数只占用一个参数.更清楚:`func3(func2(func1(x,a)b,c)d,e,f)`或`x%>%func1(a)%>%func2(b,c)%>%func3( d,e,f)`就哪个参数与哪个函数有关? (5认同)
  • 除了@DavidRobinson所做的评论之外,在编写或重新排列函数顺序后更换代码时,管道更加宽容. (3认同)
  • 有些人确实将 `-&gt;` 与管道一起使用,这让我发疯!我想每个人都有自己的。 (2认同)