Общее решение:
magicFUN <- function(vec1, vec2) {
if(length(vec2) > length(vec1)) stop("vec 2 should be shorter")
len <- length(vec1) - length(vec2) + 1
out <- vector(mode = "logical", length=len)
for(i in 1:len) {
out[i] <- identical(vec2, vec1[i:(i+length(vec2)-1)])
}
return(which(out))
}
vec1 <- c(0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1)
vec2 <- c(1, 1)
magicFUN(vec1, vec2)
[1] 4 7 8
А для цикла будет самым быстрым решением (кроме использования Rcpp).См. Контрольные показатели ниже:
magicFUN <- function(vec1, vec2) {
if(length(vec2) > length(vec1)) stop("vec 2 should be shorter")
len <- length(vec1) - length(vec2) + 1
out <- vector(mode = "logical", length=len)
for(i in 1:len) {
out[i] <- identical(vec2, vec1[i:(i+length(vec2)-1)])
}
return(which(out))
}
magicFUN2 <- function(vec1, vec2){
l1 <- length(vec1)
l2 <- length(vec2)
which(colSums(sapply(1:(l1-l2), function(i) vec1[i:(i+l2-1)]) == vec2) == l2)
}
magicFUN3 <- function(vec1, vec2){
which(c(zoo::rollapply(vec1, width=length(vec2),
function(x)all(x==vec2), align = "left"),rep(FALSE,length(vec2)-1))==TRUE)
}
library(microbenchmark)
microbenchmark(magicFUN(vec1, vec2), magicFUN2(vec1, vec2), magicFUN3(vec1, vec2))
Unit: milliseconds
expr min lq mean median uq max neval cld
magicFUN(vec1, vec2) 6.083572 6.575844 7.292443 6.878016 7.421208 13.35746 100 a
magicFUN2(vec1, vec2) 8.289640 8.976736 11.007967 9.338644 9.951492 139.68886 100 a
magicFUN3(vec1, vec2) 39.131268 42.369479 46.303722 44.203563 45.053252 172.46151 100 b