2016-10-12 11 views
6

Oto powtarzalny przykład moich danych. Na poniższej ramce danych:Dodawanie kolumny do ramki danych w R na podstawie pozycji innej kolumny

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

Chciałbym dodać kolumnę „rangi”, która stanowi pozycję dla SNR według tematu, tak że będzie ona wyglądać tak:

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 

Próbowałem przy użyciu:

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

Ale mam następujące:

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 

Próbowałem również używać różnych opcji ties.method, ale żadna nie daje mi tego, czego szukam (tj. Tylko w rankingu od 1-3).

Każda pomoc będzie bardzo ceniona!

+4

Spróbuj z 'dplyr :: dense_rank'. Lub po prostu użyj jego kodu, jeśli nie chcesz używać pakietu; to tylko dwie linie podstawowego kodu R. –

+2

'function (x) as.numeric (factor (x))' zadziałałoby przy twojej próbie. lub po prostu "factor (x)", ponieważ ave będzie zmuszać do powrotu do typu 'SNR' tak czy inaczej – rawr

+0

Dziękuję @rawr, który załatwił sprawę. – Rmg

Odpowiedz

2

Korzystanie aggregate i factor w podstawowej 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

trochę brudna, ale wydaje się działać:

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, czy to źle? – Haboryme

+0

Nie mój głos, ale domyślam się, że to dlatego, że tak naprawdę nie trzeba ładować paczki, aby dodać kolumnę. –

+0

Cóż, musisz załadować dplyra, jeśli nie używasz go regularnie, uważam, że głosowanie w dół (nie przeze mnie) było spowodowane liczbą (jak. Czynnik()) .. ale to trochę pedantyczne – infominer

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

kredytu kurs @ bogatym-Scriven dla wspomnieć dense_rank()

2

Inna podstawowa metoda R:

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

daje:

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 

Jeśli dataframe jeszcze nie zamówił, należy go zamówić najpierw df1 <- df1[order(df1$SNR),] dla tej metody, aby dać poprawny wynik.