r - 不在 dplyr tidyeval 中时抛出错误

标签 r dplyr nse tidyeval

我正在使用 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/

相关文章:

r - 如何使用定标将命名向量传递给dplyr::select?

r - 访问带引号的点参数的名称

r - 将日期数据 (m/d/y) 拆分为 3 个单独的列

r - 直接使用dplyr突变数据库表中的变量

r - 使用 geom_text 在 geom_point 中添加过滤后的行名称作为标签(数据集长度错误)

将多列中的所有非 NA 替换为特定字符串

r - 检查 tidyselect 是否为 NULL,如果是,则设置默认的 tidyselect 方法

r - R中有没有一种方法可以根据条件合并行?

r - 比较列表中的元素

c++ - 在 Rcpp 中引发异常