dplyr .data местоимение против подхода "quosure"

В dplyr v0.7.0.data было введено местоимение, которое позволило нам ссылаться на переменные со строками. Мне просто было любопытно, предпочтительнее ли этот подход по сравнению с подходом "quosure". Например, вот подход, который использует .data местоимение:

varname <- "gear"
data_pronoun_method_df <- dplyr::mutate(mtcars, new_col = .data[[varname]] + 2)

Это сравнивается с примером использования quosure подход:

quo_varname <- rlang::quo(gear)
quo_method_df <- dplyr::mutate(mtcars, new_col = !! quo_varname + 2)

Оба метода выдают одинаковый результат:

data_pronoun_method_df

# mpg cyl  disp  hp drat    wt  qsec vs am gear carb new_col
# 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4       6
# 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4       6
# 3  22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1       6
# 4  21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1       5
# 5  18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2       5
# 6  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1       5
# 7  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4       5
# 8  24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2       6
# [ reached getOption("max.print") -- omitted 24 rows ]

all.equal(data_pronoun_method_df, quo_method_df)
# [1] TRUE

Есть ли реальная разница? Каковы преимущества и недостатки любого метода?

1 ответ

Решение

.data Местоимение может быть полезно для обхода NSE, но оно более или менее ортогонально аккуратному eval. Его основная цель - убедиться, что переменная будет найдена во фрейме данных. Если он не существует, вы получаете ошибку. Это в отличие от голых имен, которые могут поднять локальные объекты, если они определены:

other <- 1e10
transmute(mtcars, 2 * other)            # Succeeds erroneously
transmute(mtcars, 2 * .data[["other"]]  # Fails

С использованием .data Местоимение более надежно, чем просто явная ссылка на фрейм данных, потому что данные могут быть сгруппированы:

group_by(mtcars, cyl) %>%
  transmute(2L * .data[["am"]])

В этом примере .data[["am"]] представляет собой кусочки am столбец определяется уровнями cyl,

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

other <- 1e10
quo <- new_quosure(quote(other), empty_env())
transmute(mtcars, 2L * !!quo)  # Fails
Другие вопросы по тегам