算术运算符后管道的不同输出与直接调用它

Different outputs with pipe after arithmetic operator vs calling it directly

我在将矩阵输入 as.data.frame 时得到了意想不到的结果,我可以利用一些智慧来解释为什么会这样。当我 运行 下面的代码时:

library(magrittr)
matrix(c(1,0,0,1), nrow = 2)*5 %>% as.data.frame()

我期待

  V1 V2
1  5  0
2  0  5

但我得到

  .
1 5

这令人困惑,因为当我围绕矩阵构造调用 as.data.frame 时它工作正常:

> as.data.frame(matrix(c(1,0,0,1), nrow = 2)*5)
  V1 V2
1  5  0
2  0  5

当我也通过管道传递乘法函数时:

> matrix(c(1,0,0,1), nrow = 2) %>% `*`(5) %>% as.data.frame()
  V1 V2
1  5  0
2  0  5

当我保存中间结果并将其通过管道传输到下一个函数时:

> v <- matrix(c(1,0,0,1), nrow = 2)*5
> v %>% as.data.frame()
  V1 V2
1  5  0
2  0  5

这让我很确定这是由于在将它发送到管道之前执行了算术运算,我们可以用其他算术和其他函数来确认它,以确保它不是特定于 * 运算符或as.data.frame 函数:

# Plus instead of times
> matrix(c(1,0,0,1), nrow = 2)+1 %>% as.data.frame()
  .
1 2

# rowSums instead of as.data.frame()
> matrix(c(1,0,0,1), nrow = 2)*5 %>% rowSums()
Error in rowSums(.) : 'x' must be an array of at least two dimensions

我显然不理解管道如何与算术运算符一起工作或算术函数是什么 return(?) 所以我可以对这里发生的事情使用一些建议。这是我无法找到文档的已知怪癖吗? Hadley 的书在 chapter on pipes 中没有提到这是一个问题,help("%>%") 的技术说明部分似乎只警告不要捕获其调用环境的函数。最后的注释提到了算术运算符,但当结果不同于切换 as.data.frame 调用和乘法步骤时,似乎只有运算符优先级受到影响:

matrix(c(1,0,0,1), nrow = 2) %>% as.data.frame() %>% `*`(5)
  V1 V2
1  5  0
2  0  5

为什么将经过算术修改的矩阵传递给另一个函数时会得到不同的结果?

?Syntax 帮助页面所述,%>% 运算符的优先级高于 * 运算符。这意味着

matrix(c(1,0,0,1), nrow = 2) * 5 %>% as.data.frame()

相同
matrix(c(1,0,0,1), nrow = 2) * (5 %>% as.data.frame())

所以在与 matrix 相乘之前,5 被传递给 as.data.frame。组合不同优先级的运算符时,您可以更明确地使用 (){} 以确保顺序发生在您期望的范围内。这些都可以工作

(matrix(c(1,0,0,1), nrow = 2) * 5) %>% as.data.frame()
{matrix(c(1,0,0,1), nrow = 2) * 5} %>% as.data.frame()