Home > Net >  How to work with an 'if' statement with 2 or more conditions after changes in R 4.2.0
How to work with an 'if' statement with 2 or more conditions after changes in R 4.2.0

Time:06-08

I have code using an if statement to evaluate whether a value is greater than .25. Occasionally, the lead up code would submit two records for evaluation that were equal. My if statement would execute with a warning "the condition has length > 1, and only the first element will be used" This was acceptable behavior for my application and so I threw a suppressWarnings around the evaluation and moved on. Today, after updating to R 4.2.0 the same code generates an error "Error in if ....: the condition has length > 1

I can't find documentation on the change (probably because it is new). Suggestions on how to circumvent this or any explanation of what is going on would be helpful. FWIW there is a lot more that is happening in the if statement, so a switch to ifelse is not really practical here. Here is some replicable code:

   a<-c(1,1)
   b<-1
   if(b > .25){print(b)}
   if(a > .25){print(a)}

Output:

> a<-c(1,1)
> b<-1
> if(b > .25){print(b)}
[1] 1
> if(a > .25){print(a)}
Error in if (a > 0.25) { : the condition has length > 1
> 

I would like

suppressWarnings(if(a > .25){print(a)}) 

to print a

CodePudding user response:

In the R NEWS we see in

CHANGES IN R 4.2.0
SIGNIFICANT USER-VISIBLE CHANGES
...
 - Calling if() or while() with a condition of length 
   greater than one gives an error rather than a warning. 
   Consequently, environment variable 
   _R_CHECK_LENGTH_1_CONDITION_ no longer has any effect.

Clearly you should be doing something that makes sense for your use case. From what you described all you were doing previously was checking if the first element matches the condition if there were more than one elements present.

So it seems the easiest workaround is just to subset to the first element. So use

if(a[1] > .25)

instead of

if(a > .25)

If there is only one element in a then there is no worries. If there are more elements in a then you're falling back to your previous check which only looks at the first element. If this is good for your use case then great - but it does sound like you really should evaluate why you're getting multiple elements sometimes and if what you really want is to only look at the first element.

CodePudding user response:

In 4.2 it is stated that:

Calling while() or if() statements with a condition of length greater than one gives an error rather than a warning.

if (1:2 == 1) do_something()
# Error in if (1:2 == 1) do_something() : the condition has length > 1

Taken from here: https://www.jumpingrivers.com/blog/new-features-r420/

  • "This is clearly a good thing, as when the length of the condition is greater than one, this is almost certainly an error. If you are using older versions of R, you can set R_CHECK_LENGTH_1_CONDITION to true in your .Renviron to get the same effect."

In your case maybe you want to use ifelse:

a<-c(1,1)
b<-1
ifelse(b > .25, b, 0)
ifelse(a > .25, a, 0)

> ifelse(b > .25, b, 0)
[1] 1
> ifelse(a > .25, a, 0)
[1] 1 1
  •  Tags:  
  • r
  • Related