R: Увеличение ранга при изменении группы столбцов

Новичок в R, я пробовал гуглить, но не могу найти решение.

Вот мой фрейм данных:

Name          Value
Bob           50
Mary          55
John          51
Todd          50
Linda         56
Tom           55

Итак, я отсортировал его, но мне нужно добавить столбец рангов, поэтому он выглядит так:

Name          Value    Rank
Bob           50       1
Todd          50       1
John          51       2
Mary          55       3
Tom           55       3
Linda         56       4

Итак, что я нашел:

resultset$Rank <- ave(resultset$Name, resultset$Value, FUN = rank)

Но это дает мне:

Name          Value    Rank
Bob           50       1
Todd          50       2
John          51       1
Mary          55       1
Tom           55       2
Linda         56       1

Так близко, но так далеко...


person Ross R    schedule 01.05.2015    source источник


Ответы (3)


Вот решение base-R:

uv <- unique(df$Value)
merge(df,data.frame(uv,r=rank(uv)),by.x="Value",by.y="uv")

который дает

  Value  Name r
1    50   Bob 1
2    50  Todd 1
3    51  John 2
4    55  Mary 3
5    55   Tom 3
6    56 Linda 4

Это неэффективно с точки зрения использования памяти и имеет побочный эффект в виде обращения к вашим данным. Вы можете поочередно сделать:

require(data.table)
DT <- data.table(df)
DT[order(Value),r:=.GRP,by=Value]

который дает

    Name Value r
1:   Bob    50 1
2:  Mary    55 3
3:  John    51 2
4:  Todd    50 1
5: Linda    56 4
6:   Tom    55 3
person Frank    schedule 01.05.2015

Не нужно сортировать... Вы можете использовать dense_rank из "dplyr":

> library(dplyr)
> mydf %>% mutate(rank = dense_rank(Value))
   Name Value rank
1   Bob    50    1
2  Mary    55    3
3  John    51    2
4  Todd    50    1
5 Linda    56    4
6   Tom    55    3
person A5C1D2H2I1M1N2O1R2T1    schedule 01.05.2015

Я предполагаю, что ваша ранговая переменная может быть получена 1:length(unique(df$value)). Ниже мой тест.

df <- data.frame(name = c("Bob", "Mary", "John", "Todd", "Linda", "Tom"),
                 value = c(50, 55, 51, 50, 56, 55))
# rank by lengths of unique values
rank <- data.frame(rank = 1:length(unique(df$value)), value = sort(unique(df$value)))
merge(df, rank, by="value")
value  name rank
1    50   Bob    1
2    50  Todd    1
3    51  John    2
4    55  Mary    3
5    55   Tom    3
6    56 Linda    4
person Jaehyeon Kim    schedule 01.05.2015
comment
rank — это функция, поэтому вы, вероятно, не захотите повторно использовать это имя. Кроме того, наличие столбца с тем же именем, что и содержащий его data.frame, может сбивать с толку. - person Frank; 01.05.2015
comment
@ Фрэнк - Спасибо за ваш комментарий. Строго говоря, R ищет функции только среди функций, чтобы не ошибиться, если я запущу rank(rank$rank) — здесь только первая — это функция rank(). Однако я не отрицаю, что это хорошая практика - назначать другое имя | Я не думаю, что присвоение одного и того же имени фрейму данных и одному из имен столбцов сбивает с толку. Скорее, меня может сбить с толку присвоение разных имен разным вещам. - person Jaehyeon Kim; 01.05.2015