DaniCee
DaniCee

Reputation: 3207

R: unexpected `ifelse` behavior

I have a data frame like the following:

mydf <- data.frame(letter=LETTERS[1:10],
                   val1=sample(1:1000, 10, replace=F),
                   val2=sample(1:1000, 10, replace=F))
> mydf
   letter val1 val2
1       A  877  250
2       B  554  427
3       C  747   92
4       D  353  890
5       E  957  194
6       F  593  338
7       G  723  731
8       H  218  849
9       I  585  932
10      J  873  642

I just want to make a new column which (for this MWE) is equal to one of the value columns, depending on a choose variable, and I wanted to use ifelse for this purpose.

I do this:

  choose <- 1
  mydf$chosen <- ifelse(choose==1, mydf$val1, mydf$val2)
  mydf

But it just uses the first value of val1 for the chosen column... what am I doing wrong here? Thanks

> mydf
   letter val1 val2 chosen
1       A  878  984    878
2       B  880   80    878
3       C  296  999    878
4       D  558  230    878
5       E  112  414    878
6       F  132  450    878
7       G  429  693    878
8       H  608   89    878
9       I  409   50    878
10      J  974  980    878

Upvotes: 2

Views: 112

Answers (2)

Samuel Onyango
Samuel Onyango

Reputation: 38

From your data, using dplyr to do the work

mydf <- data.frame(letter=LETTERS[1:10],
                   val1=sample(1:1000, 10, replace=F),
                   val2=sample(1:1000, 10, replace=F))

library(dplyr)

mydf %>%
 mutate(choosen = ifelse(letter == "A", val1, val2)) -> mydf

mydf
#   letter val1 val2 choosen
#1       A  893  103     893
#2       B  602  284     284
#3       C  930  460     460
#4       D  441  579     579
#5       E  842   62      62
#6       F  963  896     896
#7       G  471  266     266
#8       H  231   92      92
#9       I  154  136     136
#10      J  576  553     553

Upvotes: 0

Ronak Shah
Ronak Shah

Reputation: 388982

ifelse returns the output of same length as the condition we are checking. Since the length of the condition is 1 here it returns only the first value and the same value is recycled for all the values. Use if/else instead.

mydf$chosen <- if(choose=="a") mydf$val1 else mydf$val2
mydf
#   letter val1 val2 chosen
#1       A  415  244    415
#2       B  463   14    463
#3       C  179  374    179
#4       D  526  665    526
#5       E  195  602    195
#6       F  938  603    938
#7       G  818  768    818
#8       H  118  709    118
#9       I  299   91    299
#10      J  229  953    229

data

set.seed(123)
mydf <- data.frame(letter=LETTERS[1:10],
                   val1=sample(1:1000, 10, replace=F),
                   val2=sample(1:1000, 10, replace=F))

Upvotes: 2

Related Questions