Reputation: 113
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
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
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
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