3

I have two nested ifelse statements in a function. When I call the function, it fails because a variable in the last else clause is undefined - even if that clause is not reached.

x <- factor(c("a", "b", "c", "d"))

h <- "hi"
l <- "lo"

Now undefined variable m is never used, but this produces an error:

ifelse(as.numeric(x) > 2, h,
       ifelse(as.numeric(x) < 3, l, m))

Error in ifelse(as.numeric(x) < 3, l, m) : object 'm' not found

Even though all four values of x satisfy the first two if conditions:

> sum(as.numeric(x) > 2 | as.numeric(x) < 3)
[1] 4

Edit: I intentionally haven't defined m in this example, but I'd like to know how this is evaluated such that R looks for m when the last clause is never reached.

Sam Firke
  • 21,571
  • 9
  • 87
  • 105
  • 1
    Yes. But how does it evaluate the code to even look for `m`? I'd expect that only to occur when the first two if conditions aren't met. I've added that to the post. – Sam Firke Jun 06 '16 at 18:37
  • Feel free to do something like `ifelse(as.numeric(x) < 3, l, NA)` rather than something that doesn't exist. – Gregor Thomas Jun 06 '16 at 18:43
  • 1
    The "no" argument of `ifelse` will be evaluated if "test" argument has `FALSE` and `as.numeric(x) < 3` and `as.numeric(x) < 2` do; e.g. `ifelse(5 > 3:4, 1, "a" + "b")` and `ifelse(5 > 3:6, 1, "a" + "b")` – alexis_laz Jun 06 '16 at 18:47
  • 1
    Deleted my earlier comment - it is possible to bypass `ifelse()`'s evaluation of `no` if there are no no's in the input: `ifelse(1:3 < 100, 1:3, aksdjflaskj)` is fine. But `ifelse` deals in entire vectors and in your case `as.numeric(x)` **is** less than 3 in some cases as @alexis_laz points out. I'd actually be tempted to close as a dupe of [Does ifelse() really calculate both its vectors every time?](http://stackoverflow.com/q/16275149/903061). – Gregor Thomas Jun 06 '16 at 18:53
  • In your example, the inner `ifelse` is the `no` argument to the outer `ifelse` - and the argument needs to be evaluated. Nothing tells the inner `ifelse` call that only it's Yes indices are needed. It will try to produce an entire result vector and fail. The inner statement will need to be completely evaluated *before* the outer statement. – Gregor Thomas Jun 06 '16 at 18:56

0 Answers0