【问题标题】:how to use rlang::as_string() inside of a function?如何在函数内部使用 rlang::as_string()?
【发布时间】:2021-10-07 08:51:10
【问题描述】:

我正在编写一个函数,我提供一个变量名作为符号。在函数的不同步骤中,我想将变量名用作字符串。根据文档,rlang::as_string“将符号转换为字符串。”

这是一个基本示例。这个函数返回一个标题为mean的小标题。

find_mean <- function(varname){
  tibble(mean = mean(pull(mtcars, {{varname}})))
> find_mean(qsec)
# A tibble: 1 × 1
   mean
  <dbl>
1  17.8

我想添加另一列,变量名称为字符串,如下所示:

# A tibble: 1 × 2
   mean variable
  <dbl> <chr>   
1  17.8 qsec   

我认为这会起作用。

find_mean <- function(varname){
  tibble(mean = mean(pull(mtcars, {{varname}})),
         variable = rlang::as_string({{varname}}))
}

但它返回此错误。

> find_mean(qsec)
 Error in ~qsec : object 'qsec' not found 

我知道我在 rlang 的非标准评估规则方面犯了一些基本错误,但谷歌搜索并没有帮助我弄清楚这一点。

【问题讨论】:

    标签: r rlang nse


    【解决方案1】:

    我们可以使用ensym 转换为symbol 然后应用as_string

    find_mean <- function(varname){
      v1 <- rlang::as_string(rlang::ensym(varname))
      tibble(mean = mean(pull(mtcars, {{varname}})),
             variable = v1)
    }
    

    -测试

    find_mean(qsec)
    # A tibble: 1 x 2
       mean variable
      <dbl> <chr>   
    1  17.8 qsec    
    

    这也可以在base R 中完成,即使用deparse/substitute

    > find_mean <- function(varname) deparse(substitute(varname))
     
    > find_mean(qsec)
    [1] "qsec"
    

    【讨论】:

    • ensym - 这就是我所缺少的!这也适用于我更复杂的实际用例。非常感谢@akrun。你已经不是第一次让我感到沮丧了。
    【解决方案2】:

    这也可以用。我们使用enquo 来扩散用户定义的参数,并使用!! bang-bang 运算符来强制评估它。 ensymenquo 之间的区别在于第一个返回原始表达式,而后者返回一个 quosure,这是一个绑定到环境的表达式。因此,为了访问表达式并将其转换为字符串,我们需要使用rlang::get_expr 并将其包装为as_stringpaste

    library(rlang)
    
    find_mean <- function(varname){
      tibble(mean = mean(pull(mtcars, !!enquo(varname))),
             variable = paste(get_expr(enquo(varname))))
    }
    
    # A tibble: 1 x 2
       mean variable
      <dbl> <chr>   
    1  17.8 qsec  
    

    【讨论】:

      猜你喜欢
      • 2019-12-11
      • 2021-07-08
      • 2018-08-18
      • 1970-01-01
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      • 2022-11-19
      相关资源
      最近更新 更多