Usando la tubería%>% y la notación de punto(.)
magrittr (1)
El problema no es el
map
, sino cómo la tubería
%>%
trata con el
.
.
Considere los siguientes ejemplos (recuerde que
/
es una función de dos argumentos en R):
Tubería simple:
1 %>% `/`(2)
Es equivalente a
`/`(1, 2)
o
1 / 2
y da
0.5
.
Simple utilizar:
1 %>% `/`(2, .)
Es equivalente a
`/`(2, 1)
o
2 / 1
y da
2
.
Puede ver que
1
ya no se usa como el primer argumento, sino solo como el segundo.
Otros utilizar:
Sin embargo,
esto no
funciona cuando se subconjusta el
.
:
list(a = 1) %>% `/`(.$a, 2)
Error in `/`(., .$a, 2) : operator needs one or two arguments
Podemos ver eso
.
fue inyectado dos veces, como el primer argumento y subconjunto en el segundo argumento.
Una expresión como
.$a
veces se denomina
llamada de función anidada
(la función
$
se usa dentro de la función
/
, en este caso).
Usamos llaves para evitar la inyección del primer argumento:
list(a = 1) %>% { `/`(.$a, 2) }
Da 0.5 de nuevo.
Problema real:
En realidad, está llamando a
map(df, df$data, min)
, no
map(df$data, min)
.
Solución:
Use llaves:
df %>% { map(.$data, min) }
Consulte también el encabezado
Uso del punto para fines secundarios
en
?magrittr::`%>%`
que dice:
En particular, si el marcador de posición solo se usa en una llamada de función anidada, ¡lhs también se colocará como primer argumento! La razón de esto es que en la mayoría de los casos de uso esto produce el código más legible. Por ejemplo,
iris %>% subset(1:nrow(.) %% 2 == 0)
es equivalente airis %>% subset(., 1:nrow(.) %% 2 == 0)
pero un poco más compacto . Es posible anular este comportamiento encerrando los rhs entre llaves. Por ejemplo,1:10 %>% {c(min(.), max(.))}
Es equivalente ac(min(1:10), max(1:10))
.
Cuando uso el
map
en un marco de datos anidado, no entiendo por qué las dos últimas versiones dan un error, ¿cómo debo usar el punto (
.
)?
library(tidyverse)
# dummy data
df <- tibble(id = rep(1:10, each = 10),
val = runif(100))
df <- nest(df, -id)
# works as expected
map(df$data, min)
df %>% .$data %>% map(., min)
# gives an error
df %>% map(.$data, min)
# Error: Don''t know how to index with object of type list at level 1
df %>% map(data, min)