1

I need to find out how many times an instance of one variable occurred between two instances of another variable. Given the data:

v <- c(1, 0, 0, 1, 0, 0, 0, 1)
w <- c(0, 0, 1, 0, 0, 0, 1, 0)
x <- c(0, 0, 0, 1, 1, 0, 0, 0)
y <- c(0, 0, 0, 0, 0, 0, 0, 0)
z <- c(0, 0, 0, 1, 0, 0, 0, 0)

I want to see this:

some_function(v, w)
> 2

some_function(w, x)
> 1

some_function(w, y)
> 0

some_function(v, z)
> 1

Such that the first argument of some_function() demarcates windows within which I can check whether anything happened in the second argument. Note that the output should not distinguish between the event happening once or twice within each window, but rather should count the number of windows within which one or more events occurred.

PhiloT
  • 171
  • 5
  • 1
    Can you clarify why `some_function(w, z)` would return 0? – De Novo Jun 13 '18 at 21:52
  • what should you return in the case of `x=c(1,0,0,1),y=c(1,0,0,1)` or in the case of `x=c(1,0,1,0,1);y=c(1,0,1,0,1)`? – Onyambu Jun 14 '18 at 01:42
  • Dan Hall, it shouldn't -- that was an error. Sorry about that. – PhiloT Jun 14 '18 at 10:40
  • Onyambu, good point. In the case of the first one, it should return 1, since falling right on the boundary should either count as the falling in the previous window or the following window. Likewise, the second case you gave should return 2. – PhiloT Jun 14 '18 at 10:42

3 Answers3

3

Something like this:

some_function <- function(a, b){
  sum(sapply(split(b, cumsum(a)), sum) > 0)
}

> some_function(v, w)
[1] 2
> some_function(w, x)
[1] 1
> some_function(w, y)
[1] 0
> some_function(w, z) # Not sure why you are getting 0 here?
[1] 1
> some_function(v, z)
[1] 1
zx8754
  • 52,746
  • 12
  • 114
  • 209
  • 2
    `some_function(c(1,0,1),c(1,0,1))` gives 2??? should it not return 0? just curious..check @Henrik comment – Onyambu Jun 14 '18 at 00:20
2

You can use rowsum(), grouped by cumsum(). This should be pretty quick.

some_function <- function(a, b) sum(rowsum(b, cumsum(a)) > 0)

some_function(v, w)
# [1] 2
some_function(w, x)
# [1] 1
some_function(w, y)
# [1] 0
some_function(w, z)  ## possible typo in question
# [1] 1
some_function(v, z)
# [1] 1
Rich Scriven
  • 97,041
  • 11
  • 181
  • 245
  • 1
    I wonder if the function should return zero for something like `x <- c(1, 0, 1)` and `y <- c(1, 0, 0)`? – Henrik Jun 13 '18 at 22:42
1

Another approach based on findInterval():

some_function <- function(x, y) {
  sum(unique(findInterval(which(y==1), which(x==1), left.open=TRUE)) != 0)
}

> some_function(v, w)
[1] 2
> some_function(w, x)
[1] 1
> some_function(w, y)
[1] 0
> some_function(w, z) # Probably a mistake in the question
[1] 1
> some_function(v, z)
[1] 1
Karolis Koncevičius
  • 9,417
  • 9
  • 56
  • 89