6

我有一些数据:

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

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

我需要创建一个新的等级列,“第一”、“第二”、“第三”,之后的任何内容都可以留空,并且需要考虑平局。所以在上述情况下,我想得到以下输出:

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

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

4

2 回答 2

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 所说,有很多方法可以做到这一点......)

于 2013-06-13T22:51:07.500 回答
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)
于 2013-06-13T22:36:00.087 回答