tidyverse / purrr

A functional programming toolkit for R
https://purrr.tidyverse.org/
Other
1.27k stars 274 forks source link

lazy evaluation cannot be disabled `partial` inside grouped tibble #1073

Closed idavydov closed 1 year ago

idavydov commented 1 year ago

I'm trying to create a list-column with functions. Each function should depend on arguments from that tibble row, so I'm using purrr::partial().

It seems that it's impossible to reproduce the .lazy = FALSE behavior with the !! syntax.

# works, but deprecated
tibble::tibble(x = 1:3) |> 
  dplyr::rowwise() |> 
  dplyr::mutate(square_root = list(purrr::partial(sqrt, x, .lazy = FALSE)))
#> Warning: There were 3 warnings in `dplyr::mutate()`.
#> The first warning was:
#> ℹ In argument: `square_root = list(purrr::partial(sqrt, x, .lazy = FALSE))`.
#> ℹ In row 1.
#> Caused by warning:
#> ! The `.lazy` argument of `partial()` is deprecated as of purrr 0.3.0.
#> ℹ Run `dplyr::last_dplyr_warnings()` to see the 2 remaining warnings.
#> # A tibble: 3 × 2
#> # Rowwise: 
#>       x square_root
#>   <int> <list>     
#> 1     1 <prrr_fn_> 
#> 2     2 <prrr_fn_> 
#> 3     3 <prrr_fn_>

# fails
tibble::tibble(x = 1:3) |> 
  dplyr::rowwise() |> 
  dplyr::mutate(square_root = list(purrr::partial(sqrt, !!x)))
#> Error in quos(..., .ignore_empty = "all"): object 'x' not found

# fails
tibble::tibble(x = 1:3) |> 
  dplyr::rowwise() |> 
  dplyr::mutate(square_root = list(purrr::partial(sqrt, !!.data$x)))
#> Error in quos(..., .ignore_empty = "all"): object '.data' not found

Created on 2023-04-20 with reprex v2.0.2

CC @klmr

hadley commented 1 year ago

The problem is that the !! is getting evaluated by mutate instead of by partial(). I think the easiest way to work around this is to just construct the function factory yourself:

library(tidyverse)

my_sqrt <- function(x) {
  force(x)
  function() sqrt(x)
}

tibble(x = 1:3) |> 
  rowwise() |> 
  mutate(square_root = list(my_sqrt(x)))
#> # A tibble: 3 × 2
#> # Rowwise: 
#>       x square_root
#>   <int> <list>     
#> 1     1 <fn>       
#> 2     2 <fn>       
#> 3     3 <fn>

Created on 2023-07-26 with reprex v2.0.2