У меня есть небольшая загадка.Программирование с помощью dplyr может быть головной болью по сравнению с обычным подходом к строкам, но предоставляет намного больше возможностей для функциональности.Вот загадка / несоответствие, с которым я столкнулся, и я не уверен, почему это так.Единственный соответствующий ответ, который я смог найти, был этот , но не уверен, что это весь рассказ.
Рассмотрим следующие функции:
library(tidyverse)
#functions
pull_func = function(x, var) {
x %>% pull(!!var)
}
select_func = function(x, var) {
x %>% select(!!var)
}
filter_func = function(x, var, set) {
x %>% filter(!!var %in% set)
}
filter_func2 = function(x, var, set) {
x %>% filter((!!var) %in% set)
}
filter_func3 = function(x, var, set) {
var = enquo(var)
x %>% filter((!!var) %in% set)
}
filter_func4 = function(x, var, set) {
var = sym(var)
x %>% filter((!!var) %in% set)
}
Давайте попробуем аналогичные действиядля набора данных iris:
> iris %>% pull_func("Species") %>% head()
[1] setosa setosa setosa setosa setosa setosa
Levels: setosa versicolor virginica
> iris %>% select_func("Species") %>% head()
Species
1 setosa
2 setosa
3 setosa
4 setosa
5 setosa
6 setosa
> iris %>% filter_func("Species", set = "virginica") %>% head()
[1] Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<0 rows> (or 0-length row.names)
> iris %>% filter_func2("Species", set = "virginica") %>% head()
[1] Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<0 rows> (or 0-length row.names)
> iris %>% filter_func3("Species", set = "virginica") %>% head()
[1] Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<0 rows> (or 0-length row.names)
> iris %>% filter_func4("Species", set = "virginica") %>% head()
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 6.3 3.3 6.0 2.5 virginica
2 5.8 2.7 5.1 1.9 virginica
3 7.1 3.0 5.9 2.1 virginica
4 6.3 2.9 5.6 1.8 virginica
5 6.5 3.0 5.8 2.2 virginica
6 7.6 3.0 6.6 2.1 virginica
Итак, pull()
и select()
работают, но filter()
- нет, если только сначала не используется вызов sym()
.Это почему?Это заняло у меня много времени, поскольку я часто использую более простые функции, чтобы проверить свое мышление, прежде чем пытаться вызвать filter()
, или попробовать более простые, когда filter()
не дает ожидаемых результатов / возвращает ошибку.Я думаю, что это обычная тактика тестирования.