我正在使用 dplyr
并尝试整洁的评估。我对如何检查以确保有人放入裸对象而不是 NSE 的字符串感到困惑。例如,我想过滤非缺失数据:
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
df = data_frame(
myvar = c(rep("yes", 2), NA)
)
myfun <- function(x){
x = enquo(x)
num = df %>%
filter(!is.na( !! x))
return(num)
}
myfun(myvar)
#> # A tibble: 2 x 1
#> myvar
#> <chr>
#> 1 yes
#> 2 yes
如果可能,我希望等效的字符串失败。这当前给出的“错误”结果为
is.na("myvar")
永远是假的。myfun("myvar") # wrong result
#> # A tibble: 3 x 1
#> myvar
#> <chr>
#> 1 yes
#> 2 yes
#> 3 <NA>
看了之后What is the tidyeval way of using dplyr::filter? ,好像是
filter_at
将允许两种情况正常工作:myfun <- function(x){
x = enquo(x)
num = df %>%
filter_at(vars( !! x), all_vars(!is.na(.)))
return(num)
}
myfun(myvar)
#> # A tibble: 2 x 1
#> myvar
#> <chr>
#> 1 yes
#> 2 yes
myfun("myvar") # correct result
#> # A tibble: 2 x 1
#> myvar
#> <chr>
#> 1 yes
#> 2 yes
但是有没有办法让
myfun("myvar")
失败?我不能用 colnames()
除非可能使用 as.name
,否则作为未加引号的表达式的 if 语句会失败。 .
最佳答案
你可以用这样的东西测试字符串文字
myfun <- function(x){
x = enquo(x)
stopifnot(!is.character(rlang::f_rhs(x)))
num = df %>%
filter(!is.na( !! x))
return(num)
}
由于 quosures 与公式非常相似,
rlang::f_rhs
部分提取传入的“事物”,以便您可以检查它是哪种语言元素。也许不是检查字符串,您可能只想确保它是一个符号。你可以这样做myfun <- function(x){
x = enquo(x)
stopifnot(rlang::quo_is_symbol(x))
num = df %>%
filter(!is.na( !! x))
return(num)
}
然后这些做你想做的
myfun(myvar) #works
myfun("myvar") #error
关于r - 不在 dplyr tidyeval 中时抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49562047/