The problem isn't map
, but rather how the %>%
pipe deals with the .
. Consider the following examples (remember that /
is a two argument function in R):
Simple piping:
1 %>% `/`(2)
Is equivalent to `/`(1, 2)
or 1 / 2
and gives 0.5
.
It is also equivalent to 1 %>% `/`(., 2)
.
Simple .
use:
1 %>% `/`(2, .)
Is equivalent to `/`(2, 1)
or 2 / 1
and gives 2
.
You can see that 1
is no longer used as the first argument, but only as the second.
Other .
use:
This doesn't work however, when subsetting the .
:
list(a = 1) %>% `/`(.$a, 2)
Error in `/`(., .$a, 2) : operator needs one or two arguments
We can see that .
got injected twice, as the first argument and subsetted in the second argument. An expression like .$a
is sometimes referred to as a nested function call (the $
function is used inside the /
function, in this case).
We use braces to avoid first argument injection:
list(a = 1) %>% { `/`(.$a, 2) }
Gives 0.5 again.
Actual problem:
You are actually calling map(df, df$data, min)
, not map(df$data, min)
.
Solution:
Use braces:
df %>% { map(.$data, min) }
Also see the header Using the dot for secondary purposes in ?magrittr::`%>%`
which reads:
In particular, if the placeholder is only used in a nested function
call, lhs will also be placed as the first argument! The reason for
this is that in most use-cases this produces the most readable code.
For example, iris %>% subset(1:nrow(.) %% 2 == 0)
is equivalent to
iris %>% subset(., 1:nrow(.) %% 2 == 0)
but slightly more compact. It
is possible to overrule this behavior by enclosing the rhs in braces.
For example, 1:10 %>% {c(min(.), max(.))}
is equivalent to
c(min(1:10), max(1:10))
.