Find the first n elements of one vector which contain all the elements of another vector

Viewed 151

Given two vectors vecA and vecB, I would like to find the smallest n such that

all(vecB %in% vecA[1:n])

is TRUE.

This is in a tight inner loop, so speed would be good. Obviously I could do

n <- NA_integer_ 
for (i in seq_along(vecA)) {
  if (all(vecB %in% vecA[1:i])) {
    n <- i
    break
  } 
}

but is there a faster/more elegant way?

One thing you can use: vecB is always going to be a sequence of the form 1:M.

Here's an example where n should equal 5:

vecB <- 1:3
vecA <- c(1, 2, 2, 1, 3, 2)
2 Answers

One option could be:

max(match(vecB, vecA))

Results for different situations:

vecB <- 1:3
vecA <- c(1, 2, 2, 1, 3, 2)

[1] 5

vecB <- 1:3
vecA <- c(3, 2, 2, 1)

[1] 4

vecB <- 1:3
vecA <- c(2, 2, 1)

[1] NA

One solution (though) but logical translation may be

vecB <- 1:3
vecA <- c(1, 2, 2, 1, 3, 2)


min(seq_along(vecA)[sapply(Reduce(function (.x, .y) union(.x, .y), vecA, accumulate = T), 
                           function(x) all(vecB %in% x))])
#> [1] 5

Created on 2021-05-13 by the reprex package (v2.0.0)

Related