如果vector
已经排序,您可以尝试使用rle
。提取长度($lengths
),然后进行cumsum
。正如我之前提到的,如果没有排序,则这种方法行不通(根据您真正想要的结果而定)。基本上,rle
通过检查一段连续的元素中有多少个相似来运作。它将在列表中给出lengths
和相应的values
。
cumsum(rle(v1)$lengths)
另一种选择是按向量对序列进行分组,并获取每个组的
max
值。我想这可能会很慢。
unname(cumsum(tapply(seq_along(v1),v1, FUN=which.max)))
或者只需检查前一个值是否与当前值相同,然后将 TRUE
插入为最后一个元素,并使用 which
获取 TRUE
的索引。
which(c(v1[-1]!=v1[-length(v1)],TRUE))
或者使用
match
。
c(match(unique(v1),v1)-1, length(v1))[-1]
或者使用findInterval
findInterval(unique(v1), v1)
更新
对于新向量v2
max.col(t(sapply(unique(v2), `==`, v2)),'last')
或者在将无序向量排序后使用findInterval
函数
f1 <- function(v){
v1 <- setNames(v, seq_along(v))
ind <- order(v1)
as.numeric(names(v1[ind][findInterval(unique(v1), v1[ind])]))
}
f1(v2)
使用@Marat talipov帖子中的示例(z
),
f1(z)
#[1] 4 5 3
注意:我按照在z
中首次出现的唯一元素的顺序得到结果。即1
,后跟3
,2
。如果需要根据值重新排序,则可以使用order
(如@Marat Talipov所述)。但是,在这种情况下,不清楚OP真正想要什么。
数据
v1 <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3,
3, 4, 4, 4, 4, 5, 5, 5, 5)
v2 <- c(1, 2, 1, 2, 1, 1, 1, 3, 1, 2, 2, 3, 3, 3, 1, 1, 1, 4, 1, 1,
1, 4, 1, 5, 5, 6, 6, 2, 3, 3, 4, 4, 2, 2, 2, 2, 2, 3, 3, 3, 1,
4, 4, 4, 3, 2, 5, 5, 5, 5)
z <- c(1, 3, 2, 1, 3)
dput
非常方便)。 - A5C1D2H2I1M1N2O1R2T1