首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >查找向量中最后一次出现的唯一元素的索引

查找向量中最后一次出现的唯一元素的索引
EN

Stack Overflow用户
提问于 2015-01-06 23:16:45
回答 8查看 6.8K关注 0票数 17

我有一个无序向量v,就像下面显示的那样,希望找到列表中每个唯一元素的最后一次出现的索引。

代码语言:javascript
复制
v <- scan(text="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")
v
# [1] 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 
# [41] 1 4 4 4 3 2 5 5 5 5

预期结果(按1、2、3、4、5的顺序):

代码语言:javascript
复制
41 46 45 44 50

我知道我可以使用unique(unlist(v))来找到唯一的元素,但是如何找到它们最后出现的索引呢?有什么想法吗?

提前谢谢。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2015-01-06 23:31:55

另一种即使数据没有排序也有效的方法:

代码语言:javascript
复制
length(v1)-match(unique(v1),rev(v1))+1
票数 21
EN

Stack Overflow用户

发布于 2015-01-07 00:24:42

代码语言:javascript
复制
tapply(seq_along(v), v, max)
#  1  2  3  4  5  6 
# 41 46 45 44 50 27 
票数 10
EN

Stack Overflow用户

发布于 2015-01-06 23:19:11

如果vector已经订购,您可以尝试rle。提取长度($lengths),然后提取cumsum。正如我前面提到的,如果没有订购,这将不起作用(同样,这取决于你真正想要的)。基本上,rle通过检查拉伸上相似的连续元素的数量来工作。它将在列表中给出lengths和相应的values

代码语言:javascript
复制
cumsum(rle(v1)$lengths)
#[1] 28 37 42 46 50

另一种选择是按向量对序列进行分组,并获取每个groupmax值。我认为这是一个缓慢的过程。

代码语言:javascript
复制
unname(cumsum(tapply(seq_along(v1),v1, FUN=which.max)))    
#[1] 28 37 42 46 50

或者只检查前一个值与当前值是否相同,然后插入TRUE作为最后一个元素,用which得到TRUE的索引

代码语言:javascript
复制
 which(c(v1[-1]!=v1[-length(v1)],TRUE))
 #[1] 28 37 42 46 50

或者使用match

代码语言:javascript
复制
 c(match(unique(v1),v1)-1, length(v1))[-1]
#[1] 28 37 42 46 50

或者使用findInterval

代码语言:javascript
复制
 findInterval(unique(v1), v1)
 #[1] 28 37 42 46 50

更新

对于新的矢量v2

代码语言:javascript
复制
max.col(t(sapply(unique(v2), `==`, v2)),'last')
#[1] 41 46 45 44 50 27

或者在ordering无序向量之后使用findInterval的函数

代码语言:javascript
复制
   f1 <- function(v){
      v1 <- setNames(v, seq_along(v))
      ind <- order(v1)
      as.numeric(names(v1[ind][findInterval(unique(v1), v1[ind])]))
    }     

 f1(v2)
 #[1] 41 46 45 44 50 27

使用@Marat talipov的帖子中的示例(z),

代码语言:javascript
复制
 f1(z)
 #[1] 4 5 3

注意:我按照唯一元素首次出现在z中的顺序得到结果。即1,然后是32。如果需要根据值重新排序,可以使用order (如@Marat Talipov所述)来完成。然而,在这种情况下,还不清楚OP真正想要什么。

数据

代码语言:javascript
复制
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)
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27801589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档