问题描述
在嵌套的data_frame上使用map
时,我不明白为什么后两个版本会出错,我应该如何使用点(.
)?>
图书馆(tidyverse)# 虚拟数据df <- tibble(id = rep(1:10, each = 10),val = runif(100))df % map(.$data, min)# 错误:不知道如何在级别 1 使用列表类型的对象进行索引df %>% 地图(数据,分钟)
问题不在于 map
,而在于 %>%
管道如何处理.考虑以下示例(请记住,/
是 R 中的两个参数函数):
简单的管道:
1 %>% `/`(2)
等价于`/`(1, 2)
或1/2
并给出0.5
.
简单的.
使用:
1 %>% `/`(2, .)
等价于 `/`(2, 1)
或 2/1
并给出 2
.
您可以看到 1
不再用作第一个参数,而仅用作第二个参数.
其他.
使用:
这不起作用但是,当子集时.
:
list(a = 1) %>% `/`(.$a, 2)
`/`(., .$a, 2) 中的错误:操作符需要一两个参数
我们可以看到 .
被注入了两次,作为第一个参数和第二个参数的子集.像 .$a
这样的表达式有时被称为 嵌套函数调用($
函数用在 /代码>函数,在这种情况下).
我们使用大括号来避免第一个参数注入:
list(a = 1) %>% { `/`(.$a, 2) }
再次给出 0.5.
实际问题:
您实际上是在调用 map(df, df$data, min)
,而不是 map(df$data, min)
.
解决方案:
使用大括号:
df %>% { map(.$data, min) }
另见?magrittr::`%>%`
中的标题将点用于次要目的,其内容如下:
特别是,如果占位符仅用于嵌套函数中调用,lhs 也将作为第一个参数放置!的原因这是在大多数用例中,这会产生最易读的代码.例如,iris %>% subnet(1:nrow(.) %% 2 == 0)
等价于iris %>% subset(., 1:nrow(.) %% 2 == 0)
但稍微紧凑一些.它可以通过将 rhs 括在大括号中来否决这种行为.例如, 1:10 %>% {c(min(.), max(.))}
等价于c(min(1:10), max(1:10))
.
When using map
on a nested data_frame, I do not understand why the latter two version give an error, how should I use the dot (.
)?
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)
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
.
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)
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:
这篇关于使用 %>% 管道和点 (.) 表示法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!