2016-04-13 9 views
3

Mein Datensatz enthält wiederholte Beobachtungen für Personen, die an Projekten arbeiten. Ich brauche einen Datenrahmen mit zwei Spalten, die 'Kombinationen' von Projekten für jede Person und jeden Zeitpunkt auflisten. Lassen Sie mich mit einem Beispiel erklären:Datenrahmen umstrukturieren/umformen (r)

Diese meine Daten:

ID Week Project  
01 1  101 
01 1  102 
01 1  103 
01 2  101 
01 2  102 
02 1  101 
02 1  102 
02 2  101 

Person 1 (ID = 1) arbeitete an drei Projekten in der Woche 1. Das bedeutet, dass es sechs mögliche Kombinationen von Projekten (project_i & project_j) für diese Person, in dieser Woche. Diese

ist, was ich brauche

ID Week Project_i Project_j 
01 1  101  101 
01 1  101  102 
01 1  101  103 
01 1  102  101 
01 1  102  102  
01 1  102  103 
01 1  103  101 
01 1  103  102 
01 1  103  103 
01 2  101  101 
01 2  101  102 
01 2  102  101 
01 2  102  102 
02 1  101  101 
02 1  101  102 
02 1  102  101 
02 1  102  102 
02 2  101  101 

Fälle verlieren, die nur ein Projekt pro Woche haben, ist kein Problem.

Ich habe versucht basic r und reshape2 für ein bisschen, aber ich kann das nicht herausfinden.

+0

Gerade jetzt, ich habe die gleiche Projekt-ID in der gleichen Zeile nicht enthält (dh 101 101) –

Antwort

6

Hier ist eine Möglichkeit:

library(data.table) 
setDT(DT) 

DT[, CJ(P1 = Project, P2 = Project)[P1 != P2], by=.(ID, Week)] 

    ID Week P1 P2 
1: 1 1 101 102 
2: 1 1 101 103 
3: 1 1 102 101 
4: 1 1 102 103 
5: 1 1 103 101 
6: 1 1 103 102 
7: 1 2 101 102 
8: 1 2 102 101 
9: 2 1 101 102 
10: 2 1 102 101 

CJ der cartesianischen Join von zwei Vektoren ist, alle Kombinationen nehmen. Wenn Sie nicht beide (101,102) und (102,101) möchten, verwenden Sie P1 > P2 anstelle von P1 != P2. Oh, das OP hat die Frage geändert ... also nutze P1 <= P2.

+0

Dies scheint zu arbeiten, aber r noch läuft . Glauben Sie, dass dies für 2 Millionen Beobachtungen lange dauern wird (oder überhaupt möglich ist)? –

+1

@ HJ_r Es ist wahrscheinlich nicht. Sie müssen das kombinatorische Problem berücksichtigen, das Sie angehen möchten. Sie können 'Combos type = DT [. (N = .N * (. N-1 l)) von =. (ID, Woche)]' die Größe des Problems zu sehen. 'Combos [, Summe (n)]' wird die Gesamtzahl der Zeilen im Ergebnis zeigen, und Sie können auf 'Combos suchen auch [, Zusammenfassung (n)]', 'Combos [, hist (n)]', etc. – Frank

+0

Danke, am Ende hat Ihre Lösung perfekt funktioniert. –

6

Hier ist eine Lösung, die dplyr und tidyr verwendet. Der Schlüsselschritt ist tidyr::complete() mit kombinierten dplyr::group_by()

library(dplyr) 
library(tidyr) 

d %>% 
    rename(Project_i = Project) %>% 
    mutate(Project_j = Project_i) %>% 
    group_by(ID, Week) %>% 
    complete(Project_i, Project_j) %>% 
    filter(Project_i != Project_j) 
5

Hier ist eine Basisoption expand.grid:

do.call(rbind, lapply(split(df, paste(df$ID, df$Week)), function(x){ 
    x2 <- expand.grid(ID = unique(x$ID), 
         Week = unique(x$Week), 
         Project_i = unique(x$Project), 
         Project_j = unique(x$Project)) 
    # omit if 101 102 is different from 102 101; make `<` if 101 101 not possible 
    x2[x2$Project_i <= x2$Project_j,] 
})) 

#  ID Week Project_i Project_j 
# 1 1.1 1 1  101  101 
# 1 1.4 1 1  101  102 
# 1 1.5 1 1  102  102 
# 1 1.7 1 1  101  103 
# 1 1.8 1 1  102  103 
# 1 1.9 1 1  103  103 
# 1 2.1 1 2  101  101 
# 1 2.3 1 2  101  102 
# 1 2.4 1 2  102  102 
# 2 1.1 2 1  101  101 
# 2 1.3 2 1  101  102 
# 2 1.4 2 1  102  102 
# 2 2 2 2  101  101