使用 %>% 管道和点 (.) 表示法
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))
.
在嵌套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 toiris %>% 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 toc(min(1:10), max(1:10))
.