Finding All Positions for Multiple Elements in a Vector

Here is a generalized solution to find the locations of all target values (only works for vectors and 1-dimensional arrays).

locate <- function(x, targets) {
    results <- lapply(targets, function(target) which(x == target))
    names(results) <- targets
    results
}

This function returns a list because each target may have any number of matches, including zero. The list is sorted (and named) in the original order of the targets.

Here is an example in use:

sequence <- c(1:10, 1:10)

locate(sequence, c(2,9))
$`2`
[1]  2 12

$`9`
[1]  9 19

This is one way to do it. First I get the indices at which x is either 8 or 9. Then we can verify that at those indices, x is indeed 8 and 9.

> inds <- which(x %in% c(8,9))
> inds
[1]  1  3  4 12 15 19
> x[inds]
[1] 8 9 9 8 9 8

In this specific case you could also use grep:

# option 1
grep('[89]',x)
# option 2
grep('8|9',x)

which both give:

[1]  1  3  4 12 15 19

When you also want to detect number with more than one digit, the second option is preferred:

> grep('10|8',x)
[1]  1 12 18 19

However, I did put emphasis on this specific case at the start of my answer for a reason. As @DavidArenburg mentioned, this could lead to unintended results. Using for example grep('1|8',x) will detect both 1 and 10:

> grep('1|8',x)
[1]  1 10 12 18 19

In order to avoid that side-effect, you will have to wrap the numbers to be detected in word-bounderies:

> grep('\\b1\\b|8',x)
[1]  1 10 12 19

Now, the 10 isn't detected.


You could try the | operator for short conditions

which(x == 8 | x == 9)

Tags:

R

Vector

R Faq