Apollo
Apollo

Reputation: 9064

Changing values at specific indices - R

I have two vectors a & b.

a <- c(1,0,1,0,0,0,1)

b <- c(.2,.9,.3,.9,.8,.78,.3)

and I want to subtract 1 from all values in b that correspond to indices for 1 in a. I can extract the indices of all values that are 1 in a by doing which(a == 1). I tried doing something like b <- 1 - b[which(a == 1)] but this didn't work. Is there some way to do this without using a for loop?

Upvotes: 0

Views: 68

Answers (2)

Gregor Thomas
Gregor Thomas

Reputation: 146249

Your a vector is 0's and 1's. If you want to subtract 1 from b whenever a is 1, and do nothing (aka subtract 0) from b whenever a is 0, then this is just subtraction:

b - a

If your a vector has values other than 0 or 1, then you'll need a slightly more complicated, more general method as in @akrun's answer.

Another "more complex" variant would use the implicit meaning of TRUE as 1 and FALSE as 0 to do

b - (a == 1)

Upon re-reading, you might need to clarify what you want. Your text says subtract 1 from all values in b, which implies b - (1 or 0). However, you code attempt is 1 - b, subtracting b from 1 not 1 from b, in which case akrun's answer is perfect and mine would need some adjustments.

Upvotes: 4

akrun
akrun

Reputation: 887991

We can convert the binary vector 'a' to logical by double negation (!! - converts 1 to TRUE and 0 to FALSE) or by just wrapping with as.logical or as in the OP's code (a==1). This will subset the values in 'b' that corresponds to TRUE/1 in 'a'. Subtract 1 from those values and assign the output back to those values in 'b'

b[a==1] <- 1 - b[a==1]

Or we can use ifelse

ifelse(a==1, 1-b, b)

In the OP's code, wrapping with which is not needed and also assigning to 'b' with a subset of elements of 'b' replaces the original vector 'b' with the subset 'b'

Upvotes: 4

Related Questions