为数据框添加一个“等级”列
我在不同的年份有不同项目的数据框:
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)
来完成整个数据框的工作,但是我不知道如何按年完成。
有一个rank
function来帮助你:
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
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
使用order
function,
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))
使用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()
扩展pipe道。
当使用别人给出的答案时,我发现以下执行速度比变换和dyplr变种更快:
df$year.rank <- ave(count, year, FUN = function(x) rank(-x, ties.method = "first"))