【问题标题】:How can I pass a column name to a is.na function via dot-dot-dot?如何通过 dot-dot-dot 将列名传递给 is.na 函数?
【发布时间】:2021-08-23 22:35:05
【问题描述】:

我正在尝试编写一个函数,该函数将数据框的列名作为... 参数并在dplyr::mutate 函数调用中将其传递给is.na。以下玩具示例说明了基本目标:

library(tidyverse)

df <- tribble(
  ~id, ~value,
  "a",  1,
  "a",  2,
  NA,   3,
  "b",  4
)

df %>%
  group_by(id) %>%
  mutate(avg = if_else(is.na(id), NA_real_, mean(value)))

以上产生了预期的结果,但不是通过函数。

以下函数有效,但不会根据需要使用 NA 填充 avg 列:

my_fun1 <- function(.data, ...) {
  .data %>%
    group_by(...) %>%
    mutate(avg = mean(value))
}

my_fun1(df, id)

以下函数产生一个错误,指示“is.na() 应用于'closure'类型的非(列表或向量)”:

my_fun2 <- function(.data, ...) {
  .data %>%
    group_by(...) %>%
    mutate(avg = if_else(is.na(...), NA_real_, mean(value)))
}

my_fun2(df, id)

为什么会出现此错误,如何避免?

【问题讨论】:

  • 如果您在分组中传递多于一列,那么if_else 是如何工作的
  • 当你使用...时,用户可以输入id1id2等。假设,如果有多个输入,is.na(...)会假设这样做在多列上,它将是一个矩阵
  • 我明白了。有没有办法使用... 让用户只能输入一列?如果是这样,那能解决问题吗?
  • 一般...用于多列输入或假设我们不知道OP有多少组。如果你有一个固定的。为什么不创建一个正式的论点,即function(.data, grpcol)
  • 您可以查看发布的解决方案,因为它更直接

标签: r dplyr


【解决方案1】:

如果我们有一个固定的列,那么传递不带引号的参数很容易,即使用 curly-curly 运算符

myfun <- function(.data, grpcol) {
   .data %>%
          group_by({{grpcol}}) %>%
          mutate(avg = if_else(is.na({{grpcol}}), NA_real_, 
            mean(value, na.rm = TRUE))) %>%
          ungroup
}

-测试

> myfun(df, id)
# A tibble: 4 x 3
  id    value   avg
  <chr> <dbl> <dbl>
1 a         1   1.5
2 a         2   1.5
3 <NA>      3  NA  
4 b         4   4  

或者如果我们想使用...,并且如果用户输入多个列名,请始终选择第一个

myfun <- function(.data, ...) {

grps <- rlang::ensyms(...)[[1]]

.data %>%
   group_by(!! grps) %>%
   mutate(avg = if_else(is.na(!!grps), NA_real_, 
               mean(value, na.rm = TRUE))) %>%
             ungroup


}
myfun(df, id)
# A tibble: 4 x 3
  id    value   avg
  <chr> <dbl> <dbl>
1 a         1   1.5
2 a         2   1.5
3 <NA>      3  NA  
4 b         4   4  

【讨论】:

    猜你喜欢
    • 2011-10-25
    • 1970-01-01
    • 2013-01-20
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    相关资源
    最近更新 更多