Что означает оператор "!!" в R?

подскажите плиз, что означает оператор !!

Например в этой строчке? filter(!is.na(!! x) & !is.na(!! y))


Ответы (1 шт):

Автор решения: rg4s

Мне самому трудно понять, что делает этот оператор, но я постараюсь объяснить.

!! ловит шаблоны для значений x и y. Например, рассмотрим функцию, которая будет считать среднее арифметическое по группам:

mean_by <- function(data, var, by) {
  data %>%
    group_by(by) %>%
    summarise(mean = mean(var, na.rm = TRUE))
}

Если в качестве аргументов нашей функции мы вставим названия переменных из загруженных в среду R датасетов, то наша функция выдаст ошибку:

starwars %>% mean_by(mass, by = gender)
> Error: Column `by` is unknown

Функция считала "маску", но не совсем так, как нам нужно. Для нормальной работы функции нам нужно, чтобы среда "открыла скобки" для манипуляции с входными атрибутами:

mean_by <- function(data, var, by) {
  data %>%
    group_by(!!enquo(by)) %>%
    summarise(mean = mean(!!enquo(var), na.rm = TRUE))
}

starwars %>% mean_by(mass, by = gender)
> # A tibble: 5 x 2...

Еще полезно знать про оператор curly-curly - две фигурные скобки. Оператор эксплицирует конкретно те значения, которые подходят под входные данные:

mean_by <- function(data, var, by) {
  data %>%
    group_by({{ by }}) %>%
    summarise(mean = mean({{ var }}, na.rm = TRUE))
}

starwars %>% mean_by(height) 

Также есть следующая инфа из rlang, которая может навести на правильную мысль:

The main purpose of defusing evaluation of an expression is to enable data-masking, where an expression is evaluated in the context of a data frame so that you can write var instead of data$var. The expression is defused so it can be resumed later on, in a context where the data-variables have been defined.

Больше информации:

  1. Пост в блоге Tidyverse: https://www.tidyverse.org/blog/2019/06/rlang-0-4-0/
  2. Учебник Хэдли Викхема: https://adv-r.hadley.nz/quasiquotation.html#unquoting
  3. ?dplyr_data_masking также поможет немного разобраться
→ Ссылка