2016-10-12 26 views
6

Dưới đây là ví dụ về dữ liệu của tôi có thể tái sản xuất. Đối với các khung dữ liệu sau:thêm cột vào khung dữ liệu trong R dựa trên thứ hạng của một cột khác

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

Tôi muốn thêm một cột chữ 'rank' mà cung cấp một bảng xếp hạng cho SNR theo chủ đề, do đó nó sẽ trông như thế này:

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 

Tôi đã cố gắng sử dụng:

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

Nhưng tôi nhận được như sau:

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 

Tôi cũng đã thử sử dụng các tùy chọn ties.method khác nhau, nhưng không có gì cho tôi những gì tôi đang tìm kiếm (tức là, chỉ xếp hạng từ 1-3).

Mọi trợ giúp sẽ được đánh giá cao!

+4

Hãy thử với 'dplyr :: dense_rank'. Hoặc chỉ sử dụng mã của nó nếu bạn không muốn sử dụng một gói; nó chỉ có hai dòng mã R cơ sở. –

+2

'Hàm (x) as.numeric (yếu tố (x))' sẽ hoạt động trong nỗ lực của bạn. hoặc chỉ 'yếu tố (x)' kể từ khi ave sẽ coerce trở lại loại 'SNR' anyway – rawr

+0

Cảm ơn bạn @rawr, đã làm các trick. – Rmg

Trả lời

2

Sử dụng aggregatefactor trong cơ sở 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

một chút bẩn nhưng nó dường như làm việc:

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, điều này có sai không? – Haboryme

+0

Không phải phiếu bầu của tôi, nhưng tôi đoán đó là vì bạn không thực sự cần tải gói để thêm cột. –

+0

Vâng, bạn phải tải dplyr nếu bạn không sử dụng nó thường xuyên, tôi nghĩ rằng bỏ phiếu xuống (không phải bởi tôi) là do as.numeric (as.factor()) .. nhưng vẫn còn đó là một chút pedantic – infominer

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

tín dụng khóa học để @ giàu Scriven đề cập đến dense_rank()

2

Phương thức R cơ bản khác:

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

cho:

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 

Nếu dataframe của bạn không yêu cầu chưa, bạn nên đặt nó đầu tiên với df1 <- df1[order(df1$SNR),] cho phương pháp này để cung cấp cho kết quả chính xác.

Các vấn đề liên quan