【问题标题】:Return last match from vector从向量返回最后一个匹配
【发布时间】:2025-12-08 21:30:01
【问题描述】:

有没有一种简单的方法来获取向量最后一次匹配的索引?

lastInflectionRow(c(TRUE,FALSE,TRUE,FALSE,FALSE))

lastInflectionRow<-function(temp){
    m<-match(TRUE,temp,nomatch=NA)
    m
}

目标:3

【问题讨论】:

    标签: r


    【解决方案1】:

    另一种简单的方法是在TRUE 元素的索引上使用max

    x <- c(TRUE,FALSE,TRUE,FALSE,FALSE)
    
    max(which(x))
    
    #[1] 3
    

    【讨论】:

      【解决方案2】:

      ?Position 在使用 right=TRUE 参数时用于此类事情。以下所有内容应该基本上是等价的。

      Position(I, x, right=TRUE)
      #[1] 3
      Position(identity, x, right=TRUE)
      #[1] 3
      Position(isTRUE, x, right=TRUE)
      #[1] 3
      Position(function(x) x, x, right=TRUE)
      #[1] 3
      

      【讨论】:

      • "x" 是“逻辑的”,另一种选择是 Position(function(x) x, x, right = TRUE) 以避免一些“==”比较。此外,Position 的优点是在第一次匹配之前扫描尽可能少的“x”;类似的解决方案(在 R 3.3.0 中)是 match(TRUE, rev(x)),它只执行线性搜索直到第一个匹配。
      • @alexis_laz - 好点 - 这意味着 Position(I, x, right=TRUE)Position(identity, x, right=TRUE) 也应该适用于合乎逻辑的情况。
      • @RichScriven - 和 Position(`{`, x, right=TRUE) 显然 - 尽管我们正在滥用语法:-D
      【解决方案3】:

      如果我们与单个元素进行比较,我们可以使用==

      tail(which(v1 == TRUE),1)
      #[1] 3
      

      == 部分不是必需的,因为向量是逻辑的

      tail(which(v1),1)
      #[1] 3
      

      注意:这里我假设 OP 的向量可能并不总是 TRUE/FALSE 值,如示例中所示。

      如果我们需要使用match,可以提到一个选项here

      数据

      v1 <- c(TRUE,FALSE,TRUE,FALSE,FALSE)
      

      【讨论】:

        【解决方案4】:

        如果性能是一个考虑因素,那么我发现这样做的最佳方法是

        length(x) + 1L - match(TRUE, rev(x))
        

        这要快得多,尤其是在一般情况下,希望对多个条目进行最右边的匹配。

        MatchLast <- function (needles, haystack) # This approach
          length(haystack) + 1L - match(needles, rev(haystack))  
        
        MaxWhich <- function (needles, haystack)  # Ronak Shah's approach
          vapply(needles, function (needle) max(which(haystack==needle)), integer(1))
        
        Pos <- function (needles, haystack)       # thelatemail's suggestion
          vapply(needles, function (needle) 
            Position(function (x) x == needle, haystack, right=TRUE),
            integer(1))
        
        Tail <- function (needles, haystack)      # akrun's solution
          vapply(needles, function (needle) tail(which(haystack==needle), 1), integer(1))
        

        使用 Rilkon42 的数据:

        x <- c(TRUE, FALSE, TRUE, FALSE, FALSE)
        microbenchmark(MatchLast(TRUE, x), MaxWhich(TRUE, x), Pos(TRUE, x), Tail(TRUE, x))
        
        ##  function    min      lq     mean  median      uq       max
        ## MatchLast 10.730 19.1270 175.3851 23.7920  28.458 14757.131   
        ##  MaxWhich 11.663 22.1600 275.4657 25.1920  28.224 24355.120       
        ##       Pos 25.192 47.5845 194.1296 52.7160  64.612 12890.622  
        ##      Tail 39.187 69.7435 223.1278 83.0395 101.233  9223.848  
        

        在更一般的情况下:

        needles <- 24:45
        haystack <- c(45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 40, 40, 39, 39, 38, 38, 37, 37,
          36, 36, 35, 35, 34, 34, 33, 33, 32, 32, 31, 31, 30, 30, 29, 29, 28, 28,
          27, 27, 26, 26, 25, 25, 24, 24)
        
        microbenchmark(MatchLast(needles, haystack), MaxWhich(needles, haystack),
                       Pos(needles, haystack), Tail(needles, haystack))
        
        ##  function     min       lq      mean    median       uq      max
        ## MatchLast  15.395  30.3240  137.3086   36.8550   48.051 9842.441
        ##  MaxWhich  90.971 102.1665  161.1100  172.3765  214.829  238.854
        ##       Pos 709.563 733.8220 1111.7000 1162.7780 1507.530 1645.383
        ##      Tail 654.981 690.2035 1017.7400  882.6385 1404.197 1595.933
        

        【讨论】: