Finding All Positions for Multiple Elements in a Vector

42,924

Solution 1

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

Solution 2

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.

Solution 3

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

Solution 4

Alternatively, if you do not need to use the indices but just the elements you can do

> x <- sample(1:10,20,replace=TRUE)
> x
 [1]  6  4  7  2  9  3  3  5  4  7  2  1  4  9  1  6 10  4  3 10
> x[8<=x & x<=9]
[1] 9 9
Share:
42,924
Christopher DuBois
Author by

Christopher DuBois

Graduate student at UC Irvine.

Updated on July 21, 2022

Comments

  • Christopher DuBois
    Christopher DuBois almost 2 years

    Suppose I have the following vector:

    x <- c(8, 6, 9, 9, 7, 3, 2, 5, 5, 1, 6, 8, 5, 2, 9, 3, 5, 10, 8, 2)
    

    How can I find which elements are either 8 or 9?