【问题标题】:In map(), when is it necessary to use a tilde and a period. (~ and .)在 map() 中,什么时候需要使用波浪号和句号。 (〜和。)
【发布时间】:2019-10-30 10:36:08
【问题描述】:

我正在浏览“R For Data Science”中map() 的示例。

一个例子是:

library(dplyr)
library(purrr)
df <- tibble(
  a = rnorm(10),
  b = rnorm(10),
  c = rnorm(10),
  d = rnorm(10)
)

df
#> # A tibble: 10 x 4
#>         a      b       c       d
#>     <dbl>  <dbl>   <dbl>   <dbl>
#>  1 -0.570  1.48   2.37    1.60  
#>  2  0.122  2.08   0.222   0.0338
#>  3 -0.890  0.429 -1.75   -1.48  
#>  4  0.334  0.854  0.849  -0.525 
#>  5  1.22  -0.378 -1.00   -0.147 
#>  6 -1.04  -0.427 -1.18    0.907 
#>  7 -0.392  0.102  0.0951  0.842 
#>  8  0.893  0.932  0.620  -0.911 
#>  9  1.00   0.616 -0.937  -0.0286
#> 10  0.190  1.12  -1.02    1.45

在下面的 map_dbl() 中,我不需要在函数 map_dbl(~ mean) 之前添加波浪号,也不必放置 .

df %>% map_dbl(mean)

#>           a           b           c           d 
#>  0.08714704  0.68069227 -0.17382734  0.17470388

然而,在下面的示例中,我必须将 ~ 放在 .f 之前,我还必须指定 data = .

models <- mtcars %>% 
  split(.$cyl) %>% 
  map(~ lm(mpg ~ wt, data = .))
models

我已经尝试阅读以前的答案,例如What is meaning of first tilde in purrr::map,但我仍然不确定何时需要使用波浪号和. 的确切区别

也许对我来说最简单的方法是总是包含这两件事,即使它们不是绝对必要的?

【问题讨论】:

    标签: r dplyr tidyverse purrr


    【解决方案1】:

    我不是地图专家,但这就是为什么我认为在这种情况下你必须使用波浪号。我认为这与应用公式与函数有关。

    这是一个您不必这样做的示例。在这种情况下,我将列出圆柱体并将其发送到函数:

    cyl = mtcars%>%
      select(cyl)%>%
      unique%>%
      unlist()
    
    model = function(CYL){
    
      lm(mpg ~ wt, data = mtcars%>%
           filter(cyl == !!CYL))
    }
    
    cyl%>%
      map(model)
    

    在您的示例中,您应用的是公式而不是函数。这是另一个必须使用波浪号的示例:

    models <- mtcars %>% 
      split(.$cyl) %>% 
      map(~.$mpg+.$cyl)
    models
    

    在帮助中,map 被定义为:map 函数通过对每个元素应用一个函数并返回一个与输入长度相同的向量来转换其输入。我相信波浪号正在将您的公式变成一个函数。

    【讨论】:

      【解决方案2】:

      对您的问题的快速回答是,调用 map 时永远不需要使用波浪号表示法。调用 map 的方式有很多种,波浪符号就是其中之一。您已经描述了调用 map 的最简单方法,即函数只接受/需要一个参数。

      df %>% map_dbl(mean)
      

      但是,当函数变得更复杂时,基本上有两种方法可以使用波浪符号或普通匿名函数来调用它们。

      # normal anonymous function
      models <- mtcars %>% 
        split(.$cyl) %>% 
        map(function(x) lm(mpg ~ wt, data = x))
      
      # anonymous mapper function (~)
      models <- mtcars %>% 
        split(.$cyl) %>% 
        map(~ lm(mpg ~ wt, data = .))
      

      波浪符号基本上是将公式转换为函数,这在大多数情况下更容易阅读。每个选项都可以变成一个命名函数,其工作原理如下。理想情况下,命名函数将底层函数的复杂性降低到一个参数(应该循环的那个),在这种情况下,该函数可以像 map 中的所有简单函数一样被调用,而无需进一步的参数/符号。

      # normal named function notation 
      lm_mpg_wt <- function(x) {
        lm(mpg ~ wt, data = x)
      }
      
      models <- mtcars %>% 
        split(.$cyl) %>% 
        map(lm_mpg_wt)
      
      
      # named mapper function
      mapper_lm_mpg_wt <- as_mapper(~ lm(mpg ~ wt, data = .))
      
      models <- mtcars %>% 
        split(.$cyl) %>% 
        map(mapper_lm_mpg_wt)
      

      基本上这些是您的选择。您应该选择最简单且最适合您的问题的方法。如果您再次需要它们,命名函数是最好的。许多人认为映射器函数更易于阅读,但归根结底,这是个人喜好的选择。

      【讨论】:

        猜你喜欢
        • 2020-10-10
        • 2010-11-07
        • 1970-01-01
        • 2021-11-15
        相关资源
        最近更新 更多