使用 %>% 管道和点 (.) 表示法 [英] Using the %>% pipe, and dot (.) notation

查看:25
本文介绍了使用 %>% 管道和点 (.) 表示法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

库(tidyverse)# 虚拟数据df <- tibble(id = rep(1:10, each = 10),val = runif(100))df <- 嵌套(df,-id)# 按预期工作地图(df$数据,分钟)df %>% .$data %>% map(., min)# 给出错误df %>% map(.$data, min)# 错误:不知道如何在级别 1 使用列表类型的对象进行索引df %>% 地图(数据,最小值)

解决方案

问题不在于 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)

<块引用>

`/`(., .$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 %>% subset(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.

It is also equivalent to 1 %>% `/`(., 2).

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)

Error in `/`(., .$a, 2) : operator needs one or two arguments

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:

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

这篇关于使用 %>% 管道和点 (.) 表示法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆