R.bitrary
R.bitrary

Reputation: 113

R: How to use a "if"-like-function on vectors but no "ifelse" because if no it should do nothing

I try to overwrite multiple variables at once (months in a kind of calendar) with an value of another variable based on a condition of a third variable. If the condition is false, nothing should happen.

I thought the If-function would be helpful because one could omit the else but no, it does not work for vectors.

    DF1[,3:4] <- if (DF1$v7==5) {DFDF1$v5}  
the condition has length > 1 and only the first element will be used

On the other hand, fitting for a vector is ifelse, but it tells me

    DF1[,3:4] <- ifelse (DF1$v7==5, DF1$v5, )
"argument "no" is missing, with no default", 

So what should I do to achieve my goal?

Thanks for any advice, beginners as me are grateful!

PS: Variables are just examples.

EDIT: I am looking for an way, where I can address the variables that should be replaced by column-number as in DF1[, 3:4] because otherwise I would have to type up to 12 different variable names (in my original DF).

Upvotes: 5

Views: 9854

Answers (3)

nisetama
nisetama

Reputation: 8863

This modifies the input in place:

> rif=\(x,y,z)do.call('=',list(substitute(x),ifelse(y,z,x)),,parent.frame())
> v=1:4;rif(v,v>4,-v);v
[1]  1  2  3  4 -5 -6 -7 -8

Or with magrittr:

> v=1:8;v%<>%ifelse(.>4,-.,.);v
[1]  1  2  3  4 -5 -6 -7 -8

Upvotes: 0

Hugh
Hugh

Reputation: 16089

Do one column after the other. Regarding the else condition, just use the original value

for (i in 3:4){
 DF[,i] <- ifelse(DF$v7 == 5, DF1$v5, DF[,i])
}

Upvotes: 4

IRTFM
IRTFM

Reputation: 263342

I can think of one way it might work:

 DF1[DF1$v7==5,3:4] <-cbind( DF1$v5,DF1$v5 )[DF1$v7==5, ]

The numbers of items on both sides of the assignment should match up. Tested. It delivered integer values when DF1$v5 was a factor but performed as intended. Could also do:

 DF1[DF1$v7==5,3:4] <- DF1[ , c('v5','v5')][DF1$v7==5, ]

Upvotes: 0

Related Questions