Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does if_else always evaluate both 'true' and 'false' regardless of 'condition'? #5341

Closed
jwilliman opened this issue Jun 18, 2020 · 2 comments

Comments

@jwilliman
Copy link

It appears to me that if_else evaluates both the true and false arguments, and then returns only the one that matches the condition argument. This differs from ifelse which appears to only evaluate the true or false argument that matches the condition argument.

This is a problem if if_else is being used to avoid evaluating an expression that is know to fail in certain situations. Is this necessary to ensure "that true and false are the same type."? What would be a tidyverse way of handling this?

x <- list("a", 1, 2, "b")

sapply(x, function(x) ifelse(is.numeric(x), x + 1, NaN)) 
#> [1] NaN   2   3 NaN
sapply(x, function(x) dplyr::if_else(is.numeric(x), x + 1, NaN))
#> Error in x + 1: non-numeric argument to binary operator

Created on 2020-06-19 by the reprex package (v0.3.0)

@hongooi73
Copy link

hongooi73 commented Jun 19, 2020

This differs from ifelse which appears to only evaluate the true or false argument that matches the condition argument.

Eh?

> ifelse(c(FALSE, TRUE), 1:2, c(3, stop()))
Error in ifelse(c(FALSE, TRUE), 1:2, c(3, stop())) : 

What does happen is that if condition is only TRUE (or only FALSE), then the result vector that isn't needed won't be evaluated. But you can't rely on this, of course.

@lionel-
Copy link
Member

lionel- commented Jun 19, 2020

if_else() does not have short-circuiting semantics. Use if () if you need short-circuiting. It is necessary to compute both sides of the condition to figure out the return type. The code you have reported is a type error. In my opinion it is also a bit hard to understand because it relies on a strange mix of scalar predicate and recycling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants