【问题标题】:concatenate quosures and string连接quosures和字符串
【发布时间】:2017-09-13 20:54:10
【问题描述】:

我正在寻找一种连接 quosure 和结果为 quosure 的字符串的方法。实际上,如果我使用paste0()quo_name(),我可以做到。但我想知道是否有更优雅的替代方法可以在我的包中编写函数。这是一个通用示例:

library(dplyr)

df <- data_frame(
  z_1 = 1,
  z_2 = 2,
  y_1 = 10,
  y_2 = 20
)

get_var <- function(.data, var) {
  xx = enquo(var)

  select(.data, paste0(quo_name(xx), "_1"), paste0(quo_name(xx), "_2"))
}

get_var(df, z)
# A tibble: 1 x 2
    z_1   z_2
  <dbl> <dbl>
1     1     2

【问题讨论】:

    标签: r dplyr rlang tidyeval


    【解决方案1】:

    如果没有函数,这就是使用dplyr 的方法:

    library(dplyr)
    df %>%
      select(starts_with("z_"))
    

    您还可以创建一个函数并为变量名传递一个字符串,如下所示:

    get_var= function(df, var){
      df %>%
        select(starts_with(paste0(var, "_")))
    }
    
    get_var(df, "z")
    

    现在,当您尝试传入变量名而不将其引用到函数中时,棘手的部分就来了(R 代码,而不是它包含的值)。一种方法是在 Base R 中使用 deparse + substitute。这会将提供给 varsymbol 转换为字符串,以便以后在函数中使用:

    get_var = function(df, var){
      var_quo = deparse(substitute(var))
      df %>%
        select(starts_with(paste0(var_quo, "_")))
    }
    

    最后,这里是如何对enquoquo_namerlang/tidyverse 包中执行相同操作:

    library(rlang)
    get_var = function(df, var){
      var_quo = quo_name(enquo(var))
      df %>%
        select(starts_with(paste0(var_quo, "_")))
    }
    
    get_var(df, z)
    get_var(df, y)
    

    结果:

    # A tibble: 1 x 2
        z_1   z_2
      <dbl> <dbl>
    1     1     2
    
    # A tibble: 1 × 2
        y_1   y_2
      <dbl> <dbl>
    1    10    20
    

    注意事项:

    1. quosures 是跟踪环境的引用表达式。
    2. enquo 采用引用函数参数的符号,引用 R 代码并将其与函数的环境捆绑在一起。
    3. quo_name 将 quosure 格式化为字符串,稍后可以在函数中使用。
    4. quo_textquo_name 类似,但不检查输入是否为符号。

    检查这些:

    1. rlang documentation
    2. Non-Standard Evaluation in R
    3. ?enquo
    4. ?quo_name

    【讨论】:

    • 如果您可以将变量名称传递给您的选择,我会投票。 starts_with 是我会使用的方法
    • @CPark 我明白了。所以你希望能够传递变量本身而不是像"z" 这样的字符串?例如,get_var(df, "z") 不会令人满意?
    • 顺便说一句,我不是 OP。基本上 OP 想要定义一个函数,其中数据框和要选择的列作为参数动态传递。
    • @CPak 我的错。这看起来更像 OP 想要的吗?
    猜你喜欢
    • 2023-04-06
    • 2013-12-29
    • 2023-03-27
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多