Nancy
Nancy

Reputation: 101

writing combinations in R

I have a dataframe (df) like this

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

I'd like to write all possible combinations between 1 element of col1 and 1 element of col 2 and for each returned as a dataframe, for example

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

Considering that I have all alphabet letters and the number of elements in col1 and col2 can variate (from 1 element to 10), is it possible with R?

Upvotes: 1

Views: 41

Answers (2)

akrun
akrun

Reputation: 887891

We can use crossing after splitting the columns by ;

library(dplyr)
library(tidyr)
library(purrr)
df %>%
  transmute(name, new = map2(strsplit(col1, ";"),
         strsplit(col2, ";"), ~ crossing(col1 = .x, col2 = .y))) %>% 
  unnest(c(new))

-output

# 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

data

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))

Upvotes: 2

r2evans
r2evans

Reputation: 160952

Base R. This is not as clear to read as akrun's answer, but it's just 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

Upvotes: 2

Related Questions