group_by() 和 summarise() 与所有组合(包括不存在的组合)

group_by() and summarise() with all combinations (including non-existing combinations)

基本上,我想要列 ij 的所有唯一组合;如果 k 列不可用,则期待 NA(类似于 group_by & summarise,但具有所有唯一可能的组合)。

tidyverse 中是否有任何现有函数,或者是否与我在下面写的函数具有相同的功能?

library(tidyverse)

df <- tibble(
 i = c("a", "a", "b"),
 j = c("x", "y", "x"),
 k = c(100, 300, 20)
)

# I often write this chunk below after group_by & summarise
df %>%
  spread(j, k) %>%
  gather(j, k, -i)

似乎 cross_join() 仍然是 tidyverse feature request on github,需要使用 expand.grid(unique(df$i), unique(df$j), stringsAsFactors = FALSE) 来创建具有所有唯一可能组合的 data.frame:

df %>% 
  right_join(expand.grid(unique(df$i), unique(df$j), stringsAsFactors = FALSE), 
           by = c("i" = "Var1", "j" = "Var2"))
  i j   k
1 a x 100
2 b x  20
3 a y 300
4 b y  NA

因此,OP 使用 spread()gather() 的方法似乎更简洁。

就个人而言,我更喜欢 data.table 包中的 CJ() 函数:

library(data.table)
setDT(df)[CJ(i = i, j = j, unique = TRUE), on = .(i, j)]
   i j   k
1: a x 100
2: a y 300
3: b x  20
4: b y  NA

CJ()可与right_join()一起用作expand.grid()的替代品:

df %>% 
  right_join(data.table::CJ(i = .$i, j = .$j, unique = TRUE))
  i j   k
1 a x 100
2 a y 300
3 b x  20
4 b y  NA

您可以使用 tidyverse 中的 complete 函数 http://tidyr.tidyverse.org/reference/complete.html

df %>% complete(i,j)

这为您提供了第 i 列和第 j 列的所有组合