Программирование dplyr: неожиданное поведение фильтра
Я пытаюсь использовать dplyr для программирования: поведение фильтра с кавычками не понятно.
После нескольких попыток анализа реальных данных я создал следующие фиктивные данные.
dt <- data.frame(
sex = rep(c("F","M"), 50),
height = runif(100, 1, 1000),
weight = rep(c(2, 100), 50),
value = runif(100, 1, 1000 ),
stringsAsFactors = FALSE
)
library(dplyr)
wizard_fun_1 <- function(param1){
par1 <- enquo(param1)
dt %>% select(height, !!par1)
}
wizard_fun_1("sex")
# as expected
#1 74.875344 F
#2 846.614856 M
#.....
wizard_fun_2 <- function(param1){
par1 <- enquo(param1)
dt %>% select(height, !!par1) %>%
filter( (!!par1) == 'M')
}
wizard_fun_2('sex')
#[1] height sex
# ... zero rows....
Что не так? Спасибо заранее за любые идеи!
2 ответа
В функции, которую вы используете enquo
, но затем, когда вы вызываете функцию, вы передаете имя столбца в виде строки, а не голое имя. Вам просто нужно использовать пустое имя столбца при вызове функции, и она работает как написано.
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
dt <- tibble(
sex = rep(c("F","M"), 50),
height = runif(100, 1, 1000),
weight = rep(c(2, 100), 50),
value = runif(100, 1, 1000 )
)
wizard_fun_2 <- function(param1){
par1 <- enquo(param1)
dt %>% select(height, !!par1) %>%
filter( (!!par1) == "M")
}
wizard_fun_2(sex)
#> # A tibble: 50 x 2
#> height sex
#> <dbl> <chr>
#> 1 871.7788 M
#> 2 467.9220 M
#> 3 272.6478 M
#> 4 445.1101 M
#> 5 682.2095 M
#> 6 831.8522 M
#> 7 727.9525 M
#> 8 203.7829 M
#> 9 742.3000 M
#> 10 322.0473 M
#> # ... with 40 more rows
Если вы используете enquo
Вы должны вызывать свою функцию без кавычек. Например
wizard_fun_2(sex)
будет работать просто отлично. select
Функция может принимать строки или символы. То есть оба они будут работать
select(dt, sex) # more common
select(dt, "sex")
Но это не то же самое для filter()
filter(sex=="M")
filter("sex"=="M")
Поэтому будьте осторожны при переходе между строками и символами / именами без кавычек. Когда вы используете цитаты, вы вообще не используете нестандартную оценку.