mynameisJEFF
mynameisJEFF

Reputation: 4239

Which or Apply function in R

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

Answers (4)

Matthew Plourde
Matthew Plourde

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

dickoa
dickoa

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

Justin
Justin

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

Se&#241;or O
Se&#241;or O

Reputation: 17432

How about

vect[which(vect==0) + 1] > 0

Upvotes: 2

Related Questions