我想检查一个向量y
是否包含另一个向量x
y <- c(0,0,0,NA,NA,0)
x <- c(0,0,0,0)
在这种情况下,它应该给我FALSE
,因为y
中没有四个NULL的序列。但是,如果我们查看向量y2
,结果应为TRUE
。
y2 <- c(0,0,NA,0,0,0,0)
修改:
我尝试使用%in%
,但它似乎只适用于矢量元素,而不适用于整个矢量。该解决方案不一定适用于更普遍的问题。如果它适用于这种特殊情况会很好。
答案 0 :(得分:7)
您可以使用grepl
和paste
的组合。在这里,您需要使用collapse
中的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
答案 1 :(得分:5)
使用此:
any(apply(embed(y,length(y)-length(x)+1),2,identical,x))
答案 2 :(得分: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
中任何序列的一般情况下,我怀疑是否有办法按摩rle
或seqle
来执行此操作。我将不得不去玩一段时间。 :-)
答案 3 :(得分:3)
对于x
中仅0的特定情况,只需使用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
答案 4 :(得分:1)
OP没有要求这样做,但是这里有一种方法可以找到x
的实例出现的位置。
假设“9”永远不会出现在y
中,我使用“9”作为我的标记字符。显然,人们可以选择其他角色。
> 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 ...
答案 5 :(得分:0)
又一个选择:
length(x) == max(nchar(strsplit(paste(y,collapse=''),"NA")[[1]]))
length(x) == max(nchar(strsplit(paste(y2,collapse=''),"NA")[[1]]))
我还认为应该有更聪明的方法,例如以某种方式使用cumsum
(并在每次出现NA
时将其重置为0,然后获得最大值并将其与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))
开头,然后以某种方式计算结果中元素之间的最大差异。
答案 6 :(得分:0)
类似于费迪南德(很好地使用embed()
,BTW),这将返回所有匹配的向量(如果没有则为空):
which(sapply(1:(length(y)-length(x)+1), function(z) identical(x, y[z:(z+length(x)-1)])))