在 R 中编写组合

writing combinations in R

我有一个这样的数据框 (df)

name  col1   col2
pippo A;B;C  E;F;G;
pluto G;H    X;Y;Z;E;O;D

我想写下 col1 的 1 个元素和 col 2 的 1 个元素之间的所有可能组合,并将每个组合作为数据框返回,例如

name     col1   col2
pippo      A       E
pippo      A       F
pippo      A       G
pippo      B       E
... and so on. 

考虑到我有所有字母,并且 col1 和 col2 中的元素数量可以变化(从 1 个元素到 10 个元素),R 可以吗?

;

拆分列后,我们可以使用crossing
library(dplyr)
library(tidyr)
library(purrr)
df %>%
  transmute(name, new = map2(strsplit(col1, ";"),
         strsplit(col2, ";"), ~ crossing(col1 = .x, col2 = .y))) %>% 
  unnest(c(new))

-输出

# A tibble: 21 x 3
#   name  col1  col2 
#   <chr> <chr> <chr>
# 1 pippo A     E    
# 2 pippo A     F    
# 3 pippo A     G    
# 4 pippo B     E    
# 5 pippo B     F    
# 6 pippo B     G    
# 7 pippo C     E    
# 8 pippo C     F    
# 9 pippo C     G    
#10 pluto G     D    
# … with 11 more rows

数据

df <- structure(list(name = c("pippo", "pluto"), col1 = c("A;B;C", 
"G;H"), col2 = c("E;F;G;", "X;Y;Z;E;O;D")), class = "data.frame", 
row.names = c(NA, 
-2L))

Base R。这不像 akrun 的答案那样清晰易读,但它只是 Base R。

eg <- do.call(Map, c(
  list(f=function(...) do.call(expand.grid,
    lapply(list(...), function(s) strsplit(s, ";")[[1]]))),
  dat[,-1]))
cbind.data.frame(name = rep(dat$name, sapply(eg, nrow)), do.call(rbind, eg))
#          name col1 col2
# A;B;C.1 pippo    A    E
# A;B;C.2 pippo    B    E
# A;B;C.3 pippo    C    E
# A;B;C.4 pippo    A    F
# A;B;C.5 pippo    B    F
# A;B;C.6 pippo    C    F
# A;B;C.7 pippo    A    G
# A;B;C.8 pippo    B    G
# A;B;C.9 pippo    C    G
# G;H.1   pluto    G    X
# G;H.2   pluto    H    X
# G;H.3   pluto    G    Y
# G;H.4   pluto    H    Y
# G;H.5   pluto    G    Z
# G;H.6   pluto    H    Z
# G;H.7   pluto    G    E
# G;H.8   pluto    H    E
# G;H.9   pluto    G    O
# G;H.10  pluto    H    O
# G;H.11  pluto    G    D
# G;H.12  pluto    H    D