R 管道 (%>%) 不适用于复制功能

Posted

技术标签:

【中文标题】R 管道 (%>%) 不适用于复制功能【英文标题】:R piping (%>%) does not work with replicate function 【发布时间】:2017-09-03 02:44:27 【问题描述】:

我正在尝试学习管道函数 (%>%)。 当试图从这行代码转换到另一行时,它不起作用。

---- R代码--原版-----

set.seed(1014)
replicate(6,sample(1:8))
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    3    7    4    5    1
[2,]    2    8    4    2    4    2
[3,]    5    4    8    5    8    5
[4,]    3    1    2    1    1    7
[5,]    4    6    3    7    7    3
[6,]    6    5    1    3    3    8
[7,]    8    7    5    8    6    6
[8,]    7    2    6    6    2    4

---- R 代码 - 用管道重新编码 ----

> sample(1:8) %>%  replicate(6,.)
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    7    7    7    7    7    7
[2,]    3    3    3    3    3    3
[3,]    2    2    2    2    2    2
[4,]    1    1    1    1    1    1
[5,]    5    5    5    5    5    5
[6,]    4    4    4    4    4    4
[7,]    8    8    8    8    8    8
[8,]    6    6    6    6    6    6

请注意,当使用管道时,采样不起作用给我 相同的向量。

【问题讨论】:

在第一个代码中,复制正在执行示例函数 6 次。在第二个代码中,您将获得示例函数的输出并将该输出复制 6 次。 【参考方案1】:

这是意料之中的。复制需要一个表达式,但是当您按原样使用管道运算符时,您只需将调用结果粘贴到sample()replicate。所以你会得到相同结果的 6 倍。

您必须使用 quote() 来传递要复制的表达式而不是结果,但您不应忘记计算该表达式的每个重复项。

quote(sample(c(1:10,-99),6,rep=TRUE)) %>% 
  replicate(6, .) %>%
  sapply(eval)

给予:

    [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    5    2   10   10    9    2
[2,]    4    3    1    3  -99    1
[3,]   10    2    3    8    2    4
[4,]  -99    1    6    2   10    3
[5,]    8  -99    1    9    4    6
[6,]    4   10    8    1  -99    8

这里发生了什么:

管道发送和表达式复制而不对其进行评估。 replicate 复制该表达式并返回一个包含该表达式 6 倍但不对其进行评估的列表。 sapply(eval) 遍历列表并执行该列表中的每个表达式。

在您之前的问题中(即使用 data.frame 时),您可以这样做:

quote(sample(c(1:10,-99),6,rep=TRUE)) %>% 
  replicate(6, .) %>%
  data.frame

现在函数 data.frame 会强制执行表达式,但你也会得到可怕的变量名,即表达式本身。

如果您想在这里了解更多关于这些问题的信息,您将不得不深入研究所谓的“惰性评估”以及管道操作员如何准确地处理它。但老实说,在这种情况下,我真的看不出使用管道运算符有什么好处。它的可读性更高。

根据 Frank 的评论:您可以混合使用管道和函数嵌套来避免 sapply。但为此,您必须在代码块中包含嵌套函数,否则管道运算符将无法正确处理它:

quote(sample(c(1:10,-99),6,rep=TRUE)) %>% 
  replicate(6, eval(.)) 

非常有趣,但恕我直言不是很有用...

【讨论】:

非常感谢。这很有意义。只是想学习这些东西。是的,在这里使用管道可能不值得,但我只是在学习。 我认为不需要 sapply:quote(sample(c(1:10,-99),6,rep=TRUE)) %>% replicate(6, eval(.)) @Frank 忘记我之前的评论,我错过了,事实上eval() 现在嵌套在replicate 中。这确实有效,但这一半是管道,一半不是,所以它更没有意义。谢谢你提到它,这是一个有趣的案例。还有另一个例子,为什么那个管道操作员是一罐我不愿意打开的蠕虫。不过,我已将您的建议添加到帖子中。 好的,在我看来,它仍然是管道,只是不是replicate 的第一个参数。 “猜测”何时将. 传递给第一个参数的 magrittr 规则很烦人,是的。而且,对于模拟,我不会使用管道,在这里运行基准测试(在“速度和管道”下):franknarf1.github.io/r-tutorial/_book/work.html#simulations

以上是关于R 管道 (%>%) 不适用于复制功能的主要内容,如果未能解决你的问题,请参考以下文章

grep 的管道不适用于尾部? [复制]

我的正则表达式适用于 regex101 但不适用于 python? [复制]

Nodejs异步功能不适用于每个功能[重复]

suppressWarnings() 不适用于管道运算符

jQuery隐藏功能不适用于iframe

加载功能不适用于href