首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用tidyselect助手初始化变量?

如何使用tidyselect助手初始化变量?
EN

Stack Overflow用户
提问于 2020-03-22 20:26:03
回答 2查看 98关注 0票数 2

我在某些函数中使用tidyselection,我必须将第一个参数与省略号连接起来,因为它可能是一个需要特定处理的特定类。

正常的行为是:

代码语言:javascript
复制
foo = function(x, ...){
    xloc = eval_select(expr(c(x, ...)), data = iris)
    return(xloc)
}
foo(everything())

everything()NULL时,我希望将它作为默认值(由于某种原因,x不能将它直接放在标头中,)。

不幸的是,这种语法是不允许的:

代码语言:javascript
复制
bar = function(x, ...){
    if(is_null(x))
        x=everything() #throws an error
    xloc = eval_select(expr(c(x, ...)), data = iris)
    return(xloc)
}
bar(NULL)
# Error: `everything()` must be used within a *selecting* function.
# i See <https://tidyselect.r-lib.org/reference/faq-selection-context.html>.

我试着用我知道的所有“神秘”函数包装everything()parsedeparsecallsubstitutequosymenquoensym,.什么都没有用(你在这里可以看出,我对这些不太精通)。

使用什么表达式可以替换第二个代码块中的x=everything() 行以使该函数工作?

版本:

  • tidyselect版本1.0.0
  • rlang版本0.4.5
  • dplyr版本0.8.5
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-23 07:52:18

首先,您需要通过x传递{{,否则tidyselect无法检查参数,而且某些特性不能正常工作。然后你可以给它一个默认的everything()

代码语言:javascript
复制
foo <- function(x = everything(), ...) {
  eval_select(expr(c({{ x }}, ...)), data = iris)
}

foo(everything())
#> Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species
#>            1            2            3            4            5

foo()
#> Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species
#>            1            2            3            4            5

如果由于某种原因可以使用默认参数,请手动解除everything(),然后使用!!强制使用

代码语言:javascript
复制
foo <- function(x = NULL, ...) {
  x <- enquo(x)

  if (quo_is_null(x)) {
    x <- expr(everything())
  }

  eval_select(expr(c(!!x, ...)), data = iris)
}
票数 2
EN

Stack Overflow用户

发布于 2020-03-22 20:41:49

我们可以将everything封装在eval_select

代码语言:javascript
复制
bar <- function(x, ...){

    xloc <- tidyselect::eval_select(expr(c(x, ...)), data = iris)
    if(length(xloc) == 0) {
     xloc <- tidyselect::eval_select(expr(everything()), data = iris)
      }
    xloc
}



bar(1:2)
#Sepal.Length  Sepal.Width 
#           1            2 
bar(NULL)
#Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
#           1            2            3            4            5 

或者我们可以在if/else中使用expr条件

代码语言:javascript
复制
bar <- function(x, ...) {

    x1 <-  expr(c(if(is_null(x)) everything() else x, ...))
    tidyselect::eval_select(x1, data = iris)

}

bar(everything())
#Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
#           1            2            3            4            5 
bar(NULL)
#Sepal.Length  Sepal.Width Petal.Length  Petal.Width      Species 
#           1            2            3            4            5 
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60804580

复制
相关文章

相似问题

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