7

我想检查一个向量是否y包含另一个向量x

y <- c(0,0,0,NA,NA,0)
x <- c(0,0,0,0)

在这种情况下,它应该给我FALSE,因为 NULL 中没有四个 NULL 的序列y。但是如果我们看一下向量y2,结果应该是TRUE

y2 <- c(0,0,NA,0,0,0,0)

编辑

我尝试使用%in%,但它似乎只适用于向量的元素,而不适用于整个向量。该解决方案不必适用于更普遍的问题。如果它适用于这种特殊情况,那就太好了。

4

8 回答 8

7

您可以使用grepl和的组合paste。在这里,您需要使用collapsein 中的参数将每个向量折叠成一个字符paste

> grepl(paste(x,collapse=";"),paste(y2,collapse=";"))
[1] TRUE
> grepl(paste(x,collapse=";"),paste(y,collapse=";"))
[1] FALSE

> grepl(paste(c(123),collapse=";"),paste(c(12,3),collapse=";"))
[1] FALSE
于 2013-09-10T13:16:33.643 回答
5

用这个:

any(apply(embed(y,length(y)-length(x)+1),2,identical,x))
于 2013-09-10T13:25:10.460 回答
4

只是对于那些可能想知道的人,答案的时间测试。

findit1<-function(x,y) any(apply(embed(y,length(y)-length(x)+1),2,identical,x))
findit2<-function(x,y) grepl(paste(x,collapse=";"),paste(y,collapse=";"))

x<-c(0,1,1,0,0,0,1,0,1)
y<-sample(c(0,1),1e5,replace=TRUE)

Rgames> microbenchmark(findit1(x,y),findit2(x,y))
Unit: milliseconds
          expr       min       lq   median       uq      max neval
 findit1(x, y) 403.79291 449.9028 457.8320 466.4996 603.6573   100
 findit2(x, y)  99.09317 100.7774 101.4513 102.1728 119.8970   100

编辑:使用eddi的rle回答,

Rgames> findit3<-function(x,y) sum(length(x) <= rle(y)$lengths[rle(y)$values %in% 0]) 
Rgames> x<-c(0,0,0,0,0)
Rgames> microbenchmark(findit1(x,y),findit2(x,y),findit3(x,y))
Unit: milliseconds
          expr       min        lq   median        uq       max neval
 findit1(x, y) 340.63570 383.39450 414.6791 456.38786 532.98017   100
 findit2(x, y)  99.72606 101.11308 101.9399 103.20869 117.91149   100
 findit3(x, y)  23.39226  24.39826  31.8478  35.10592  53.15408   100

但在任何序列的一般情况下,x我怀疑是否有按摩rleseqle这样做的方法。我得去玩一会儿。:-)

于 2013-09-10T14:27:49.690 回答
3

对于仅在 0 中的这种特殊情况x,只需使用rle

sum(length(x) <= rle(y2)$lengths[rle(y2)$values %in% 0]) > 0
#[1] TRUE
sum(length(x) <= rle(y)$lengths[rle(y)$values %in% 0]) > 0
#[1] FALSE
于 2013-09-10T15:00:24.763 回答
1

OP 没有要求这样做,但这是一种查找实例x发生位置的方法。我使用“9”作为我的标记字符,假设“9”永远不会出现在y. 显然,人们可以选择其他角色。

 > bar<-gsub(paste(x,collapse=""),'9',paste(y,collapse=""))
 > rab<-as.numeric(unlist(strsplit(bar,'')))
 > rle(rab==9)
Run Length Encoding
  lengths: int [1:3123] 49 1 49 1 20 1 6 1 78 1 ...
  values : logi [1:3123] FALSE TRUE FALSE TRUE FALSE TRUE ...
于 2013-09-10T17:58:32.777 回答
0

还有一个选择:

length(x) == max(nchar(strsplit(paste(y,collapse=''),"NA")[[1]]))
length(x) == max(nchar(strsplit(paste(y2,collapse=''),"NA")[[1]]))

我还认为应该有更聪明的方法,例如以某种方式利用cumsum(并在每次出现时将其重置为 0,NA然后获取最大值并将其与 的长度进行比较x)。经过一些互联网搜索后,我有:

length(x) == max(sapply(split(y, replace(cumsum(is.na(y)), is.na(y), -1))[-1],length))
length(x) == max(sapply(split(y2, replace(cumsum(is.na(y2)), is.na(y2), -1))[-1],length))

或者也许开始,which(is.na(x))然后以某种方式计算结果中元素之间的最大差异。

于 2013-09-10T14:47:52.953 回答
0

类似于 Ferdinand 的(很好地使用embed(),顺便说一句),这将返回一个包含所有匹配项的向量(如果没有则为空):

which(sapply(1:(length(y)-length(x)+1), function(z) identical(x, y[z:(z+length(x)-1)])))

于 2017-11-09T20:19:33.670 回答
0

我真的很喜欢这种方法:

# Second vector contains all the elements of the first
all(1:10 %in% 1:10)
# [1] TRUE

# Second vector does not contain all elements of the first
all(1:11 %in% 1:10)
# [1] FALSE
于 2021-10-06T06:34:03.760 回答