R:功能工厂的管道输入

R:功能工厂的管道输入,r,lazy-evaluation,magrittr,R,Lazy Evaluation,Magrittr,在R中,我有一个函数输出一个函数(一个函数工厂,它被称为)。 但是,当使用%%>%%将输入管道传输到它时,会产生奇怪的错误 以下是一个简化的示例: ax <- function(a) { function(x) a*x } library(magrittr) 3 %>% ax() %>% plot # Error in a * x : non-numeric argument to binary operator ax(3) %>% plot # work

在R中,我有一个函数输出一个函数(一个函数工厂,它被称为)。 但是,当使用
%%>%%
将输入管道传输到它时,会产生奇怪的错误

以下是一个简化的示例:

ax <- function(a) {
  function(x) a*x
}

library(magrittr)
3 %>% ax() %>% plot # Error in a * x : non-numeric argument to binary operator
ax(3) %>% plot      # works, a plot of y=3x is produced
ax%ax()%%>%plot#a*x中的错误:二进制运算符的非数值参数
ax(3)%>%plot#起作用,产生y=3x的plot
导致我尝试将
force(a)
插入到
ax
的函数体中。 现在,在这两种情况下都会产生一个情节


但我不明白为什么会这样。对我来说,这两种情况基本相同。那么,为什么第一种情况需要
force()
,而第二种情况不需要
force()

更新:安装magrittr的开发版本。显然这个问题已经解决了,但没有人意识到这一点<代码>遥控器::安装github(“tidyverse/magrittr”)

两年来没有人接触过管道代码

他们的根本问题是R惰性评估。当您将参数传递给函数时,直到需要时才对其求值

有关此示例,请尝试以下代码:

funs <- list()
for (i in 1:3) {
  funs[[i]] <- ax(i)
}
# i is not evaluated until now. it has been modified before it is evaluated so all the calls evaluate a to the current value of i (i=3)
print(funs[[3]](1))
print(funs[[2]](1))
print(funs[[1]](1))
# lapply creates an environment for each iteration. Even though the evaluation is delayed, it maps to the expected value of a
funs2 <- lapply(1:3, ax)
print(funs2[[3]](1))
print(funs2[[2]](1))
print(funs2[[1]](1))

fun示例说明了
force
和lazy求值的帮助。谢谢!:)环顾magrittr repo中的问题,我有一种预感,magrittr可能扰乱了函数的环境,导致了错误。显然,magrittr的作者在5年前简化了函数的实现,并在过程中修复了这个问题,尽管他不知道问题的存在。我想是时候发布新的magrittr了!:-)