按唯一元素对值进行分组

时间:2016-05-03 14:02:54

标签: r

我有一个看起来像这样的矢量:

a <- c("A110","A110","A110","B220","B220","C330","D440","D440","D440","D440","D440","D440","E550")

我想创建另一个基于a的向量,它应该是:

b <- c(1,1,1,2,2,2,3,4,4,4,4,4,4,5)

换句话说,b应该为a的每个不同元素赋值(从1开始)。

1 个答案:

答案 0 :(得分:8)

首先,(我假设)这是你的载体

a <- c("A110","A110","A110","B220","B220","C330","D440","D440","D440","D440","D440","D440","E550")

根据可能的解决方案,这里很少(现在找不到好的傻瓜)

as.integer(factor(a))
# [1] 1 1 1 2 2 3 4 4 4 4 4 4 5

或者

cumsum(!duplicated(a))
# [1] 1 1 1 2 2 3 4 4 4 4 4 4 5

或者

match(a, unique(a))
# [1] 1 1 1 2 2 3 4 4 4 4 4 4 5

rle同样适用于特定方案

with(rle(a), rep(seq_along(values), lengths))
# [1] 1 1 1 2 2 3 4 4 4 4 4 4 5

或(实际上是相同的)

data.table::rleid(a)
# [1] 1 1 1 2 2 3 4 4 4 4 4 4 5

虽然被告知所有4种解决方案在不同场景中都有其独特的行为,但请考虑以下向量

a <- c("B110","B110","B110","A220","A220","C330","D440","D440","B110","B110","E550")

4种不同解决方案的结果:

1

as.integer(factor(a))
# [1] 2 2 2 1 1 3 4 4 2 2 5

factor解决方案以2开头,因为a未排序,因此第一个值在integer函数中获得更高的factor表示。因此,如果您的矢量已排序,此解决方案仅有效,因此请勿以其他方式使用它。

2

cumsum(!duplicated(a))
# [1] 1 1 1 2 2 3 4 4 4 4 5

这个cumsum/duplicated解决方案因为"B110"已经出现在开头而感到困惑,因此将"D440","D440","B110","B110"分组到同一组中。

3

match(a, unique(a))
# [1] 1 1 1 2 2 3 4 4 1 1 5

match/unique解决方案最后添加了一个,因为它对"B110"敏感,显示在多个序列中(因为unique),因此将它们全部归为同一组无论它们出现在哪里

4

with(rle(a), rep(seq_along(values), lengths))
# [1] 1 1 1 2 2 3 4 4 5 5 6

该解决方案仅关注序列,因此"B110"的不同序列被分组到不同的组