【问题标题】:Using the %>% pipe, and dot (.) notation使用 %>% 管道和点 (.) 符号
【发布时间】:2017-07-12 02:52:39
【问题描述】:

在嵌套的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)

【问题讨论】:

    标签: r magrittr


    【解决方案1】:

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

    简单管道:

    1 %>% `/`(2)
    

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

    也相当于1 %&gt;% `/`(., 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) }
    

    另请参阅?magrittr::`%&gt;%` 中的标题将点用于次要目的,内容如下:

    特别是,如果占位符仅在嵌套函数中使用 调用,lhs 也将作为第一个参数!的原因 这就是在大多数用例中,这会产生最易读的代码。 例如,iris %&gt;% subset(1:nrow(.) %% 2 == 0) 等价于 iris %&gt;% subset(., 1:nrow(.) %% 2 == 0) 但稍微紧凑一些。它 可以通过将 rhs 括在大括号中来推翻这种行为。 例如,1:10 %&gt;% {c(min(.), max(.))} 等价于 c(min(1:10), max(1:10)).

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 2021-03-15
      • 1970-01-01
      • 2018-01-03
      • 2016-08-11
      相关资源
      最近更新 更多