0

I can nest multiple ifelse statements as follows:

ifelse(2==1, "2==1", ifelse(3==1, "3==1", ifelse(1==1, "1==1", NA)))
#[1] "1==1"

However, it seems as if NAs are getting into the way. The following returns ...

df <- data.frame(a = c(1, 1, NA, NA, NA ,NA),
                 b = c(NA, NA, 1, 1, NA, NA),
                 c = c(rep(NA, 4), 1, 1))
ifelse(df$a==1, "a==1", ifelse(df$b==1, "b==1", ifelse(df$c==1, "c==1", NA)))
#[1] "a==1" "a==1" NA     NA     NA     NA    

... instead of the desired

#[1] "a==1" "a==1" "b==1" "b==1"  "c==1" "c==1" 

I could first assign different values to NAs to obtain the desired result:

df_noNA <- data.frame(a = c(1, 1, 2, 2, 2 ,2),
                 b = c(2, 2, 1, 1, 2, 2),
                 c = c(rep(2, 4), 1, 1))

ifelse(df_noNA$a==1, "a==1", ifelse(df_noNA$b==1, "b==1", ifelse(df_noNA$c==1, "c==1", NA)))
#[1] "a==1" "a==1" "b==1" "b==1"  "c==1" "c==1" 

However, I was wondering if there was a more direct way to tell ifelse to ignore NAs?


EDIT: I am looking for an efficient solution to this problem.

As noted in the comments by @Cath, I can tell ´ifelse´ to ignore NAs:

ifelse(df$a==1 &  !is.na(df$a), "a==1", 
    ifelse(df$b==1 & !is.na(df$b), "b==1", 
        ifelse(df$c==1 & !is.na(df$c), "c==1", NA)))

However, as also noted by @akrun, it seems somewhat lengthy to type !is.na(x_i) for every column (personally it also seems redundant to me to specify that x should equal 1 and not be NA). At this moment, the workaround of first replacing NAs with a value that is not present in the data set (e.g., 2 in this case) and then writing an ´ifelse´ statement without !is.na(x_i) seems more efficient.

Flo
  • 1,503
  • 1
  • 18
  • 35
  • `R` cannot know if `NA` fulfill the condition or not, you need to add a missing value check with `is.na` to make it work properly – Cath Jun 07 '17 at 09:59
  • @Cath it can be done in efficient ways and by duping you are denying the OP to get good answers – akrun Jun 07 '17 at 10:01
  • 2
    thanks, that was helpful: `ifelse(df$a==1 & !is.na(df$a), "a==1", ifelse(df$b==1 & !is.na(df$b), "b==1", ifelse(df$c==1 & !is.na(df$c), "c==1", NA))) works`. However, it seems somewhat verbose to me to indicate that as a test x should be equal to 1 and not equal to NA... – Flo Jun 07 '17 at 10:01
  • @Cath I am opening this as the OP's question is different and need efficient ways – akrun Jun 07 '17 at 10:02
  • 1
    the question is about the error and not about efficiency. Don't change the Q so you can put an answer – Cath Jun 07 '17 at 10:05
  • @Cath Please read the OP's comments `However, it seems somewhat verbose to me to indicate that as a test x should be equal to 1 and not equal to NA...` – akrun Jun 07 '17 at 10:06
  • @Cath Are you saying that if the OP had 100 columns, he should use `100` ifelse statements – akrun Jun 07 '17 at 10:08
  • 1
    @Cath, I found your contribution helpful because it pointed me to another way to solve my problem. However, I do find your solution lengthier than my workaround of replacing all NA entries with e.g., 99999 first. I am still wondering if there was a more efficient way of telling ifelse to ignore NAs – Flo Jun 07 '17 at 10:08
  • 1
    @Flo Could you update your post with the one in the comments – akrun Jun 07 '17 at 10:09
  • 2
    @Flo as akrun said, then you can update your post or post another question. This one is about the surprising result your were getting and is a dupe of other questions. – Cath Jun 07 '17 at 10:10
  • @akrun, will do! – Flo Jun 07 '17 at 10:10
  • @Flo Please update the expected output for `df_noNA` – akrun Jun 07 '17 at 10:12
  • @Jaap You are abusing your dupe hammer power by tagging it to some posts while the OP's question is also about efficiency – akrun Jun 07 '17 at 10:13
  • @akrun, also updating the expected output for df_nonNA now – Flo Jun 07 '17 at 10:18

0 Answers0