I have a dataframe with counts of different items, in different years:
我有一个不同项目、不同年份的数据aframe:
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))
And I would like to add a "year.rank" column, which gives an item's rank within a given year, where a higher count leads to a higher "rank". With the above, it would look like:
我想加上“一年”。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
I know I could do this for the whole data frame using order(df$count)
, but I'm not sure how I would do it by year.
我知道我可以使用order(df$count)对整个数据帧执行此操作,但我不确定如何按年执行。
5 个解决方案
#1
32
There is a rank
function to help you with that:
有一个等级函数可以帮助你:
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
24
data.table
version for practice:
数据。表版本实践:
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
9
Using 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
EDIT
编辑
You can use plyr
here also:
你也可以在这里使用plyr:
ddply(dat,.(year),transform,x = order(count,decreasing=T))
#4
8
Using dplyr you could do it as follows:
使用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
It is the same as:
它等于:
df %>%
group_by(year) %>%
mutate(yrrank = rank(-count, ties.method = "first"))
Note that the resulting data is still grouped by "year". If you want to remove the grouping you can simply extend the pipe with %>% ungroup()
.
注意,结果数据仍然按“年”分组。如果您想要删除分组,您可以只使用%>% ungroup()来扩展管道。
#5
1
While using the answers given by others, I found that the following performs faster than the transform and dyplr variants:
在使用别人给出的答案时,我发现下面的结果比转换和dyplr变体表现得更快:
df$year.rank <- ave(count, year, FUN = function(x) rank(-x, ties.method = "first"))
#1
32
There is a rank
function to help you with that:
有一个等级函数可以帮助你:
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
24
data.table
version for practice:
数据。表版本实践:
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
9
Using 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
EDIT
编辑
You can use plyr
here also:
你也可以在这里使用plyr:
ddply(dat,.(year),transform,x = order(count,decreasing=T))
#4
8
Using dplyr you could do it as follows:
使用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
It is the same as:
它等于:
df %>%
group_by(year) %>%
mutate(yrrank = rank(-count, ties.method = "first"))
Note that the resulting data is still grouped by "year". If you want to remove the grouping you can simply extend the pipe with %>% ungroup()
.
注意,结果数据仍然按“年”分组。如果您想要删除分组,您可以只使用%>% ungroup()来扩展管道。
#5
1
While using the answers given by others, I found that the following performs faster than the transform and dyplr variants:
在使用别人给出的答案时,我发现下面的结果比转换和dyplr变体表现得更快:
df$year.rank <- ave(count, year, FUN = function(x) rank(-x, ties.method = "first"))