向数据帧添加“rank”列

时间:2021-12-04 19:36:11

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"))