Как я могу использовать аргументы функции, если переменные существуют с одинаковыми именами? - PullRequest
1 голос
/ 01 ноября 2019

Если у меня есть столбец в data.frame, имя которого совпадает с именем одного из аргументов моей функции, имя столбца используется при попытке mutate или filter.

Есть ли способ явно использовать параметр функции?

Воспроизводимый пример:

my_function <- function(x) {
  my_tib <- tribble(
    ~x, ~y,
    1,  5,
    2,  10,
    3,  15
  )

  my_tib %>%
    mutate(z = x * y)
}

my_function(x=100)

## A tibble: 3 x 3
#      x     y     z
#  <dbl> <dbl> <dbl>
#1     1     5     5
#2     2    10    20
#3     3    15    45

Желаемый результат:

my_function(x=100)

## A tibble: 3 x 3
#      x     y     z
#  <dbl> <dbl> <dbl>
#1     1     5    500
#2     2    10    1000
#3     3    15    1500

Ответы [ 2 ]

3 голосов
/ 01 ноября 2019

Вы можете использовать оператор {{, хотя во-первых, избежание конфликта кажется лучшим способом избежать возможных головных болей.

library(dplyr)

my_function <- function(x) {
  my_tib <- tribble(
    ~x, ~y,
    1,  5,
    2,  10,
    3,  15
  )

  my_tib %>%
    mutate(z = {{x}} * y)
}

my_function(100)

# A tibble: 3 x 3
      x     y     z
  <dbl> <dbl> <dbl>
1     1     5   500
2     2    10  1000
3     3    15  1500
2 голосов
/ 04 ноября 2019

В текущем принятом ответе предлагается использовать фигурную-фигурную для подстановки аргумента функции.

my_tib <- tribble(
  ~x, ~y,
  1,  5,
  2,  10,
  3,  15
)

my_function_nse <- function(data, x) {
  data %>% mutate(z = {{ x }} * y)
}

Это хорошо работает с литеральными числами:

my_tib %>% my_function_nse(100)
#> # A tibble: 3 x 3
#>       x     y     z
#>   <dbl> <dbl> <dbl>
#> 1     1     5   500
#> 2     2    10  1000
#> 3     3    15  1500

Однако выПри использовании переменных возникнет та же проблема с маскированием данных:

x <- 100
my_tib %>% my_function_nse(x)
#> # A tibble: 3 x 3
#>       x     y     z
#>   <dbl> <dbl> <dbl>
#> 1     1     5     5
#> 2     2    10    20
#> 3     3    15    45

Здесь происходит то, что переменная данных x имеет приоритет над переменной среды x. Чтобы обойти это, пользователю необходимо принудительно вызвать env-var x с помощью оператора принудительного ввода !!:

my_tib %>% my_function_nse(!!x)
#> # A tibble: 3 x 3
#>       x     y     z
#>   <dbl> <dbl> <dbl>
#> 1     1     5   500
#> 2     2    10  1000
#> 3     3    15  1500

. Вы также можете принудительно вызвать внутри функции:

my_function_se <- function(data, x) {
  data %>% mutate(z = !!x * y)
}

В этом случае ваша функция вообще не использует NSE. У него нет проблемы маскирования данных:


my_tib %>% my_function_se(x)
#> # A tibble: 3 x 3
#>       x     y     z
#>   <dbl> <dbl> <dbl>
#> 1     1     5   500
#> 2     2    10  1000
#> 3     3    15  1500

Конечно, с другой стороны, вы вообще не можете ссылаться на переменные данных:

my_tib %>% my_function_se(y + 10)
#> Error : object 'y' not found

my_tib %>% my_function_nse(y + 10)
#> # A tibble: 3 x 3
#>       x     y     z
#>   <dbl> <dbl> <dbl>
#> 1     1     5    75
#> 2     2    10   200
#> 3     3    15   375
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...