Home > Software design >  ifelse() behavior and related error: incompatible types in subassignment type fix (R)
ifelse() behavior and related error: incompatible types in subassignment type fix (R)

Time:12-17

I am trying to run a ifelse() command but getting some weird behavior...

Running:

1 <= 50

I get:

TRUE

Where typeof(1 <= 50) and class(1 <= 50) returns

[1] "logical"

However, once I put this into a ifelse() loop I get some weird behavior...

ifelse(1 <= 50, print("Yay"), print("Boo"))

[1] "Yay"

[1] "Yay"

It prints the true condition action twice....

I am thinking this is the reason I get this error:

Error in ans[ypos] <- rep(yes, length.out = len)[ypos] : incompatible types (from S4 to logical) in subassignment type fix

When I write more complicated code:

ifelse(length(List[[1]]) >= 50, List[[1]][1], print("Error"))

Which is interesting because if I have the yes statementifelse() assign something to a variable, I still get the error but the resulting object is correct....

> ifelse(length(List[[1]]) >= 50, test <- List[[1]][1], print("Error"))
> test

What am I not understanding....

CodePudding user response:

You are slightly misunderstanding the purpose of ifelse(): this function is made to pick elements from either of two vectors/matrices. The online help describes it as follows:

ifelse returns a value with the same shape as test which is filled with elements selected from either yes or no depending on whether the element of test is TRUE or FALSE.

Using arguments with side effects is allowed, but somewhat odd. I believe you should use if ... else for your case.

So what is going on for ifelse(1 <= 50, print("Yay"), print("Boo"))? The first argument is a number (vector of length 1) with just the value TRUE. So ifelse() returns a single element. Since the value is TRUE, it gets the value from the second argument. This prints "Yay", but also returns "Yay" to the ifelse() function. This returned "Yay" is then selected as the output and returned from the ifelse() call. After the call completes, this result is printed to the terminal, giving you the second line of "Yay".

CodePudding user response:

The reason is, ifelse() does two things: It prints and it returns.

See describtion of the function print.

--> print prints its argument and returns it invisibly (via invisible(x))

  • Related