#r #dataframe
#r #фрейм данных
Вопрос:
Вот воспроизводимый пример моих данных. Для следующего фрейма данных:
df <- data.frame(Subject = c('John', 'John', 'John', 'John','Mary', 'Mary', 'Mary', 'Mary'),
SNR = c(-4,-4,0,4,0,4,4,8))
Я хотел бы добавить столбец ‘rank’, который обеспечивает ранжирование SNR по теме, чтобы он выглядел так:
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
Я пытался использовать:
dfNew <- transform(df, Rank = ave(SNR, Subject, FUN = function(x) rank(x, ties.method = "first")))
Но я получаю следующее:
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
Я также пытался использовать разные варианты ties.method, но ни один из них не дает мне то, что я ищу (т. Е. ранжирование только с 1-3).
Любая помощь будет высоко оценена!
Комментарии:
1. Попробуйте с
dplyr::dense_rank
помощью . Или просто используйте его код, если вы не хотите использовать пакет; это всего две строки базового кода R.2.
function(x) as.numeric(factor(x))
сработает в вашей попытке. или простоfactor(x)
, поскольку ave в любом случае принудительно вернется к типуSNR
3. Спасибо @rawr, это сделало свое дело.
Ответ №1:
Использование aggregate
и factor
в базе 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
Ответ №2:
Другой базовый метод R:
transform(df1, Rank = ave(SNR, Subject, FUN = function(x) cumsum(c(TRUE, head(x, -1) != tail(x, -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
Если ваш фрейм данных еще не упорядочен, вы должны сначала упорядочить его с df1 <- df1[order(df1$SNR),]
помощью этого метода, чтобы получить правильный результат.
Ответ №3:
library(dplyr)
df %>%
arrange(Subject, SNR) %>%
group_by(Subject) %>%
mutate(rank=dense_rank(SNR))
конечно, спасибо @rich-scriven за упоминание dense_rank()
Ответ №4:
Немного грязно, но, похоже, работает:
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
Комментарии:
1. Не мой голос, но я предполагаю, что это потому, что вам действительно не нужно загружать пакет для добавления столбца.
2. Ну, вам нужно загрузить dplyr, если вы не используете его регулярно, я считаю, что голосование против (не мной) было вызвано as.numeric(as.factor()) .. но все же это немного педантично