示例函数不适用于 purrr::rerun 和管道?

Sample function doesn't work well with purrr::rerun and pipe?

我在 purrr::rerun 与 %>% 一起使用时观察到一些我无法理解的奇怪行为。

如果我运行,

library(purrr)
sample(1:30, 3) %>% rerun(4, .)

会return,

# 1 24 5
# 1 24 5
# 1 24 5
# 1 24 5

显然这不是我想要的。

但是,如果我 运行 没有 %>% 的类似代码,它实际上会按预期工作。

rerun(4, sample(1:30, 3))
# 17 5 20
# 13 3 6
# 22 25 3
# 20 30 29

我不明白为什么行为不同。有人可以解释吗?提前致谢。

调用函数的顺序很重要。在第一种情况下,您从 30 个元素中选择 3 个元素并调用它 4 次。就像做

temp <- sample(1:30, 3)
purrr::rerun(4, temp)

所以无论调用4次还是1000次,temp的值都不会改变。

而在第二种情况下,您调用 sample(1:30, 3) 4 次,每次都会得到不同的结果。

magrittr 不会懒惰地计算点。它可能很好,就像在这个模拟管道中一样(不要使用它,它很容易损坏!)

`%foo>%` <- function(e1,e2){
  eval.parent(eval(substitute(substitute(e2,list(. = substitute(e1))))))
}

sample(1:30, 3) %foo>% purrr::rerun(4, .)
#> [[1]]
#> [1] 22 25  9
#> 
#> [[2]]
#> [1] 14 28 21
#> 
#> [[3]]
#> [1]  4  1 25
#> 
#> [[4]]
#> [1] 17  2 25

reprex package (v0.3.0)

于 2019-09-19 创建

这是一种设计选择,可能是为了避免使用多个点时出现歧义和效率低下。