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

if_else produce unnecessary warning in mutate #6877

Closed
mghaderizefreh opened this issue Jul 5, 2023 · 4 comments
Closed

if_else produce unnecessary warning in mutate #6877

mghaderizefreh opened this issue Jul 5, 2023 · 4 comments

Comments

@mghaderizefreh
Copy link

the function if_else combined with mutate will produce warnings which are not appropriate.

Consider foo to be

foo <- tibble(fac = rep(c('linear','exp'), each = 2), value = c(-2,-1,1,2))

Now, I want to log-transform the exponential part.

bar <- foo %>% mutate(if_else("exp" == fac, log(value), value)

This produces the desired output but will give a warning

Warning message:
There was 1 warning in `mutate()`.
In argument: `if_else(fac == "exp", log(value), value)`.
Caused by warning in `log()`:
! NaNs produced 

even though there is no NaN in bar.

@joranE
Copy link
Contributor

joranE commented Jul 5, 2023

mutate() isn't necessary to produce the warnings, they appear if you just run if_else() and are expected. if_else() can't know up front what the TRUE/FALSE values in the expression will be, so it calculated both log(value) and value in their entirety up front, and then constructs the output from the results.

I could have sworn this behavior was explicitly mentioned in the documentation (and for ifelse) but unless my tired eyes are just glossing over it, I can't find it.

Edit: Ah, here is what I recalled in ?ifelse: "yes will be evaluated if and only if any element of test is true, and analogously for no" which is cryptic, but means to imply that the entire yes condition will be evaluated if there is any TRUE in the condition, regardless of each individual value. if_else() behaves similarly, though I can't find a similar (if cryptic) statement to that effect.

@banbh
Copy link

banbh commented Jul 7, 2023

if_else appears to be stricter than ifelse. For example, ifelse(c(TRUE,TRUE), 1, stop()) succeeds, but if_else(c(TRUE,TRUE), 1, stop()) generates an error. (Perhaps this is a result of the type stability of if_else.)

@psychelzh
Copy link

psychelzh commented Jul 10, 2023

This is by design, and see the documentation:

Compared to the base R equivalent, ifelse(), this function allows you to handle missing values in the condition with missing and always takes true, false, and missing into account when determining what the output type should be.

For more discussions, see also #3637. In light of this, I think this issue should be closed.

@DavisVaughan
Copy link
Member

As others have said, the fact that if_else() and case_when() fully evaluate all conditions is by design and due to type stability. I think it is mostly clear from the description of:

always takes true, false, and missing into account when determining what the output type should be.

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

5 participants