2015-08-03 12 views
8

Ich habe einige monatliche Daten und möchte meinem Datenrahmen eine Spalte hinzufügen, die den kleinsten Wert in der ersten Spalte dem größten Wert in der ersten Spalte zuordnet. Der zweiten kleinste Wert in der ersten Spalte in dem zweitgrößten Wert in der ersten Spalte, ect ...Hinzufügen einer sortierten Spalte zum Datenrahmen

Hier einige Beispieldaten

x1<-c(100,151,109,59,161,104,170,101) 
dat<-data.frame(x1) 
rownames(dat)<-c('Apr','May', 'Jun','Jul', 'Aug', 'Sep', 'Oct', 'Nov') 

    x1 
Apr 100 
May 151 
Jun 109 
Jul 59 
Aug 161 
Sep 104 
Oct 170 
Nov 101 

Ich versuche, meine Daten zu erhalten, wie dies

aussehen
 x1 x2 
Apr 100 161 
May 151 101 
Jun 109 104 
Jul 59 170 
Aug 161 100 
Sep 104 109 
Oct 170 59 
Nov 101 151 

Ich gehe in Kreisen mit Rang, Art und Reihenfolge. Jede Hilfe wäre willkommen.

Antwort

6

Es ist relativ einfach, wenn Sie ein temporäres Objekt erstellen, das die aufsteigende hat und absteigenden Werte gepaart:

> temp <- data.frame(asc =x1[order(x1)],desc=x1[rev(order(x1))]) 
> dat$x2 <- temp$desc[ match(dat$x1, temp$asc) ] 
> dat 
    x1 x2 
Apr 100 161 
May 151 101 
Jun 109 104 
Jul 59 170 
Aug 161 100 
Sep 104 109 
Oct 170 59 
Nov 101 151 

DieDie Funktionwurde entwickelt, um ganzzahlige Indizierungswerte zu konstruieren, die als Argumente für "[" verwendet werden. Es ist die grundlegende Funktion innerhalb merge.

4

Die Nutzung der Basis R month.abb

df = dat[order(dat$x1),, drop = FALSE] 
df$x2 = sort(x1,decreasing = T) 
df[match(month.abb, rownames(df), nomatch = 0),] 

#  x1 x2 
#Apr 100 161 
#May 151 101 
#Jun 109 104 
#Jul 59 170 
#Aug 161 100 
#Sep 104 109 
#Oct 170 59 
#Nov 101 151 

data.table Mit einfach

library(data.table) 
df = setDF(setDT(dat, keep.rownames=T)[order(x1), x2 := sort(x1, decreasing = T)]) 
rownames(df) = df$rn; df[,1] = NULL 

#  x1 x2 
#Apr 100 161 
#May 151 101 
#Jun 109 104 
#Jul 59 170 
#Aug 161 100 
#Sep 104 109 
#Oct 170 59 
#Nov 101 151 
4

ähnliche Idee wie @BondedDust:

library(dplyr) 
dat %>% mutate(x2 = x1[match(row_number(desc(x1)), row_number(x1))]) 

Welche gibt:

# x1 x2 
#1 100 161 
#2 151 101 
#3 109 104 
#4 59 170 
#5 161 100 
#6 104 109 
#7 170 59 
#8 101 151 
3

Ansatz in data.table:

library(data.table) 
setDT(dat,keep.rownames=T)[order(x1),x2:=rev(x1)] 
    rn x1 x2 
1: Jul 59 170 
2: Apr 100 161 
3: Nov 101 151 
4: Sep 104 109 
5: Jun 109 104 
6: May 151 101 
7: Aug 161 100 
8: Oct 170 59 

Wenn Sie mit den Zeilen wollen, um am Ende, Ich denke, der einfachste Weg ist, month.abb als die Ebenen von rn a zu verwenden s ein Faktor:

setDT(dat,keep.rownames=T)[order(x1),x2:=rev(x1) 
          ][order(factor(rn,levels=month.abb))] 
    rn x1 x2 
1: Apr 100 161 
2: May 151 101 
3: Jun 109 104 
4: Jul 59 170 
5: Aug 161 100 
6: Sep 104 109 
7: Oct 170 59 
8: Nov 101 151 

auch order(match(rn,month.abb)) stattdessen verwenden könnte, wenn das zu Ihnen passt; wenn Sie vorhaben, eine Menge von Monat zu Umsortieren, kann es Sinn macht rn als Faktor zu definieren, so dass Sie nicht zu tun haben, die match oder factor Hund und Pony Show wiederholt: dat[,rn:=factor(rn,levels=month.abb)][order(rn)]

+2

Die ursprüngliche Reihenfolge sollte am Ende wiederhergestellt werden, nicht? – Frank

+0

Nicht unbedingt, aber ich füge eine Änderung hinzu, um das zu tun. – MichaelChirico

+0

@VeerendraGadekar hinzugefügt Bonus: nicht mehr benötigen die Entwicklungsversion von 'data.table', um meinen Code zu verwenden (glaube ich ...) – MichaelChirico

Verwandte Themen