繁体   English   中英

R:在向量列表中找到向量

[英]R: find vector in list of vectors

我正在使用R,我的目标是检查一个给定的向量是否在一个独特的向量列表中。

该列表看起来像

final_states <- list(c("x" = 5, "y" = 1),
                 c("x" = 5, "y" = 2),
                 c("x" = 5, "y" = 3),
                 c("x" = 5, "y" = 4),
                 c("x" = 5, "y" = 5),
                 c("x" = 3, "y" = 5))

现在我想检查列表中的给定状态。 例如:

state <- c("x" = 5, "y" = 3)

如您所见,向量状态是列表final_states的元素。 我的想法是用%in%运算符检查它:

state %in% final_states

但我得到了这个结果:

[1] FALSE FALSE

谁能告诉我,有什么不对?

招呼,卢皮

如果您只想确定矢量是否在列表中,请尝试

Position(function(x) identical(x, state), final_states, nomatch = 0) > 0
# [1] TRUE

Position()基本上与match()类似,但在列表中。 如果你设置nomatch = 0并检查Position > 0 ,你会得到一个逻辑结果,告诉你state是否在final_states

“final_states”是一个“列表”,因此您可以将“状态”转换为list然后执行

final_states %in% list(state)
#[1] FALSE FALSE  TRUE FALSE FALSE FALSE

或者使用mapply来检查“state_states”的每个列表元素中是否存在“state”中的所有元素(假设vector和list元素的长度相同)

 f1 <- function(x,y) all(x==y)
 mapply(f1, final_states, list(state))
 #[1] FALSE FALSE  TRUE FALSE FALSE FALSE

rbind列表元素的矩阵,然后检查“M1”,“状态”和“行”是否相同。

m1 <- do.call(rbind, final_states)
!rowSums(m1!=state[col(m1)])
#[1] FALSE FALSE  TRUE FALSE FALSE FALSE

要么

 m1[,1]==state[1] & m1[,2]==state[2]
 #[1] FALSE FALSE  TRUE FALSE FALSE FALSE

更新

如果你需要一个TRUE/FALSE

  any(mapply(f1, final_states, list(state)))
  #[1] TRUE

要么

  any(final_states %in% list(state))
  #[1] TRUE

要么

 list(state) %in% final_states
 #[1] TRUE

或者使用“快” fmatchfastmatch

 library(fastmatch)
 fmatch(list(state), final_states) >0
 #[1] TRUE

基准

@Richard Sciven的base R功能是非常快的其他解决方案相比,除了一个与fmatch

 set.seed(295)
 final_states <- replicate(1e6, sample(1:20, 20, replace=TRUE), 
          simplify=FALSE)
 state <- final_states[[151]]


 richard <- function() {Position(function(x) identical(x, state),
              final_states, nomatch = 0) > 0}
 Bonded <- function(){any( sapply(final_states, identical, state) )}
 akrun2 <- function() {fmatch(list(state), final_states) >0}
 akrun1 <- function() {f1 <- function(x,y) all(x==y)
            any(mapply(f1, final_states, list(state)))}

 library(microbenchmark)
 microbenchmark(richard(), Bonded(), akrun1(), akrun2(), 
        unit='relative', times=20L)
 #Unit: relative
 #    expr          min           lq        mean      median          uq
 # richard()     35.22635     29.47587    17.49164    15.66833    14.58235
 # Bonded() 109440.56885 101382.92450 55252.86141 47734.96467 44289.80309
 # akrun1() 167001.23864 138812.85016 75664.91378 61417.59871 62667.94867
 # akrun2()      1.00000      1.00000     1.00000     1.00000     1.00000
  #          max neval cld
  #     14.62328    20 a  
  #  46299.43325    20 b 
  #  63890.68133    20 c
  #      1.00000    20 a  

每当我看到一个列表对象时,我首先想到的是lapply 似乎提供与测试identical的预期结果,并将'state'作为第二个参数:

> lapply(final_states, identical, state)
[[1]]
[1] FALSE

[[2]]
[1] FALSE

[[3]]
[1] TRUE

[[4]]
[1] FALSE

[[5]]
[1] FALSE

[[6]]
[1] FALSE

您可以获得一个可能有用的中间结果:

lapply(final_states, match, state)

...但它作为一系列位置向量返回,其中c(1,2)是正确的结果。

如果你想让结果作为向量返回,比如说你想使用any ,那么使用sapply而不是lapply

> any( sapply(final_states[-3], identical, state) )
[1] FALSE
> any( sapply(final_states, identical, state) )
[1] TRUE

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM