【问题标题】:Getting unquoted variable names from a vector using rlang使用 rlang 从向量中获取不带引号的变量名
【发布时间】:2019-07-26 05:00:09
【问题描述】:

我正在构建一个函数,我希望用户能够为其传递未加引号的变量。稍后在准备输出时,我将需要这些变量的名称作为字符串。

如果每个参数只带有一个变量,这没有问题。我可以使用deparse(substitute(x))rlang::as_name(rlang::enquo(x)) 来获取名称(后者可能是更好的方法)。但是,如果我让他们使用c() 在一个参数中传递多个变量,我该怎么做?

在阅读了一大堆关于 quosures 等的文章后,到目前为止,我想出的唯一方法是 names(dplyr::select(data,{{x}})),但我无法想象这是正确的方法。

nameprinter <- function(x, manynames, onename) {
  manynames <- names(dplyr::select(x, {{manynames}}))
  onename <- rlang::as_name(rlang::enquo(onename))

  c(manynames,onename)
}

df <- data.frame(a=1:10,b=1:10,c=1:10)

nameprinter(df,c(a,b),c)
# [1] "a" "b" "c"

在获取manynames 中传递的变量名称方面,有什么比我这里更好的方法?谢谢。

【问题讨论】:

    标签: r rlang


    【解决方案1】:

    实际上已经有它的功能。我们可以使用vars_select

    tidyselect::vars_select(names(df), c(a,b), c)
    # a   b   c 
    #"a" "b" "c" 
    
    tidyselect::vars_select(names(df), a, b)
    #  a   b 
    # "a" "b" 
    

    【讨论】:

      【解决方案2】:

      您可以使用 base R 来完成此操作:

      nameprinter <- function(x, manynames, onename) {
        manynames <- substitute(manynames)
        names_env <- setNames(as.list(names(x)), names(x))
        manynames_quo <- eval(manynames, names_env)
      
        onename <- deparse(substitute(onename))
      
        c(manynames_quo,onename)
      }
      
      df <- data.frame(a=1:10,b=1:10,c=1:10)
      
      nameprinter(df,c(a,b),c)
      #[1] "a" "b" "c"
      

      这会根据 df 中变量的名称来评估我们的 manynames 向量。这应该比使用select 然后提取名称要快一些。

      【讨论】:

        【解决方案3】:

        我认为您不需要直接使用rlang::enquo 函数来解决这个问题:

        library("dplyr")
        
        nameprinter <- function(x, manynames, onename) {
        
          select(df, !!manynames) %>% print()
          select(df, !!onename) %>% print()
        
          c(manynames, onename)
        }
        
        df <- tibble(a = 1:10, b = 1:10, c = 1:10)
        nameprinter(df, c("a", "b"), "c")
        

        这是你想要的吗?

        【讨论】:

        • 我担心的是,使用select 提取名称似乎很笨拙,必须有一种更简洁的方法,例如as_name 如何处理单个变量。 select() 是这里的最佳实践吗?
        【解决方案4】:

        我选择了一种更通用且不依赖于数据框的方法。它使用as_name 并使用vapply 将其应用于quosures ...

        foo <- function(.data, value_col, ...) {
          group_cols <- enquos(...)
          value_col <- enquo(value_col)
          # do stuff
          .data %>% group_by(!!!group_cols) %>% summarize_at(vars(!!value_col), mean) %>% print()
          # passed columns as a character vector
          vapply(c(group_cols, value_col), rlang::as_name, "")
        }
        foo(mtcars, mpg, cyl, vs)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-02
          • 2022-01-07
          • 2019-08-14
          • 2017-05-21
          • 2022-08-14
          相关资源
          最近更新 更多