userITmcmc
userITmcmc

Reputation: 23

Check for consecutive elements in vector

I have a vector of K elements and I need to check if it contains a precise subset of 2 consecutive elements.

Assume K = 6

vec = c(4,4,3,1,2,2)

How can I get an indicator that checks for the subset (4,2) as consecutive elements? Should return FALSE in this example while (3,1) should return TRUE.

Upvotes: 2

Views: 364

Answers (4)

r.user.05apr
r.user.05apr

Reputation: 5456

Especially if you have more than 2 elements to check, this might be worthwhile:

vec <-= c(4,4,3,1,2,2)
chk <- c(3, 1)

as.logical(length(Reduce(intersect, lapply(seq_along(chk), function(x) which(chk[x] == lead(vec, x - 1))))))
# [1] TRUE

chk <- c(4, 1)
as.logical(length(Reduce(intersect, lapply(seq_along(chk), function(x) which(chk[x] == lead(vec, x - 1))))))
# [1] FALSE

Upvotes: 1

G. Grothendieck
G. Grothendieck

Reputation: 269644

1) Use rollapply with the identical function.

library(zoo)

vec <- c(4,4,3,1,2,2)
x <- c(4, 2)
any(rollapply(vec, length(x), identical, x))
## [1] FALSE

x <- c(3, 1)
any(rollapply(vec, length(x), identical, x))
## [1] TRUE

2) Create strings out of vec and x and use grepl:

x <- c(4, 2)
grepl(sprintf("\\b%s\\b", toString(x)), toString(vec))
## [1] FALSE

x <- c(3, 1)
grepl(sprintf("\\b%s\\b", toString(x)), toString(vec))
## [1] TRUE

3) If x always has two elements then:

x <- c(4, 2)
any(head(vec, -1) == x[1] & tail(vec, -1) == x[2])
## [1] FALSE

x <- c(3, 1)
any(head(vec, -1) == x[1] & tail(vec, -1) == x[2])
## [1] TRUE

Upvotes: 2

tmfmnk
tmfmnk

Reputation: 39858

One another approach could be:

grepl("42", paste(vec, collapse = ""))

[1] FALSE

grepl("31", paste(vec, collapse = ""))

[1] TRUE

Upvotes: 3

Konrad Rudolph
Konrad Rudolph

Reputation: 545598

Using base R:

find_subsequence = function (vec, needle) {
    sub_idx = seq_along(needle) - 1L
    Filter(
        function (i) all(needle == vec[sub_idx + i]),
        seq_len(length(vec) - length(needle) + 1L)
    )
}
find_subsequence(vec, c(3, 1))
# [1] 4
find_subsequence(vec, c(4, 2))
# integer(0)

Upvotes: 1

Related Questions