Usando la notación %>% barra vertical y punto (.)

Resuelto johannes asked hace 54 años • 1 respuestas

Cuando lo uso mapen un data_frame 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)
johannes avatar Jan 01 '70 08:01 johannes
Aceptado

El problema no es map, sino más bien cómo %>%maneja la tubería el .. Considere los siguientes ejemplos (recuerde que /es una función de dos argumentos en R):

Tuberías sencillas:

1 %>% `/`(2)

Equivale a `/`(1, 2)o 1 / 2y da 0.5.

También es equivalente a 1 %>% `/`(., 2).

Uso sencillo .:

1 %>% `/`(2, .)

Equivale a `/`(2, 1)o 2 / 1y da 2.

Puedes ver que 1ya no se utiliza como primer argumento, sino sólo como segundo.

Otro .uso:

Sin embargo, esto no funciona cuando se subconjunto .:

list(a = 1) %>% `/`(.$a, 2)
Error in `/`(., .$a, 2) : operator needs one or two arguments

Podemos ver que .se inyectó dos veces, como primer argumento y como subconjunto en el segundo argumento. Una expresión como .$aa veces se denomina llamada a función anidada (en este caso, la $función se usa dentro de la /función).

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ás llamando map(df, df$data, min), no map(df$data, min).

Solución:

Utilice aparatos ortopédicos:

df %>% { map(.$data, min) }

Véase también el encabezado Uso del punto con fines secundarios en ?magrittr::`%>%`el que se lee:

En particular, si el marcador de posición solo se usa en una llamada a 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 iris %>% subset(., 1:nrow(.) %% 2 == 0)pero ligeramente más compacto. Es posible anular este comportamiento encerrando el derecho entre llaves. Por ejemplo, 1:10 %>% {c(min(.), max(.))}equivale a c(min(1:10), max(1:10)).

Axeman avatar Feb 22 '2017 09:02 Axeman