2010-10-21 24 views
6

Ich versuche, einen data.frame basierend auf mehreren Spalten in einem anderen zu sortieren. Diese Frage does this with vectors. Kann jemand einen Weg vorschlagen, das Äquivalent mit data.frames zu machen?R: Sortieren Sie mehrere Spalten nach einem anderen data.frame?

Hier sind einige Beispieldaten.

x1 <- data.frame(a=1:5, b=letters[1:5], c=rnorm(5)) 
x2 <- data.frame(a=c(4,4,2), b=c("d", "d", "b"), d=rnorm(3)) 

Also ich möchte x2 durch die ersten beiden Spalten von x1 sortieren. Meine aktuellen Daten ist viel komplizierter, aber das repliziert die Idee ...

Antwort

9

Es hängt wirklich davon ab, wie Ihre Daten wirklich aussehen. Wie es jetzt aussieht, müssen Sie nur eine Spalte zu sortieren, und das ist leicht getan durch:

x2[order(match(x2[,1],x1[,1])),] 

Wenn Sie mehr als eine Spalte benötigen, ist dies ein bisschen schwieriger wird. Sie müssen angeben, welche Sie zuerst auf sortieren wollen, und welche eine zweite, zum Beispiel:

x1 <- data.frame(a=rep(1:3,2), b=rep(letters[2:4],each=2), c=rnorm(6)) 
x2 <- data.frame(a=c(3,3,2), b=c("c", "d", "b"), d=rnorm(3)) 


x2[order(match(
    paste(x2[,1],x2[,2]), 
    paste(x1[,1],x1[,2])) 
),] 

Diese sortiert auf der ersten Spalte zuerst, und dann auf dem zweiten. Sie müssen daran denken, dass Sie alle Kombinationen in x2 auch in x1 benötigen. T

2

einen Rang Spalte auf den entsprechenden Spalten von x1 Attach:

len <- dim(x1)[1] 
x1. <- cbind(x1[,1:2], rank=1:len) 

Merge in x2 (das ist wie ein SQL verbinden, siehe die Zusammenführung Dokumentation, wie Sie angeben, was, wenn es passiert, Zweideutigkeiten wie mehrere Übereinstimmungen oder keine Übereinstimmungen sind):

x2. <- merge(x2, x1.) 

Sortieren:

x2.[order(x2.[,'rank']),] 
1

Dies kann mit plyr präzise durchgeführt werden. Joris' Antwort würde funktionieren ziemlich gut, aber möglicherweise missort könnte, wenn Strings kombinieren:

> paste ("A A","B") 
[1] "A A B" 
> paste ("A","A B") 
[1] "A A B" 

Sie können eine genaue Antwort erhalten mit join.keys und match:

x1 <- data.frame(a=rep(1:3,2), b=rep(letters[2:4],each=2), c=rnorm(6)) 
x2 <- data.frame(a=c(3,3,2), b=c("c", "d", "b"), d=rnorm(3)) 

library(plyr) 
keys<-join.keys(x1,x2,c("a","b")) 
matches<-match(keys$y,keys$x,nomatch=(keys$n+1)) 
x2[order(matches),] 

Dies sollte die meisten Rand Fällen nicht übereinstimmen Liste Griff Größen usw. Elemente ohne Übereinstimmung in den beiden Indexspalten werden am Ende der Liste eingefügt.

Verwandte Themen