【问题标题】:Match a vector to a list of vectors将向量与向量列表匹配
【发布时间】:2014-02-08 06:28:21
【问题描述】:

我有一个向量列表lis,我需要将其匹配到另一个向量vec

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

所以要么我会得到一个逻辑输出

 [1] FALSE  TRUE  FALSE  FALSE  FALSE  FALSE

或者只是匹配的lis内的位置

我一直在尝试这些方面:

unlist(lis) %in% vec

但问题是数字的位置很重要,即区分c(1,1,0)c(1,0,1),这是我无法做到的。我想避免for 循环,因为这需要非常高效(快速)。

【问题讨论】:

    标签: r list vector


    【解决方案1】:

    @agstudy 和@Julius 的答案涉及(长)lis 对象的循环;这是一个替代方法,假设 lis 的所有元素与 vec 的长度相同,以允许对未列出的参考进行矢量比较

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

    lisvec 长时速度更快。

    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
    

    有趣的是,与lapply 中的隐式循环相比,从性能角度来看,使用for 并没有那么糟糕(尽管更复杂且容易出错)

    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
    

    【讨论】:

    • +1 - 你总是给出很好的答案,但是在所有开车投票的投票者完成之后,往往没有得到你应得的荣誉。创造性的解决方案。
    【解决方案2】:
    sapply(lis, identical, vec)
    # [1] FALSE  TRUE FALSE FALSE FALSE FALSE
    

    基准测试:

    l1 <- list(1:1000)[rep(1, 10000)]
    v1 <- sample(1000)
    AG <- function() sapply(l1,function(x)all(x==v1))
    J <- function() sapply(l1, identical, v1)
    microbenchmark(AG(), J())
    # Unit: milliseconds
    #  expr      min       lq    median        uq      max neval
    #  AG() 76.42732 84.26958 103.99233 111.62671 148.2824   100
    #   J() 32.14965 37.54198  47.34538  50.93195 104.4036   100
    

    【讨论】:

      【解决方案3】:
      sapply(lis,function(x)all(x==vec))
      [1] FALSE  TRUE FALSE FALSE FALSE FALSE
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-23
        • 2014-02-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多