Jake L
Jake L

Reputation: 1067

Replace elements in a vector using mapply if conditions are met

Trying to replace values in a vector if conditions are met using a quick apply function, but having a hard time with syntax.

 v1 <- c(-18,-18,-19,-20,-18,-18,-19)
 v2 <- c(34, 7,   8,   9,  7, 10, 30)

I want to compare elements in each vector and if v1 is less than -v2, replace it with the v2 value. I can easily identify those that need to be replaced:

 v1 < (-v2)
 [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE

I tried to use this mapply function, but am getting the following error

 v1 <- mapply(function(x) if (x< (-v2)) (-v2) else x, v1) 

 Warning messages:
 1: In if (x < (-v2)) (-v2) else x :
   the condition has length > 1 and only the first element will be used
 2: In if (x < (-v2)) (-v2) else x :
   the condition has length > 1 and only the first element will be used

I think it's because I'm not specifically saying to compare elements in order, so it's only using the first element of one of the vectors, but I'm not quite sure how to do so. By the way, I know I could do this with a for loop, but I am trying to avoid that since the dataset will be very large. Thanks in advance.

Update: I also tried this, and got a new error

 v1 <- mapply(function(i) if(v1[i]< (-v2[i]) (-v2[i]) else v1[i], seq_along(v1))
 Error: unexpected 'else' in "v1 <- sapply(function(i) if(v1[i]< (-v2[i]) (-v2[i]) else"

Upvotes: 0

Views: 396

Answers (2)

Grada Gukovic
Grada Gukovic

Reputation: 1253

You dont need a loop for that. This does the job:

v1[v1 < (-v2)] <- v2[v1 < (-v2)].

Note: You must make sure that the length of the two vectors is equal, otherwise R will extend the shorter one tacitly when comparing v1 < (-v2) and the subsetting will give you a nonsensical result.

Upvotes: 1

GKi
GKi

Reputation: 39737

In mapply you can apply a Function to Multiple Arguments. In your case your function should take two variables like like:

v1 <- mapply(function(x,y) if (x < (-y)) (-y) else x, v1, v2)
v1
#[1] -18  -7  -8  -9  -7 -10 -19

As Grada Gukovic wrote, there is no need to loop. In the answer only the - is missing:

v1[v1 < (-v2)] <- -v2[v1 < (-v2)]
v1
#[1] -18  -7  -8  -9  -7 -10 -19

Upvotes: 1

Related Questions