2016-10-12 5 views
6

Hier ist ein reproduzierbares Beispiel meiner Daten. Für die folgenden Datenrahmen:Hinzufügen einer Spalte zu einem Datenrahmen in R basierend auf dem Rang einer anderen Spalte

df <- data.frame(Subject = c('John', 'John', 'John', 'John','Mary', 'Mary', 'Mary', 'Mary'), 
       SNR = c(-4,-4,0,4,0,4,4,8)) 

würde Ich mag eine Spalte ‚Rang‘ hinzuzufügen, die ein Ranking für SNR nach Thema bietet, so dass es wie folgt aussehen:

Subject SNR Rank 
John  -4 1 
John  -4 1 
John  0 2 
John  4 3 
Mary  0 1 
Mary  4 2 
Mary  4 2 
Mary  8 3 

ich versucht habe, Verwendung:

dfNew <- transform(df, Rank = ave(SNR, Subject, FUN = function(x) rank(x, ties.method = "first"))) 

Aber ich folgendes:

Subject SNR Rank 
John  -4 1 
John  -4 2 
John  0 3 
John  4 4 
Mary  0 1 
Mary  4 2 
Mary  4 3 
Mary  8 4 

Ich habe auch versucht, die verschiedenen ties.method Optionen, aber keiner gibt mir, was ich suche (d. H. Ranking nur von 1-3).

Jede Hilfe wäre sehr willkommen!

+4

Versuchen Sie mit 'dplyr :: dicht_rank'. Oder verwenden Sie einfach den Code, wenn Sie kein Paket verwenden möchten. es sind nur zwei Zeilen des Basis-R-Codes. –

+2

'Funktion (x) as.numeric (Faktor (x))' würde in Ihrem Versuch arbeiten. oder einfach 'factor (x)' da ave sowieso auf die Art von 'SNR' zurückgreift – rawr

+0

Danke @rawr, das hat den Trick gemacht. – Rmg

Antwort

2

Mit aggregate und factor in Basis R:

ag <- aggregate(SNR~Subject, df, function(x) as.numeric(factor(x))) 
df$rank <- c(t(ag[,-1])) 

    Subject SNR rank 
1 John -4 1 
2 John -4 1 
3 John 0 2 
4 John 4 3 
5 Mary 0 1 
6 Mary 4 2 
7 Mary 4 2 
8 Mary 8 3 
1

ein bisschen schmutzig, aber es scheint zu funktionieren:

library(dplyr) 
df %>% group_by(Subject) %>% mutate(Rank = as.numeric(as.factor(SNR))) 

    Subject SNR Rank 
    <fctr> <dbl> <dbl> 
1 John -4  1 
2 John -4  1 
3 John  0  2 
4 John  4  3 
5 Mary  0  1 
6 Mary  4  2 
7 Mary  4  2 
8 Mary  8  3 
+0

Downvote, ist das falsch? – Haboryme

+0

Nicht meine Stimme, aber ich vermute, es ist, weil Sie nicht wirklich ein Paket laden müssen, um eine Spalte hinzuzufügen. –

+0

Nun, Sie müssen dplyr laden, wenn Sie es nicht regelmäßig verwenden, ich denke, die down-Abstimmung (nicht von mir) war wegen as.numeric (as.factor()) .. aber das ist immer noch ein bisschen pedantisch – infominer

1
library(dplyr)  
df %>% 
    arrange(Subject, SNR) %>% 
    group_by(Subject) %>% 
    mutate(rank=dense_rank(SNR)) 

natürlich Kredit @ Rich-scriven für dense_rank() erwähnen

2

Eine andere Basis-R-Methode:

transform(df1, Rank = ave(SNR, Subject, FUN = function(x) cumsum(c(TRUE, head(x, -1) != tail(x, -1))))) 

gibt:

Subject SNR Rank 
1 John -4 1 
2 John -4 1 
3 John 0 2 
4 John 4 3 
5 Mary 0 1 
6 Mary 4 2 
7 Mary 4 2 
8 Mary 8 3 

Wenn Ihr Datenrahmen noch nicht bestellt ist, sollten Sie es zunächst für diese Methode mit df1 <- df1[order(df1$SNR),] bestellen das richtige Ergebnis zu geben.

Verwandte Themen