I'm not sure if I really understand what you're trying to do, but if do understand I think I have a vectorized solution for you.
> f <- function(a,b){
+ b[unique(c(which(a[-length(a)] == 0 & b[-1] != 0) + 1,which(b[-length(b)] == b[-1] & b[-1] != 0)))] <- 0
+ return(b)
+ }
> f(a,b)
[1] 0 0 -1 0 0 0 0 0 0 0 0 0 -1 0 1 0 0 -1 0 0 1 0 0 0 0 0 0
Here was my rational. I think you want to set values of b to zero based on two different scenarios:
1) When non-zero values of b repeat. If so this should find those indices:
which(b[-length(b)] == b[-1] & b[-1] != 0)
2) When non-zero values of b occur when the previous index of a was zero. If so this should do the trick:
which(a[-length(a)] == 0 & b[-1] != 0) + 1
Hopefully I didn't misunderstand your goals here.
EDIT:
Second try here. I'm still pretty sure that I don't understand what you're trying to do since my solution still flags b[10] (which you say it shouldn't), but from what you're writing the best I can understand is that you want to make the following changes:
Non-zero values of "b" that follow zero values of "a" must be set to zero.
Since this rule incorrectly flags b[10] can you please tell me why it is incorrect? I think this problem will need to be phrased that way in order for me to give you a solution since the finance talk just sounds like jibberish to me.
Anyway, here is the vectorized solution for the rule I listed.:
> f <- function(a,b) {
+ b[which(b != 0)[which(!which(b != 0) %in% (which(a[-length(a)] != 0) + 1))]] <- 0
+ return(b)
+ }
> f.indices <- function(a,b) which(b != 0)[which(!which(b != 0) %in% (which(a[-length(a)] != 0) + 1))]
> f(a,b)
[1] 0 0 -1 0 0 0 0 0 0 0 0 -1 -1 1 1 0 0 -1 0 0 1 0 -1 0 0 0 0
> f.indices(a,b)
[1] 5 10 11 24 26
EDIT: Third try is the charm...
Now operating under the assumption that goal is the set all non-zero values of b to be zero except for the first value that follows a non-zero value of a. I'm not sure if/how that can be fully vectorized, but here should a quick solution:
> a <- c(0, 1, 0, 0, 0, 0, 0,-1, 0, 0, 1, 1,-1,-1, 0, 0, 1, 0, 0,-1, 0, 1, 0, 0, 0, 0, 0)
> b <- c(0, 0,-1, 0,-1, 0, 0, 0, 0, 1, 1,-1,-1, 1, 1, 0, 0,-1, 0, 0, 1, 0,-1,-1, 0,-1, 0)
>
> f <- function(a,b){
+ #non-zero b indices
+ nz.b <- which(b != 0)
+ #non-zero a indices
+ nz.a <- which(a != 0)
+ #non-zero b indices that do not follow non-zero a indices
+ nz.b.rm <- nz.b
+ for(i in nz.a){
+ nz.b.rm <- nz.b.rm[!nz.b.rm %in% nz.b[nz.b > i][1]]
+ }
+ #print non-zero b indices that do no folow non-zero a indices
+ print(paste0("Indices Removed: ",paste(nz.b.rm,collapse=",")))
+ #remove non-zero b indices that do not follow non-zero a indices
+ return(b[-nz.b.rm])
+ }
>
> b.new <- f(a,b)
[1] "Indices Removed: 5,11,24,26"
> b.new
[1] 0 0 -1 0 0 0 0 0 1 -1 -1 1 1 0 0 -1 0 0 1 0 -1 0 0