2017-08-04 6 views
5

Angenommen, ich habe zwei Datenrahmen, Schüler und Lehrer.Generieren Sie alle möglichen Kombinationen von Zeilen in R?

students <- data.frame(name = c("John", "Mary", "Sue", "Mark", "Gordy", "Joey", "Marge", "Sheev", "Lisa"), 
        height = c(111, 93, 99, 107, 100, 123, 104, 80, 95), 
        smart = c("no", "no", "yes", "no", "yes", "yes", "no", "yes", "no")) 
teachers <- data.frame(name = c("Ben", "Craig", "Mindy"), 
        height = c(130, 101, 105), 
        smart = c("yes", "yes", "yes")) 

Ich möchte alle möglichen Kombinationen von Schülern und Lehrern erzeugen und die begleitenden Informationen zu halten, erstellen Sie grundsätzlich alle Kombinationen von Zeilen aus Datenrahmen „Studenten“ und „Lehrer“. Dies kann leicht mit einer Schleife und Cbind getan werden, aber für einen massiven Datenrahmen dauert dies ewig. Helfen Sie einem R-Neuling - was ist der schnellste Weg, dies zu tun?

Edit: Ist dies nicht klar ist, möchte ich die Ausgabe folgendes Format haben:

rbind(
    cbind(students[1, ], teachers[1, ]), 
    cbind(students[1, ], teachers[2, ]) 
    ... 
    cbind(students[n, ], teachers[n, ])) 

Antwort

2

Sie können alle Daten kombinieren, wie unten:

do.call(cbind.data.frame,Map(expand.grid,teacher=teachers,students=students)) 

    name.teacher name.students height.teacher height.students smart.teacher smart.students 
1   Ben   John   130    111   yes    no 
2   Craig   John   101    111   yes    no 
3   Mindy   John   105    111   yes    no 
4   Ben   Mary   130    93   yes    no 
5   Craig   Mary   101    93   yes    no 
6   Mindy   Mary   105    93   yes    no 
:   :   :    :    :   :    : 
:   :   :    :    :   :    : 
2

und halten Sie die zugehörigen Informationen

würde ich empfehlen, dies nicht zu tun. Es ist nicht notwendig, alles in einem einzigen Objekt zu haben.

Um nur die Lehrer zu kombinieren und Studenten, gibt es

res = expand.grid(teacher_name = teachers$name, student_name = students$name) 

in den anderen Daten zusammenzuführen (was ich bis notwendig, nicht tun würde empfehlen):

res[, paste("teacher", c("height", "smart"), sep="_")] <- 
    teachers[match(res$teacher_name, teachers$name), c("height","smart")] 

res[, paste("student", c("height", "smart"), sep="_")] <- 
    students[match(res$student_name, students$name), c("height","smart")] 

Dies gibt

head(res) 

    teacher_name student_name teacher_height teacher_smart student_height student_smart 
1   Ben   John   130   yes   111   no 
2  Craig   John   101   yes   111   no 
3  Mindy   John   105   yes   111   no 
4   Ben   Mary   130   yes    93   no 
5  Craig   Mary   101   yes    93   no 
6  Mindy   Mary   105   yes    93   no 
+0

Side Anmerkung: die 'logical' Klasse ist für' zu bejahen ist/'no' Werte. Siehe '' logisch'. – Frank

+0

Nützliches Feature, aber für meinen aktuellen Zweck möchte ich alles in einem einzigen Objekt behalten –

+1

Oder verwenden Sie 'CJ' aus' data.table' – akrun

0

Sie können diese Funktion

verwenden
expand.grid.df <- function(...) Reduce(function(...) merge(..., by=NULL), list(...)) 

expand.grid.df(students,teachers) 
Verwandte Themen