【问题标题】:elegant increment operator as pipeline优雅的增量运算符作为管道
【发布时间】:2015-06-12 18:02:49
【问题描述】:
library(magrittr)
x <- 2
x %<>% 
  add(3) %>% 
  subtract(1)
x

是否有预定义的更易读的方式与管道一起使用?

可能类似于x %+=% 3 %-=% 1

【问题讨论】:

  • 预定义的方式,由 magrittr 的作者选择。他们创造了这些功能。
  • 你甚至可以在具有内置增量运算符的语言中做到这一点吗?

标签: r operators increment pipeline


【解决方案1】:

简短的回答

没有。

长答案

递增运算符很容易制作:

%+=% <- function (x, inc) x + inc
%-=% <- function (x, dec) x - dec

但是,这些函数不会直接修改 x,因为 R 非常努力地阻止函数修改其范围之外的变量。也就是说,您仍然需要编写x &lt;- x %+=% 1 才能真正更新x

Hmisc 包中的 inc&lt;-dec&lt;- 函数可以解决此限制。所以你可能会惊讶地发现inc&lt;-的定义只是:

function (x, value) 
{
    x + value
}

也就是说,函数内部的代码与我们自定义的%+=%操作符中的代码完全相同。神奇的发生是因为 R 解析器中的一个特殊功能,它可以解释

inc(x) <- 1

作为

x <- `inc<-`(x, 1)

这就是您能够执行names(iris) &lt;- letters[length(iris)] 之类的操作的方式。

%&lt;&gt;% 很神奇,因为它在其范围之外修改了x。这也非常违反 R 的编码范式*。因此,所需的机器很复杂。要以您喜欢的方式实现%+=%,您需要对%&lt;&gt;% 进行逆向工程。不过,可能值得在他们的 GitHub 上提出功能请求。

*除非您是data.table 用户,在这种情况下,您无论如何都没有希望。

【讨论】:

  • 要就地修改,一个选项是`%+=%` &lt;- function(x,y) assign(deparse(substitute(x)),x+y,.GlobalEnv),尽管可能用其他东西代替.GlobalEnv 以减少不安全性。顺便说一句,没有data.table 用户会要求使用这样的管道。
  • @Frank 很公平。我写的时候想到了:=
  • 哦,你是对的,还有很多像 set* 这样命名的函数也可以在适当的位置进行修改。我只是说你的警告“*除非你是......”可能不需要,因为 OP 几乎肯定不是一个。
  • 来自 magrittr 的 AFAICT %&lt;&gt;% 确实 not 就地修改,而是将结果重写回原始变量(它只屏蔽了赋值)。两者是非常不同的东西。
  • @Arun 是的,这就是它实际上在做的事情。但对最终用户的影响是一样的
猜你喜欢
  • 2018-08-22
  • 1970-01-01
  • 2011-12-11
  • 2015-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-29
  • 2020-07-14
相关资源
最近更新 更多