在 dplyr 链中使用 table()

Using table() in dplyr chain

有人可以解释为什么 table()在 dplyr-magrittr 管道操作链中不起作用吗?这是一个简单的代表:

tibble(
  type = c("Fast", "Slow", "Fast", "Fast", "Slow"),
  colour = c("Blue", "Blue", "Red", "Red", "Red")
) %>% table(.$type, .$colour)

Error in sort.list(y) : 'x' must be atomic for 'sort.list' Have you called 'sort' on a list?

但这当然有效:

df <- tibble(
  type = c("Fast", "Slow", "Fast", "Fast", "Slow"),
  colour = c("Blue", "Blue", "Red", "Red", "Red")
) 

table(df$type, df$colour)


       Blue Red
  Fast    1   2
  Slow    1   1

此行为是设计使然:https://github.com/tidyverse/magrittr/blob/00a1fe3305a4914d7c9714fba78fd5f03f70f51e/README.md#re-using-the-placeholder-for-attributes

因为你没有自己的 .,tibble 仍然作为第一个参数传递,所以它更像是

... %>% table(., .$type, .$colour)

magrittr 的官方解决方法是使用大括号

... %>% {table(.$type, .$colour)}

我已经开始像这样使用 with(table(...))

tibble(type = c("Fast", "Slow", "Fast", "Fast", "Slow"),
       colour = c("Blue", "Blue", "Red", "Red", "Red")) %>% 
  with(table(type, colour))

类似于我们可能将 %>% 读为 "and then" 的方式,我会将其读为 "and then with that data make this table"。

dplyr中的%>%运算符实际上是从magrittr导入的。使用 magrittr,我们还可以使用 %$% 运算符,它公开了前面表达式中的名称:

library(tidyverse)
library(magrittr)

tibble(
  type = c("Fast", "Slow", "Fast", "Fast", "Slow"),
  colour = c("Blue", "Blue", "Red", "Red", "Red")
) %$% table(type, colour)

输出:

      colour
type   Blue Red
  Fast    1   2
  Slow    1   1