Получить уникальную комбинацию (combn) по ID в R

Я пытаюсь получить уникальную комбинацию по каждому идентификатору, я получаю ошибку, он не расширяет идентификатор.

ID <- c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,4,4,4,5,5,5,5,5,6,6,6,6)
var1 <- c("A","B","E","F","C","D","C","A","B","C","A","D","B","C",
      "A","B","C","A","D","C","A","B","C","E","F","G")
df1 <- data.frame(ID,var1)
df1 <- df1[order(df1$ID, df1$var1),]
dd <- unique(df1)
dd <- data.table(dd)
dd[,new4 := t(combn(sort(var1), m = 3))[,1],by= "ID"]
dd[,new5:= t(combn(sort(var1), m = 3))[,2],by="ID"]
dd[,new6:= t(combn(sort(var1), m = 3))[,3],by="ID"]

Warning message:
In `[.data.table`(dd, , `:=`(new4, t(combn(sort(var1), m = 3))[,  :
RHS 1 is length 10 (greater than the size (5) of group 1). The last 5 element(s) will be discarded.

     ID var1 new4 new5 new6
 1:  1    A    A    B    C
 2:  1    B    A    B    E
 3:  1    C    A    B    F
 4:  1    E    A    C    E
 5:  1    F    A    C    F
 6:  2    A    A    B    C
 7:  2    B    A    B    D
 8:  2    C    A    C    D
 9:  2    D    B    C    D
10:  3    A    A    B    C
11:  3    B    A    B    D
12:  3    C    A    C    D
13:  3    D    B    C    D
14:  4    A    A    B    C
15:  4    B    A    B    C
16:  4    C    A    B    C
17:  5    A    A    B    C
18:  5    B    A    B    D
19:  5    C    A    C    D
20:  5    D    B    C    D
21:  6    C    C    E    F
22:  6    E    C    E    G
23:  6    F    C    F    G
24:  6    G    E    F    G

Вывод не дает достаточного количества комбинаций по каждому ID, ID1 (A,B,C,E,F), он дает только 5 комбинаций. В любом случае есть решение проблемы?Вывод, который я хочу для ID1, есть 10 комбинаций (A B C) (A C F) (A B F) (A B E) (BC E) (B C F) (C A B) (C A E) (C A F) (E C F)


person BIN    schedule 23.09.2016    source источник
comment
Вы назначаете его набору данных, в котором исходное количество строк меньше, чем новая длина combn.   -  person akrun    schedule 23.09.2016
comment
@akrun Есть ли способ противостоять этому?   -  person prateek1592    schedule 23.09.2016
comment
как мы расширяем ту же длину данных перед использованием cobm   -  person BIN    schedule 23.09.2016
comment
@BIN Кажется, вы хотите, чтобы столбец var1 имел ту же длину, что и комбинации. Но я не уверен, как будут реплицироваться элементы в 'var1'. Пожалуйста, покажите ожидаемый результат   -  person akrun    schedule 23.09.2016
comment
@akrun dd[rep(1:.N,each = 3)][,new4:= t(combn(unique(var1), m = 3))[,1], by = .(ID)], я нашел таким образом, он зафиксировал длину, но затем я получил так много комбинаций, единственная, в которой мне нужна уникальная комбинация, например (ABC) или (ADE), а не (AAB)   -  person BIN    schedule 23.09.2016
comment
@akrun просто обнови   -  person BIN    schedule 23.09.2016
comment
@BIN Это должно дать правильные комбинации dd[, transpose(combn(sort(as.character(var1)), 3, FUN = list)), by = ID], но если мы хотим, чтобы «var1» также отображался на выходе, я не уверен, как вы хотели   -  person akrun    schedule 23.09.2016
comment
@akrun Я думаю, что simplify=FALSE - более стандартный способ добиться этого, чем FUN = list.   -  person Frank    schedule 23.09.2016
comment
@akrun, все еще выдает ошибку, я могу найти другой способ получить комбинацию   -  person BIN    schedule 23.09.2016
comment
Если это дает вам ошибку, возможно, вам нужно использовать data.table::transpose и иметь какой-то другой пакет с конфликтом пространства имен, вызывающим проблемы.   -  person Frank    schedule 23.09.2016


Ответы (1)


@BIN Поскольку количество комбинаций обычно не соответствует количеству уникальных букв для «Var1», вы можете попробовать следующее:

 library(dplyr)      
 dd[,var1:=as.character(var1)]

 dd[,.(Numb.Combinations = choose(var1 %>% uniqueN,3),
             ID1 = paste0(var1 %>% unique, collapse=""),
      Combinations = paste(combn(var1,3,function(x) paste0(x,collapse = "")),collapse="-")),   
   by="ID"]

Вывод аналогичен тому, который вы просили в самом конце:

   ID Numb.Combinations   ID1                            Combinations
1:  1                10 ABCEF ABC-ABE-ABF-ACE-ACF-AEF-BCE-BCF-BEF-CEF
2:  2                 4  ABCD                         ABC-ABD-ACD-BCD
3:  3                 4  ABCD                         ABC-ABD-ACD-BCD
4:  4                 1   ABC                                     ABC
5:  5                 4  ABCD                         ABC-ABD-ACD-BCD
6:  6                 4  CEFG                         CEF-CEG-CFG-EFG  

Или, если хотите, как предложили @akrun и @frank,

 dd <- dd[, c(ID1 = paste0(var1 %>% unique, collapse=""),
             transpose(combn(sort(var1), 3, simplify = F))), by = ID]
colnames(dd) <- c("ID","ID1","New1","New2","New3")

С выходом:

    ID   ID1 New1 New2 New3
 1:  1 ABCEF    A    B    C
 2:  1 ABCEF    A    B    E
 3:  1 ABCEF    A    B    F
 4:  1 ABCEF    A    C    E
 5:  1 ABCEF    A    C    F
 6:  1 ABCEF    A    E    F
 7:  1 ABCEF    B    C    E
 8:  1 ABCEF    B    C    F
 9:  1 ABCEF    B    E    F
10:  1 ABCEF    C    E    F
11:  2  ABCD    A    B    C
12:  2  ABCD    A    B    D
13:  2  ABCD    A    C    D
14:  2  ABCD    B    C    D
15:  3  ABCD    A    B    C
16:  3  ABCD    A    B    D
17:  3  ABCD    A    C    D
18:  3  ABCD    B    C    D
19:  4   ABC    A    B    C
20:  5  ABCD    A    B    C
21:  5  ABCD    A    B    D
22:  5  ABCD    A    C    D
23:  5  ABCD    B    C    D
24:  6  CEFG    C    E    F
25:  6  CEFG    C    E    G
26:  6  CEFG    C    F    G
27:  6  CEFG    E    F    G
    ID   ID1 New1 New2 New3
person J.Sillero    schedule 30.09.2016