我有一个看起来像这样的矢量:
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开始)。
答案 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"
的不同序列被分组到不同的组