For example, I have two vectors:
x1 <- c(0,1,2)
x2 <- c(1,2,0,1,2,3,4,5,0,1,0,1,2)
I would like to find the position where x1 is first present x2, which is in this case is 3. I have tried which(), match(), but both seems to find elements, instead of vectors. Is there a R function that can achieve this or a way to construct one?
Thank you!
CodePudding user response:
If you are looking for the first match of 0
:
match(x1[1], x2)
But for the whole vector:
> which(apply(t(embed(x2, length(x1))) == rev(x1), 2, all))[1]
[1] 3
>
Edit:
To give NA
on no-match:
cond <- apply(t(embed(x2, length(x1))) == rev(x1), 2, all)
if (any(cond)) which(cond)[1] else NA
Explanation:
This uses embed
to split x2
into chunks by the length of x1
, and it applies it and detects whether it is equivalent to x1
, and gives a boolean vector (or TRUE
s and FALSE
s). Then finally it uses which
to get the index of the occurrences of TRUE
, and I use [1]
to get the first value.
For the edit, I detect if in the conditioned boolean vector contains any TRUE
s, if so, do the same thing as mentioned above, if not, give NA
.
CodePudding user response:
One option would be to do rolling comparison.
x1 <- c(0,1,2)
x2 <- c(1,2,0,1,2,3,4,5,0,1,0,1,2)
which(zoo::rollapply(x2, length(x1), function(x) all(x == x1)))
#[1] 3 11
To get the 1st occurrence -
which(zoo::rollapply(x2, length(x1), function(x) all(x == x1)))[1]
#[1] 3
CodePudding user response:
For all elements for vector x1.
sapply(x1, function(x) match(x,x2))
[1] 3 1 2
CodePudding user response:
Another approach with stringr
;
library(tidyverse)
x1_ <- paste0(x1,collapse="")
x2_ <- paste0(x2,collapse="")
str_locate_all(x2_, x1_)[[1]]
gives,
start end
[1,] 3 5
[2,] 11 13
which returns empty if there is no match.