Match a vector to a list of vectors

前端 未结 3 469
情话喂你
情话喂你 2021-01-17 11:35

I have a list of vectors lis which I need to match to another vector vec

lis <- list(c(2,0,0),c(1,1,0), c(1,0,1), c(0,2,0), c(0,         


        
3条回答
  •  礼貌的吻别
    2021-01-17 12:10

    The answers by @agstudy and @Julius involve a loop over the (long) lis object; here's an alternative assuming that all elements of lis are the same length as vec to allow vector comparison of the unlisted reference

    shortloop <- function(x, lst)
        colSums(matrix(unlist(lst) == x, length(x))) == length(x)
    

    which is fast when lis is long compared to vec.

    longloop <- function(x, lst)
        sapply(lst, identical, x)
    
    l1 = rep(lis, 1000)
    microbenchmark(shortloop(vec, l1), longloop(vec, l1))
    ## Unit: microseconds
    ##                expr       min         lq    median         uq      max neval
    ##  shortloop(vec, l1)   793.009   808.2175   896.299   905.8795  1058.79   100
    ##   longloop(vec, l1) 18732.338 21649.0770 21797.646 22107.7805 24788.86   100
    

    Interestingly, using for is not that bad from a performance perspective compared to the implicit loop in lapply (though more complicated and error-prone)

    longfor <- function(x, lst) {
        res <- logical(length(lst))
        for (i in seq_along(lst))
            res[[i]] = identical(x, lst[[i]])
        res
    }
    library(compiler)
    longforc = cmpfun(longfor)
    microbenchmark(longloop(vec, l1), longfor(vec, l1), longforc(vec, l1))
    ## Unit: milliseconds
    ##               expr      min       lq   median       uq      max neval
    ##  longloop(vec, l1) 18.92824 21.20457 21.71295 21.80009 23.23286   100
    ##   longfor(vec, l1) 23.64756 26.73481 27.43815 27.61699 28.33454   100
    ##  longforc(vec, l1) 17.40998 18.28686 20.47844 20.75303 21.49532   100
    

提交回复
热议问题