使用 %>% 管道和点 (.) 表示法

Using the %>% pipe, and dot (.) notation

在嵌套data_frame上使用map时,我不明白为什么后两个版本会报错,我应该如何使用点(.)?

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)

问题不在于 map,而在于 %>% 管道如何处理 .。考虑以下示例(请记住 / 是 R 中的两个参数函数):

简单的管道:

1 %>% `/`(2)

等同于 `/`(1, 2)1 / 2 并给出 0.5.

也相当于1 %>% `/`(., 2).

简单.使用:

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

等同于 `/`(2, 1)2 / 1 并给出 2.

可以看到1不再作为第一个参数,而只作为第二个。

其他.使用:

但是,当对 .:

进行子集化时
list(a = 1) %>% `/`(.$a, 2)
Error in `/`(., .$a, 2) : operator needs one or two arguments

我们可以看到 . 被注入了两次,作为第一个参数并在第二个参数中被子集化。像 .$a 这样的表达式有时被称为 嵌套函数调用 (在这种情况下, $ 函数在 / 函数内部使用) .

我们使用大括号来避免第一个参数注入:

list(a = 1) %>% { `/`(.$a, 2) }

再次给出 0.5。

实际问题:

您实际上是在呼叫 map(df, df$data, min),而不是 map(df$data, min)

解决方案:

使用大括号:

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

另请参阅 header 将圆点用于次要目的 ?magrittr::`%>%` 中的内容如下:

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)).