当我在R中对程序包进行编程时,是否有任何客观原因可以避免R magrittr
中的pipe operators,例如%>%
?
更具体地说,我想知道使用管道运算符是否会导致编码冲突或(正面或负面)影响性能。我正在寻找这类案件的具体具体例子。
答案 0 :(得分:32)
与R中编写的所有高级函数一样,%>%
会带来很多开销,因此不要在循环中使用它(这包括隐式循环,例如*apply
系列,或者每个组在dplyr
或data.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
答案 1 :(得分:18)
不应过于轻易地将依赖项添加到程序包中。一般而言,程序包所依赖的每个程序包都会在依赖项更新时进行维护,或者在依赖项停止时被维护。它还使人们(稍微)更难以安装您的软件包 - 尽管在互联网连接不可靠的情况下才会显着增加。但是如果有人想把你的软件包放在拇指驱动器上安装某个地方,他们还需要确保他们拥有你所有的依赖项(以及依赖项的依赖项......)。
Base R和默认包具有很长的历史,R-Core非常清楚不会引入会破坏下游依赖关系的更改。 magrittr
更新,看起来像2014年2月首次登陆CRAN。
实际上,magrittr
一直稳定,似乎是一种低风险依赖。特别是如果你只导入%>%
并忽略它提供的更深奥的运算符(如dplyr
,tidyr
等),你可能非常安全。它的受欢迎程度几乎可以保证,即使它的创建者放弃它,也会有人接管维护。
答案 2 :(得分:7)
管道范例与标准功能编程"相比,颠倒了功能应用的明显顺序。这是否具有不良后果取决于功能符号学(我最初的错误定义是“语义学”,但是spielchucker虽然我的意思是semiotics
,但似乎没问题)。我碰巧认为管道创建的代码可读性较差,但这是因为我已经训练了我的大脑来查看来自"由内到外"的编码。比较:
y <- func3 ( func2( func1( x) ) )
y <- x %>% func1 %>% func2 %>% func3
以我的思维方式,第一个更具可读性,因为信息&#34;流动&#34;向外(并始终向左)并最终位于最左边的位置y
,其中第二个中的信息向右流动然后&#34;转向并向左发送。管道范例还允许无参数函数应用程序,我认为这会增加错误的可能性。仅使用位置参数匹配的R编程通常会产生完全不可思议的错误消息,而惩罚自己始终(或几乎总是)使用参数名称可以获得更多信息性错误消息。
我倾向于采用具有一致方向的管道范例:
y <- func3 %<% func2 %<% func1 %<% x
# Or
x %>% func1 %>% func2 %>% func3 -> y
而且我认为这实际上是pkg原始设计的一部分 - magrittr
我相信其中包括一个“左管道”。以及“右管道”。所以这可能是一个人为因素设计问题。 R具有左右相关性,dplyr / magrittr管道范例的典型用户通常遵循该规则。我可能患有僵硬脑综合征,所有年轻人都可能是未来,所以你做出了选择。我真的很佩服Hadley合理化数据输入和处理的目标,以便将文件和SQL服务器视为通用串行设备。
David Robinson提供的例子表明,跟踪争论是一个大问题,我完全同意。我通常的方法是使用制表符和空格来突出显示层次结构:
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)
不可否认,在检查缺少的逗号或括号时,使用语法感知编辑器可以更轻松地实现这一点,但在上面的示例中,没有使用逗号或者括号,堆叠/间距方法确实突出了我认为的语法错误。 (当遇到困难时,我也会迅速添加参数名称,但我认为这同样适用于管道代码策略。)