我正在使用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")失败呢?除非使用as.name,否则我不能使用colnames()和if语句作为未加引号的表达式。
发布于 2018-03-30 02:48:06
您可以使用如下代码测试字符串文字
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部件提取传入的"thing“,以便您可以检查它是哪种语言元素。也许不需要检查字符串,您可能只想确保它是一个符号。您可以使用以下命令完成此操作
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发布于 2018-03-30 01:51:21
在取消引用x之前,您可以在函数中测试它。如果您将x作为一个带引号的字符串传入,那么它的长度为1,函数将返回NA或您想要的任何失败条件。如果(正确地)传入未加引号的变量名,则length将失败(并显示Error: object 'knockdown' not found),但错误将被try()消除,函数将照常运行。
myfun <- function(x){
try({if (length(x) == 1) return(NA)}, silent = TRUE)
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")
[1] NAhttps://stackoverflow.com/questions/49562047
复制相似问题