我正在尝试学习管道功能(%>%) 当试图从这行代码转换到另一行时,它不起作用。
---- 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
请注意,使用烟斗时,取样不起作用 相同的矢量。
答案 0 :(得分:19)
这是可以预料的。复制需要一个表达式,但是当使用管道运算符时,您只需将调用结果粘贴到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
这里会发生什么:
在您之前的问题中(即使用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(.)) }
非常有趣,但imho不是很有用......