Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple if-else loop in R

Tags:

r

if-statement

Can someone tell me what is wrong with this if-else loop in R? I frequently can't get if-else loops to work. I get an error:

if(match('SubjResponse',names(data))==NA) {
    observed <- data$SubjResponse1
}
else {
    observed <- data$SubjResponse
}

Note that data is a data frame.

The error is

Error in if (match("SubjResponse", names(data)) == NA) { : 
  missing value where TRUE/FALSE needed
like image 251
CodeGuy Avatar asked Jan 18 '12 03:01

CodeGuy


2 Answers

This is not a full example as we do not have the data but I see these issues:

  1. You cannot test for NA with ==, you need is.na()
  2. Similarly, the output of match() and friends is usually tested for NULL or length()==0
  3. I tend to write } else { on one line.
like image 195
Dirk Eddelbuettel Avatar answered Sep 17 '22 15:09

Dirk Eddelbuettel


As @DirkEddelbuettel noted, you can't test NA that way. But you can make match not return NA:

By using nomatch=0 and reversing the if clause (since 0 is treated as FALSE), the code can be simplified. Furthermore, another useful coding idiom is to assign the result of the if clause, that way you won't mistype the variable name in one of the branches...

So I'd write it like this:

observed <- if(match('SubjResponse',names(data), nomatch=0)) {
    data$SubjResponse # match found
} else {
    data$SubjResponse1 # no match found
}

By the way if you "frequently" have problems with if-else, you should be aware of two things:

  1. The object to test must not contain NA or NaN, or be a string (mode character) or some other type that can't be coerced into a logical value. Numeric is OK: 0 is FALSE anything else (but NA/NaN) is TRUE.

  2. The length of the object should be exactly 1 (a scalar value). It can be longer, but then you get a warning. If it is shorter, you get an error.

Examples:

len3 <- 1:3
if(len3) 'foo'  # WARNING: the condition has length > 1 and only the first element will be used

len0 <- numeric(0)
if(len0) 'foo'  # ERROR: argument is of length zero

badVec1 <- NA
if(badVec1) 'foo' # ERROR: missing value where TRUE/FALSE needed

badVec2 <- 'Hello'
if(badVec2) 'foo' # ERROR: argument is not interpretable as logical
like image 35
Tommy Avatar answered Sep 20 '22 15:09

Tommy