I have the following table:
Group Value
---- ----
1 A
1 B
1 C
1 D
2 A
2 B
2 C
For each of the two groups, I want to return all possible combinations of values. For group 1, e.g., the possible combinations of are (A,B), (A,C), (A,D), (B,C), (B,D), (C,D), (A,B,C), (B,D,C), (D,C,A), (C,A,B). Analogous, for group 2 it is (A,B), (A,C), (B,C) [Remark: I don't want to consider (1) the combintions with just one value, (2) the combination with all values and (3) the combination with no values. Thus I have 2^(n)-n-1-1 combinations for n different values].
I want to list all those combinations with the help of an additional column "Combi". This column numbers the different combinations consecutively.
Group Combi Value
---- ---- ----
1 1 A
1 1 B
1 2 A
1 2 C
1 3 A
1 3 D
1 4 B
1 4 C
1 5 B
1 5 D
1 6 C
1 6 C
1 7 A
1 7 B
1 7 C
1 8 B
1 8 C
1 8 D
1 9 C
1 9 D
1 9 A
1 10 D
1 10 A
1 10 B
2 11 A
2 11 B
2 12 A
2 12 C
2 13 B
2 13 C
How do I do this in R?
Here is a general tidyverse solution, should work with sets of values that have more than 3 items.
The idea is to use combn (with m = 2 then 3 etc) and format the output as a tibblefor different Group and m values. From there we can use tidyverse functions map_dfr and unnest. Finally as we have multiple ids rather than one, we build a table of unique ids, build the unique combi id and join it back to our result.
# convenience fonction to store combinations in a long format
combi_as_tibble <- function(n,values) combn(values,n) %>%
{tibble(id = rep(seq(ncol(.)),each=nrow(.)),Value=c(.))}
combi_as_tibble(2,letters[1:3]) # example
# # A tibble: 6 x 2
# id Value
# <chr> <chr>
# 1 1 a
# 2 1 b
# 3 2 a
# 4 2 c
# 5 3 b
# 6 3 c
df1 %>% group_by(Group) %>%
summarize(combis = list(
map_dfr(2:(length(unique(Value))-1),combi_as_tibble,Value,.id="id2")
)) %>% # by Group, build a long tibble with all combinations
unnest %>% # unnest to get a long unnested table
left_join(.,select(.,Group,id2,id) %>% distinct %>% mutate(combi=row_number())
) %>% # build combi ids
select(Group,Value,combi) %>%
as.data.frame
# Group Value combi
# 1 1 A 1
# 2 1 B 1
# 3 1 A 2
# 4 1 C 2
# 5 1 A 3
# 6 1 D 3
# 7 1 B 4
# 8 1 C 4
# 9 1 B 5
# 10 1 D 5
# 11 1 C 6
# 12 1 D 6
# 13 1 A 7
# 14 1 B 7
# 15 1 C 7
# 16 1 A 8
# 17 1 B 8
# 18 1 D 8
# 19 1 A 9
# 20 1 C 9
# 21 1 D 9
# 22 1 B 10
# 23 1 C 10
# 24 1 D 10
# 25 2 A 11
# 26 2 B 11
# 27 2 A 12
# 28 2 C 12
# 29 2 B 13
# 30 2 C 13
data
df1 <- read.table(text="Group Value
1 A
1 B
1 C
1 D
2 A
2 B
2 C",h=T,strin=F)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With