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
谁能告诉我,怎么了?
您好,
狼皮
"final_states" 是一个 "list",因此您可以将 "state" 转换为 list
,然后执行
final_states %in% list(state)
#[1] FALSE FALSE TRUE FALSE FALSE FALSE
或使用 mapply
检查 "state" 中的所有元素是否存在于 "final_states" 的每个列表元素中(假设向量的长度相同,并且列表元素)
f1 <- function(x,y) all(x==y)
mapply(f1, final_states, list(state))
#[1] FALSE FALSE TRUE FALSE FALSE FALSE
或rbind
列表元素到一个矩阵,然后检查"state"和"m1"的"rows"是否相同。
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
或使用 fastmatch
中的 "faster" fmatch
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
如果您只想确定向量是否在列表中,请尝试
Position(function(x) identical(x, state), final_states, nomatch = 0) > 0
# [1] TRUE
Position()
基本上与 match()
类似,但在列表中。如果您设置 nomatch = 0
并检查 Position > 0
,您将得到一个合乎逻辑的结果,告诉您 state
是否在 final_states
中
我正在使用 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
谁能告诉我,怎么了?
您好, 狼皮
"final_states" 是一个 "list",因此您可以将 "state" 转换为 list
,然后执行
final_states %in% list(state)
#[1] FALSE FALSE TRUE FALSE FALSE FALSE
或使用 mapply
检查 "state" 中的所有元素是否存在于 "final_states" 的每个列表元素中(假设向量的长度相同,并且列表元素)
f1 <- function(x,y) all(x==y)
mapply(f1, final_states, list(state))
#[1] FALSE FALSE TRUE FALSE FALSE FALSE
或rbind
列表元素到一个矩阵,然后检查"state"和"m1"的"rows"是否相同。
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
或使用 fastmatch
fmatch
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
如果您只想确定向量是否在列表中,请尝试
Position(function(x) identical(x, state), final_states, nomatch = 0) > 0
# [1] TRUE
Position()
基本上与 match()
类似,但在列表中。如果您设置 nomatch = 0
并检查 Position > 0
,您将得到一个合乎逻辑的结果,告诉您 state
是否在 final_states