Reputation: 4239
I am trying to write a function that:
given the current index of a vector vect[i] == 0
, if vect[i+1] > 0
, it will return TRUE
. Else, return FALSE
.
I know how to write it out using a for-loop to traverse the whole vector. However, I am interested in more efficient ways of doing this, i.e. write a simple function like the following and then pass it to which()
or apply()
function ?
ia <- function(x) {
if(vect[i] == 0) {
if(vect[i+1] > 0) {
return TRUE
} else {
return FALSE
}
}
}
This doesn't work. How can make it work such that I can pass the above function into a which function or any better functions you can come up with?
Upvotes: 0
Views: 817
Reputation: 44614
Here are two ways:
k <- c(0,1,0,2,0,0,3,0)
result <- c(mapply(function(x,y) x == 0 & y > 0, head(k, -1), tail(k, -1)), FALSE)
and
c(apply(embed(k,2), 1, function(row) row[1] > 0 & row[2] == 0), FALSE)
tail
and head
with -1
arguments return all but the first and last elements, respectively, you can use this to compare the value at each index to the one after it. embed
with argument 2
creates a two column matrix of the vector, where the last column includes all but the last element and the second column is lagged by 1.
Upvotes: 0
Reputation: 18437
Try something like this
ia <- function(x) c(x[-length(x)] == 0 & x[-1] > 0, FALSE)
x <- c(1, 3, 0, 3, 4, 5, 0, 0, -3, 4, 0, 1, 0, -3, 10)
ia(x)
[1] FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[11] TRUE FALSE FALSE FALSE
cbind(x, ia(x))
x
[1,] 1 0
[2,] 3 0
[3,] 0 1
[4,] 3 0
[5,] 4 0
[6,] 5 0
[7,] 0 0
[8,] 0 0
[9,] -3 0
[10,] 4 0
[11,] 0 1
[12,] 1 0
[13,] 0 0
[14,] -3 0
[15,] 10 0
We can also get the index using which
which(ia(x))
[1] 3 11
Upvotes: 2
Reputation: 43265
Lets assume you want the last element of your vector to return TRUE
if it is == 0 irrelevant of the "following" value. I'd make a shifted vector and do two comparisons:
vect <- rbinom(10, 1, prob=0.5)
shifted <- c(vect[-1],0)
Then do your comparison:
result <- vect == 0 & shifted > 0
Upvotes: 1