В map (), когда необходимо использовать тильду и точку.(~ и.) - PullRequest
0 голосов
/ 16 июня 2019

Я рассматриваю примеры map() из 'R For Data Science'.

Один из примеров:

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

В приведенной ниже карте_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

Я пытался прочитать предыдущие ответы, например Что означает первый тильда в purrr :: map , но яЯ до сих пор не уверен в точной разнице в том, когда мне нужно использовать тильду и .

Возможно, мне будет проще всего просто включить эти две вещи, даже если они не являются строгонеобходимо?

Ответы [ 2 ]

2 голосов
/ 16 июня 2019

Я не специалист по карте, но вот почему я думаю, что в этом случае вы должны использовать тильду. Я считаю, что это связано с применением формулы против функции.

Вот пример, где вам не нужно было бы. В этом случае я беру список цилиндров и отправляю его в функцию:

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

В справочной карте определяется как: функции карты преобразуют свои входные данные, применяя функцию к каждому элементу и возвращая вектор такой же длины, что и входные данные. Я считаю, что тильда превращает вашу формулу в функцию.

1 голос
/ 16 июня 2019

Быстрый ответ на ваш вопрос: при вызове карты никогда не нужно использовать обозначение тильды.Существуют разные способы вызова карты, и нотация тильды является одним из них.Вы уже описали простой способ вызова карты, когда функция принимает / нуждается только в одном аргументе.

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

Нотация тильды в основном превращает формулу в функцию, которую в большинстве случаев легче читать.Каждая опция может быть превращена в именованную функцию, которая работает следующим образом.В идеале именованная функция уменьшает сложность базовой функции до одного аргумента (тот, который должен быть зациклен), и в этом случае функцию можно вызывать, как и все простые функции в карте, без дополнительных аргументов / обозначений.

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

В основном это ваши варианты.Вы должны выбрать то, что является самым простым и наиболее подходящим для вашей проблемы.Именованные функции лучше, если они вам понадобятся снова.Многие думают, что функции картостроителя легче читать, но в конце концов это выбор личных предпочтений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...