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
Anonymous functions in pmap #203
Comments
The function should work on the tuple that comes from selecting elements i from all the lists. I almost always do this with data frames, in which case the function should operate on one row. In your case, you could specify sum to just "add everything up". pmap(list(a, b, c), sum)
#> $name1
#> [1] 7
#>
#> $name2
#> [1] 61
#>
#> $name3
#> [1] 601 Or you can use argument matching by position or name (in which case it's really important to name your input list!). pmap(list(a, b, c), function(x, y, z) x^2 + exp(y) + (z - 1))
#> $name1
#> [1] 7.718282
#>
#> $name2
#> [1] 22076.47
#>
#> $name3
#> [1] 2.688117e+43
f <- function(c, b, a) c - b - a
pmap(dplyr::lst(a, b, c), f)
#> $name1
#> [1] 3
#>
#> $name2
#> [1] 39
#>
#> $name3
#> [1] 399
pmap(dplyr::lst(b, c, a), f)
#> $name1
#> [1] 3
#>
#> $name2
#> [1] 39
#>
#> $name3
#> [1] 399 One gotcha is that you have to use all members of the tuple. I'm not really sure why that is necessary. pmap(dplyr::lst(a, b, c), function(x, y) x^2 + exp(y))
#> Error in .f(a = .l[[c(1L, i)]], b = .l[[c(2L, i)]], c = .l[[c(3L, i)]], : unused arguments (a = .l[[c(1, i)]], b = .l[[c(2, i)]], c = .l[[c(3, i)]]) |
Thanks a million, you've totally cleared that up for me. I suppose then that the shorthand
but I suppose |
Could extracting from the
or more generic, if there is a reason why
|
The anonymous function is not evaluated in an environment where > purrr::pmap
function (.l, .f, ...)
{
.f <- as_function(.f, ...)
.Call(pmap_impl, environment(), ".l", ".f", "list")
}
<environment: namespace:purrr> So you can see here, |
This could simply be: pmap <- function(.l, .f, ...) {
.f <- rlang::as_function(.f, ...)
.f <- rlang::env_bury(.f, .l = .l)
.Call(pmap_impl, environment(), ".l", ".f", "list")
}
pmap(list(a = 1, b = 2, c = 3), ~ .l$a + .l$b + .l$c)
#> [[1]]
#> [1] 6 |
but should probably only be applied to formulas otherwise this could have surprising effects |
@dandermotj - thanks for clearing that up, I understand now why it won't work (given the current wrapper function.) @lionel- that's a pretty incredible piece of code! Is a similarly "improved" wrapper function something that could be released in future? (perhaps with a relevant check for |
This doesn't do the job for me as soon as I replace the 1-dim list by a data.frame (or any other 2-dim structure): pmap_gh <- function(.l, .f, ...) {
.f <- rlang::as_function(.f, ...)
.f <- rlang::env_bury(.f, .l = .l)
.Call(purrr:::pmap_impl, environment(), ".l", ".f", "list")
}
# unexpected behaviour
pmap_gh(list(a = 1:2, b = 2:3, c = 3:4), ~ .l$a + .l$b + .l$c)
> [[1]]
[1] 6 9
[[2]]
[1] 6 9
# expected behaviour
pmap(list(a = 1:2, b = 2:3, c = 3:4), function(a, b, c) a + b + c)
> [[1]]
[1] 6
[[2]]
[1] 9 Unless I'm missing something I would like to open a new issue with the feature request to expose all arguments to the function without explicitely specifying them. I don't mind providing them for 3 arguments as above but pmap is from my point of view amazing when it comes to row-wise data.frame operations (often an anti-pattern but it has its applications) and I hate providing 40 arguments (all of which are dynamically being accessed in the function using edit: I know I can use pmap within data.table (and I would assume |
You can use slider::slide(as.data.frame(x), ~ .x$a + .x$b + .x$c)
#> [[1]]
#> [1] 6
#>
#> [[2]]
#> [1] 9 We might provide a similar feature in purrr. No need to open an issue though. |
Excellent, works like a charm with the examples I had in mind. Cheers |
The documentation for
pmap
is bundled in withmap2
and doesn't include anypmap
specific examples. This makes it unclear how to access lists in.f
, and after a lot of investigation I'm still stumped. Inmap2
, the variables are simply.x
and.y
, and in the deprecatedmap3
were.x
,.y
and.z
. The below example works for the first two lists, but I have no idea how access the third list.Obviously this pattern could not extend to a list of length n, but I can't work out what the convention could be. If this is me missing something blatant or
pmap
is not designed to work in this way, then I apologise!The text was updated successfully, but these errors were encountered: