【问题标题】:How to programmatically filter columns in dplyr?如何以编程方式过滤 dplyr 中的列?
【发布时间】:2017-08-11 01:53:22
【问题描述】:

如果我不想在函数被调用之前指定列,我将如何创建一个删除列中 NA 值的函数?

minimal_case <- function(column_name = "a") {
  enquo_name <- enquo(column_name)

  example <- tibble(a = c(NA, 1))

  print(filter(example, !is.na(a)))

  print(filter(example, !is.na(rlang::UQ(enquo_name))))

}

第一个打印语句的输出是:

# A tibble: 1 x 1
      a
  <dbl>
1     1

第二个打印语句的输出是:

# A tibble: 2 x 1
      a
  <dbl>
1    NA
2     1

如何让第二个打印语句与第一个匹配?

【问题讨论】:

  • function(df, x) df[!is.na(df[[x]]), ]
  • 如果您提供一个字符串作为列名,那么您使用的是标准评估,可以跳过整个 tidyeval 业务。

标签: r dplyr rlang tidyeval


【解决方案1】:

column_name 参数似乎是一个字符串。在这种情况下,您可以使用rlang::sym

minimal_case <- function(column_name = "a") {
    example <- tibble(a = c(NA, 1))

    print(filter(example, !is.na(a)))

    print(filter(example, !is.na(!!rlang::sym(column_name))))

}

【讨论】:

  • 参考rlang很有帮助;我已经看到了 dplyr 的 quosure 内容,但 rlang::sym 看起来像是一种转换使用旧样式的函数的简单方法,例如mutate_ 调用 quosures。
  • dplyr 也将很快导出sym()sym() 和quosures 的功能是互补的。
【解决方案2】:

这里有一篇关于如何在 dplyr 中执行此类操作的文章:http://dplyr.tidyverse.org/articles/programming.html

这种情况的妙语是您不必在参数中引用a。你也可以用!!代替UQ

minimal_case <- function(column_name = a) {
    enquo_name <- enquo(column_name)

    example <- tibble(a = c(NA, 1))

    print(filter(example, !is.na(a)))

    print(filter(example, !is.na(!!enquo_name)))

}

【讨论】:

  • 我不会称该变量为column_name,因为“列名”让我想到了字符串,例如colnames() 的输出。同样在您的版本中,它不一定是列符号,也可能是表达式。
猜你喜欢
  • 2021-06-05
  • 1970-01-01
  • 2018-12-04
  • 1970-01-01
  • 2011-08-13
  • 2017-12-21
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
相关资源
最近更新 更多