作者:顾旭东-夏天 | 来源:互联网 | 2023-02-07 11:48
我正在尝试学习管道功能(%>%).
当试图从这行代码转换到另一行时,它不起作用.
---- 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
请注意,使用管道时,采样不起作用,给我相同的矢量.
1> Joris Meys..:
这是可以预料的.复制需要一个表达式,但是在使用管道运算符时,只需将调用结果粘贴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
这里发生了什么:
管道发送和表达复制而不进行评估.
复制复制该表达式并返回一个列表,其中包含该表达式的6倍但未对其进行评估.
sapply(eval)遍历列表并执行该列表中的每个表达式.
在您之前的问题中(即使用data.frame时),您可以完成以下操作:
quote(sample(c(1:10,-99),6,rep=TRUE)) %>%
replicate(6, .) %>%
data.frame
现在该函数data.frame
会强制执行表达式,但最终还是会出现可怕的变量名,即表达式本身.
如果你想在这里了解更多关于这些问题的信息,你将不得不深入研究所谓的"懒惰评估"以及管道运营商如何处理这个问题.但老实说,在这种情况下,我真的看不到使用管道操作员的任何好处.它更具可读性.
根据弗兰克的评论:你可以使用混合管道和功能嵌套来避免sapply
.但为此,您必须在代码块中包含嵌套函数,否则管道操作符将无法正确处理它:
quote(sample(c(1:10,-99),6,rep=TRUE)) %>% {
replicate(6, eval(.)) }
非常有趣,但imho不太有用......
好吧,在我看来,它仍然是管道,而不是"复制"的第一个参数."猜测"何时将`.`传递给第一个参数的magrittr规则很烦人,是的.而且,对于模拟,我不会使用管道,在这里运行基准测试(在"速度和管道"下):http://franknarf1.github.io/r-tutorial/_book/work.html#simulations