添加一列排名

时间:2013-06-13 22:22:08

标签: r ranking

我有一些数据:

test <- data.frame(A=c("aaabbb",
"aaaabb",
"aaaabb",
"aaaaab",
"bbbaaa")
)

等等。所有元素都是相同的长度,并且在我得到之前已经排序。

我需要建立一个新的行列,“第一”,“第二”,“第三”,之后的任何内容都可以留空,并且需要考虑关系。所以在上面的例子中,我想获得以下输出:

   A       B
 aaabbb  First
 aaaabb  Second
 aaaabb  Second
 aaaaab  Third
 bbbaaa
 bbbbaa  

我查看了rank()和其他一些使用它的帖子,但我无法让它去做我想要的。

2 个答案:

答案 0 :(得分:3)

这个怎么样:

test$B <- match(test$A , unique(test$A)[1:3] )
test
       A  B
1 aaabbb  1
2 aaaabb  2
3 aaaabb  2
4 aaaaab  3
5 bbbaaa NA
6 bbbbaa NA

执行此操作的众多方法之一。可能不是最好的,但是很容易让人想起并且相当直观。您可以使用unique,因为您收到了预先排序的数据。

在对数据进行排序时,另一个值得考虑的合适函数是rle,尽管在这个例子中它稍微有些迟钝:

rnk <- rle(as.integer(df$A))$lengths
rnk
# [1] 1 2 1 1 1
test$B <- c( rep( 1:3 , times = rnk[1:3] ) , rep(NA, sum( rnk[-c(1:3)] ) ) )

rle计算向量中相等值运行的长度(以及我们并不真正关心的值) - 所以这也是有效的,因为您的数据已经被排序了。

如果你没有 在排名第三的项目之后有空白它甚至更简单(也更可读):

test$B <- rep(1:length(rnk),times=rnk)

答案 1 :(得分:3)

这似乎是一个很好的应用因素:

test$B <- as.numeric(factor(test$A, levels = unique(test$A)))

cumsum也会浮现在脑海中,每当值发生变化时我们都会添加1

test$B <- cumsum(c(TRUE, tail(test$A, -1) != head(test$A, -1)))

(就像@Simon说的,有很多方法可以做到这一点......)