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

Translation of dplyr::if_else() breaks if .data$var is used #220

Closed
mrcaseb opened this issue Mar 8, 2021 · 1 comment
Closed

Translation of dplyr::if_else() breaks if .data$var is used #220

mrcaseb opened this issue Mar 8, 2021 · 1 comment

Comments

@mrcaseb
Copy link

mrcaseb commented Mar 8, 2021

I am using dplyr inside a package and therefore do .data$var to avoid tidy evaluation R CMD check NOTEs

dtplyr translates this falsely inside a dplyr::if_else()

library(data.table)
library(dtplyr)
library(dplyr, warn.conflicts = FALSE)

tib_lazy <- tibble::tibble(num = 1:5) %>% 
  dtplyr::lazy_dt() %>% 
  dplyr::mutate(
    # don't use .data$ -> works well
    lvl = dplyr::if_else(num <= 3, "low", "high"),
    # use .data$ in if_else -> the string ".data$" remains in the query
    lvl_.data = dplyr::if_else(.data$num <= 3, "low", "high"),
    # use .data$ in base ifelse -> works but doesn't call fifelse
    lvl_alt = ifelse(.data$num <= 3, "low", "high"),
    # use .data$ outside if_else works well
    num_alt = .data$num * 10
  )

# lvl_.data is NA
# note the string ".data$" in the fifelse query of the lvl_.data variable

tib_lazy
#> Source: local data table [5 x 5]
#> Call:   copy(`_DT1`)[, `:=`(lvl = fifelse(num <= 3, "low", "high"), lvl_.data = fifelse(.data$num <= 
#>     3, "low", "high"), lvl_alt = ifelse(num <= 3, "low", "high"), 
#>     num_alt = num * 10)]
#> 
#>     num lvl   lvl_.data lvl_alt num_alt
#>   <int> <chr> <chr>     <chr>     <dbl>
#> 1     1 low   <NA>      low          10
#> 2     2 low   <NA>      low          20
#> 3     3 low   <NA>      low          30
#> 4     4 high  <NA>      high         40
#> 5     5 high  <NA>      high         50
#> 
#> # Use as.data.table()/as.data.frame()/as_tibble() to access results

Created on 2021-03-08 by the reprex package (v1.0.0)

@hadley
Copy link
Member

hadley commented Mar 8, 2021

Somewhat more minimal reprex:

library(dtplyr)
library(dplyr, warn.conflicts = FALSE)

dt <- lazy_dt(tibble(x = 1:5))

dt %>% 
  mutate(y = dplyr::if_else(.data$x <= 3, 1, 2)) %>% 
  show_query()
#> copy(`_DT1`)[, `:=`(y = fifelse(.data$x <= 3, 1, 2))]

Created on 2021-03-08 by the reprex package (v1.0.0)

I also see:

library(dtplyr)
library(dplyr, warn.conflicts = FALSE)

dt <- lazy_dt(tibble(x = 1:5))

dt %>% 
  mutate(y = dplyr::if_else(.data$x <= 3, 1, 2))
#> Error in fifelse(.data$x <= 3, 1, 2): could not find function "fifelse"

Created on 2021-03-08 by the reprex package (v1.0.0)

which suggests we forgot to add fifelse to dt_env().

And seems like it's worth translating ifelse() too.

@hadley hadley closed this as completed in 9c83443 Mar 8, 2021
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

2 participants