1
m <- 10
mtcars %>% dplyr::mutate(disp = rlang::.data$disp * .env$m)

The above does not work.

The goal is to be able to remove the importFrom rlang .data that my package has.

What is the alternative way to achieve that if the prefix method does not work?

MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • Why can't you use `disp` i.e. `mtcars %>% dplyr::mutate(disp = disp * .env$m)`. Based on the example, the `disp` doesn't need any `.data$`. Even in grouped data – akrun Dec 23 '21 at 17:19
  • 1
    As far as I can tell (https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html), `.data` is a `dplyr` thing ... and it's just a pronoun, so not something exported as `dplyr::.data`. Perhaps `mutate(disp = cur_data()$disp * .env$m)`? – r2evans Dec 23 '21 at 17:20
  • @akrun yes you correct, for this particular example, it isn't needed – Bear Bile Farming is Torture Dec 23 '21 at 17:22
  • @r2evans the example worked. But will it work in general? i.e., where ever there is `.data`, I can replace it with `cur_data()`? – Bear Bile Farming is Torture Dec 23 '21 at 17:23
  • @free_lions_n_tigers_from_cages no, it depends on the context. `cur_data()` only works in certain cases – akrun Dec 23 '21 at 17:23
  • I think so but I'm not sure. Another alternative is to use `mutate(disp = .data$disp * .env$m)` and add `utils::globalVariables(".data")` somewhere in your package (not within a function) so that R check won't complain about `.data` being uninitialized and not found. (I have not verified that R-check complains about it, but ... try it for yourself :-) – r2evans Dec 23 '21 at 17:24
  • Actually, from that same link, use `#' @importFrom rlang .data`. So I guess it *is* an `rlang` thing, my bad. (I got that from the section conveniently titled *"Eliminating `R CMD check` NOTEs"* :-) – r2evans Dec 23 '21 at 17:25
  • Try assigning `d <-rlang::.data` and `e <- rlang::.env`. I was able to get the check past that problem, but not the recognizing the `%>%` pipe problem. –  Dec 23 '21 at 21:56

1 Answers1

0

As mentioned in my other answer dplyr::cur_data_all() should be an alternative which works instead of .data. I have not yet seen a case where cur_data_all() doesn't work inside data-masking dplyr verbs, but .data does. We can also access grouping variables, which doesn't work with cur_data():

library(dplyr)

mtcars %>%
  group_by(cyl) %>%
  transmute(x = cur_data()[["cyl"]],
            y = .data[["cyl"]],
            z = cur_data_all()[["cyl"]]) 
#> # A tibble: 32 x 3
#> # Groups:   cyl [3]
#>      cyl     y     z
#>    <dbl> <dbl> <dbl>
#>  1     6     6     6
#>  2     6     6     6
#>  3     4     4     4
#>  4     6     6     6
#>  5     8     8     8
#>  6     6     6     6
#>  7     8     8     8
#>  8     4     4     4
#>  9     4     4     4
#> 10     6     6     6
#> # … with 22 more rows

However, outside of dplyr verbs cur_data_all() cannot be used, while .data will work depending on the context. This is the case in tibbles for example:

library(dplyr)

tibble(new = 1,
       new2 = .data$new)
#> # A tibble: 1 x 2
#>     new  new2
#>   <dbl> <dbl>
#> 1     1     1

tibble(new = 1,
       new2 = cur_data_all()$new)
#> Error in context_peek("mask", fun): `cur_data_all()` must only be used inside dplyr verbs.

Although cur_data() and cur_data_all() throw an error saying they can only be used inside dplyr verbs this is only half true. They can only be used inside data-masking dplyr verbs. However, this also holds true for .data which won't work in verbs supporting tidy selection:

library(dplyr)

mtcars %>% 
  select(6)
#>                        wt
#> Mazda RX4           2.620
#> Mazda RX4 Wag       2.875
#> Datsun 710          2.320
#> Hornet 4 Drive      3.215
#> Hornet Sportabout   3.440
#> Valiant             3.460
...

mtcars %>% 
  select(first(.data$cly)) # should be 6 the same as above
#> Error in stop_fake_data_subset(): Can't subset `.data` outside of a data mask context.

mtcars %>% 
  select(first(cur_data_all()$cly)) # should be 6 the same as above
#> Error in context_peek("mask", fun): `cur_data_all()` must only be used inside dplyr verbs.

Created on 2021-12-23 by the reprex package (v0.3.0)

TimTeaFan
  • 17,549
  • 4
  • 18
  • 39
  • 1
    This needs to work inside a package. –  Dec 23 '21 at 21:53
  • My understanding, which might be wrong, is that the package is using dplyr and that the goal is to only get rid of the direct dependency to rlang. In this case replacing `.data` with `cur_data_all()` should work. Of course there would still be an indirect dependency to rlang. – TimTeaFan Dec 23 '21 at 22:14