首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不在dplyr tidyeval中时抛出错误

不在dplyr tidyeval中时抛出错误
EN

Stack Overflow用户
提问于 2018-03-30 01:32:44
回答 2查看 95关注 0票数 4

我正在使用dplyr并尝试进行整洁的评估。我对如何检查以确保有人为NSE放入了一个空对象而不是一个字符串感到困惑。例如,我想对非缺失数据进行过滤:

代码语言:javascript
复制
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")永远不会是假的。

代码语言:javascript
复制
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似乎允许这两种情况都能很好地工作:

代码语言:javascript
复制
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语句作为未加引号的表达式。

EN

回答 2

Stack Overflow用户

发布于 2018-03-30 02:48:06

您可以使用如下代码测试字符串文字

代码语言:javascript
复制
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“,以便您可以检查它是哪种语言元素。也许不需要检查字符串,您可能只想确保它是一个符号。您可以使用以下命令完成此操作

代码语言:javascript
复制
myfun <- function(x){
  x = enquo(x)
  stopifnot(rlang::quo_is_symbol(x))
  num = df %>%
    filter(!is.na( !! x)) 
  return(num)
}

然后这些可以做你想做的事

代码语言:javascript
复制
myfun(myvar) #works
myfun("myvar") #error
票数 3
EN

Stack Overflow用户

发布于 2018-03-30 01:51:21

在取消引用x之前,您可以在函数中测试它。如果您将x作为一个带引号的字符串传入,那么它的长度为1,函数将返回NA或您想要的任何失败条件。如果(正确地)传入未加引号的变量名,则length将失败(并显示Error: object 'knockdown' not found),但错误将被try()消除,函数将照常运行。

代码语言:javascript
复制
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] NA
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49562047

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档