将矢量与矢量列表匹配

cry*_*405 15 r list vector

我有一个向量列表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)
Run Code Online (Sandbox Code Playgroud)

所以我要么得到合理的输出

 [1] FALSE  TRUE  FALSE  FALSE  FALSE  FALSE
Run Code Online (Sandbox Code Playgroud)

或者只是lis比赛中的位置

我一直在尝试这些方面:

unlist(lis) %in% vec
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*gan 12

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

shortloop <- function(x, lst)
    colSums(matrix(unlist(lst) == x, length(x))) == length(x)
Run Code Online (Sandbox Code Playgroud)

lis与...相比,这是很快的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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

  • +1 - 你总是给出很好的答案,但是在所有的驱逐选民完成之后,所以经常没有得到你应得的信誉.创造性的解决方案. (4认同)

Jul*_*ora 9

sapply(lis, identical, vec)
# [1] FALSE  TRUE FALSE FALSE FALSE FALSE
Run Code Online (Sandbox Code Playgroud)

基准测试:

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
Run Code Online (Sandbox Code Playgroud)


ags*_*udy 7

sapply(lis,function(x)all(x==vec))
[1] FALSE  TRUE FALSE FALSE FALSE FALSE
Run Code Online (Sandbox Code Playgroud)