Добавить столбец "ранг" в кадр данных
У меня есть dataframe с количеством разных элементов, в разные годы:
df <- data.frame(item = rep(c('a','b','c'), 3),
year = rep(c('2010','2011','2012'), each=3),
count = c(1,4,6,3,8,3,5,7,9))
И я хотел бы добавить столбец "year.rank", который дает ранжирование позиции в течение данного года, где более высокий счет ведет к более высокому "рангу". С вышесказанным это будет выглядеть так:
item year count year.rank
1 a 2010 1 3
2 b 2010 4 2
3 c 2010 6 1
4 a 2011 3 2
5 b 2011 8 1
6 c 2011 3 3
7 a 2012 5 3
8 b 2012 7 2
9 c 2012 9 1
Я знаю, что могу сделать это для всего фрейма данных, используя order(df$count)
, но я не уверен, как бы это сделать в год.
Ответы
Ответ 1
Существует функция rank
, которая поможет вам в этом:
transform(df,
year.rank = ave(count, year,
FUN = function(x) rank(-x, ties.method = "first")))
item year count year.rank
1 a 2010 1 3
2 b 2010 4 2
3 c 2010 6 1
4 a 2011 3 2
5 b 2011 8 1
6 c 2011 3 3
7 a 2012 5 3
8 b 2012 7 2
9 c 2012 9 1
Ответ 2
data.table
версия для практики:
library(data.table)
DT <- as.data.table(df)
DT[,yrrank:=rank(-count,ties.method="first"),by=year]
item year count yrrank
1: a 2010 1 3
2: b 2010 4 2
3: c 2010 6 1
4: a 2011 3 2
5: b 2011 8 1
6: c 2011 3 3
7: a 2012 5 3
8: b 2012 7 2
9: c 2012 9 1
Ответ 3
Используя функцию order
,
transform(dat, x= ave(count,year,FUN=function(x) order(x,decreasing=T)))
item year count x
1 a 2010 1 3
2 b 2010 4 2
3 c 2010 6 1
4 a 2011 3 2
5 b 2011 8 1
6 c 2011 3 3
7 a 2012 5 3
8 b 2012 7 2
9 c 2012 9 1
ИЗМЕНИТЬ
Здесь вы также можете использовать plyr
:
ddply(dat,.(year),transform,x = order(count,decreasing=T))
Ответ 4
Используя dplyr, вы можете сделать это следующим образом:
library(dplyr) # 0.4.1
df %>%
group_by(year) %>%
mutate(yrrank = row_number(-count))
#Source: local data frame [9 x 4]
#Groups: year
#
# item year count yrrank
#1 a 2010 1 3
#2 b 2010 4 2
#3 c 2010 6 1
#4 a 2011 3 2
#5 b 2011 8 1
#6 c 2011 3 3
#7 a 2012 5 3
#8 b 2012 7 2
#9 c 2012 9 1
Это то же самое, что:
df %>%
group_by(year) %>%
mutate(yrrank = rank(-count, ties.method = "first"))
Обратите внимание, что полученные данные по-прежнему группируются по "году". Если вы хотите удалить группировку, вы можете просто расширить канал с помощью %>% ungroup()
.
Ответ 5
Используя ответы, полученные другими, я обнаружил, что следующее выполняется быстрее, чем варианты преобразования и dyplr:
df$year.rank <- ave(count, year, FUN = function(x) rank(-x, ties.method = "first"))