Evaluating undefined ifelse() condition in R

Viewed 53

I've been hung up trying to have R evaluate an ifelse() conditional response that evaluates the following expression 0^(2)*(1/0+1)), which results in "NaN" value. The code below is what i have tried, however, i cannot force it to evaluate to the desired response.


library(dplyr)
df=data.frame(test_statistic=c(1,1.8, 2.1,  0^(2)*(1/0+1))) %>% rowwise() %>% mutate(
  
  Significance=
    ifelse(test_statistic <1.7, "test_statistic <1.7",
           ifelse(test_statistic < 2 & test_statistic >= 1.7 ,"test_statistic < 2 & test_statistic <= 1.7",
                  ifelse(test_statistic < Inf & test_statistic >= 2.0, "test_statistic < Inf & test_statistic <= 2.0", 
                         ifelse(is.na(test_statistic)==TRUE,"is.na(test_statistic)","unspecified condition")))))

the result of the ifelse() test is shown below.

# A tibble: 4 x 2
# Rowwise: 
  test_statistic Significance                                
           <dbl> <chr>                                       
1            1   test_statistic <1.7                         
2            1.8 test_statistic < 2 & test_statistic <= 1.7  
3            2.1 test_statistic < Inf & test_statistic <= 2.0
4          NaN   NA      

by changing the squared expression to the value one (1) " 1^(2)(1/0+1)))" the ifelse() statement works, however, if the expression 0^(2)(1/0+1))) the statement does not work.

I've consulted over posts and havent been successful identifying a solution. Can someone please help, provide the following desired result.

# A tibble: 4 x 2
# Rowwise: 
test_statistic Significance                                
<dbl> <chr>                                       
  1            1   test_statistic <1.7                         
2            1.8 test_statistic < 2 & test_statistic <= 1.7  
3            2.1 test_statistic < Inf & test_statistic <= 2.0
4          NaN   is.na(test_statistic)


Thanx

1 Answers

Consider changing the order of expressions i.e. the first one should be is.na instead of the test_statistic < 1.7. Also, instead of nested ifelse use case_when along with remove the rowwise attribute with ungrouping as ifelse/case_when etc are all vectorized

library(dplyr)
df %>%
     ungroup %>% 
      mutate(Significance = case_when(is.na(test_statistic) ~ 
             "is.na(test_statistic)", 
       test_statistic <1.7 ~  "test_statistic <1.7",
       test_statistic < 2 & test_statistic >= 1.7  ~
              "test_statistic < 2 & test_statistic <= 1.7", 
       test_statistic < Inf & test_statistic >= 2.0 ~
          "test_statistic < Inf & test_statistic <= 2.0",
       TRUE ~ "unspecified condition"))

-output

# A tibble: 4 x 2
  test_statistic Significance                                
           <dbl> <chr>                                       
1            1   test_statistic <1.7                         
2            1.8 test_statistic < 2 & test_statistic <= 1.7  
3            2.1 test_statistic < Inf & test_statistic <= 2.0
4          NaN   is.na(test_statistic)         

Why we need to reorder the expressions is based on the return value from comparison operators when there is a NA - any computation on NA returns NA. In the ifelse, we are passing the nested ifelse in the 'no' argument. According to ?ifelse

no - return values for false elements of test

v1 <- df$test_statistic
v1 < 1.7
#[1]  TRUE FALSE FALSE    NA
ifelse(v1 < 1.7, 1, ifelse(is.na(v1), 2, 3))
#[1]  1  3  3 NA

Here, the last ifelse is not passed on the FALSE, but only the NA and thus it returns NA

data

df <- data.frame(test_statistic=c(1,1.8, 2.1,  0^(2)*(1/0+1))) %>% 
       rowwise
Related