【问题标题】:Using group_by inside a function [duplicate]在函数中使用 group_by [重复]
【发布时间】:2019-11-12 10:50:06
【问题描述】:

我正在尝试使用dplyr 语法编写一个函数,其中包括在函数内部使用 group_by 进行分组。 group_by 语句似乎有问题,我不知道出了什么问题。当我将abc 作为参数传递并在函数内部使用select 时,它会像我预期的那样工作(Gfunc1)。当尝试group_by 相同的参数时,它给了我一个错误;

错误:dims 列未知

请看下面的例子。我真的希望我没有忽略一些令人尴尬的简单事情......无论如何,将不胜感激!

library(dplyr)


abc <- c("a","a","a","b","b","c")
num <- c(1,2,3,4,5,6) 
df <- data.frame(abc,num)


Gfunc1 <- function(dims) {
test1 <- df %>% 
    select(dims)
assign("test1", test1, envir = .GlobalEnv)
}

Gfunc2 <- function(dims) {
test2 <- df %>% 
  group_by(dims)

assign("test2", test2, envir = .GlobalEnv)
}

Gfunc1("abc") 
# Returns as expected; df test1 with only col = "abc"

Gfunc2("abc")
# Does not return what i expect; gives error:  Error: Column `dims` is unknown 

【问题讨论】:

  • 使用`group_by_at(dims)"。

标签: r group-by dplyr user-defined-functions


【解决方案1】:

可以通过使用{{}}(我使用rlang 0.4.1,dplyr 0.8.3)来解决这个问题,如下所示。

问题是在编写依赖于dplyr 的函数时需要做一些额外的工作。这通常通过整洁的评估/非标准评估(NSE)来完成。我添加了df 作为参数,因为我觉得提供数据集作为参数总是比从外部环境调用它更好。 为什么Gfunc1 起作用是因为select 比其他dplyr 函数更健壮:

Gfunc2 <- function(df = NULL,dims) {
  test2 <- df %>% 
    group_by({{dims}})

  assign("test2", test2, envir = .GlobalEnv)
}

对于早期版本的rlangdplyr,同样可以使用sym!! 实现:

Gfunc2 <- function(df = NULL,dims) {
  test2 <- df %>% 
    group_by(!!sym(dims))

  assign("test2", test2, envir = .GlobalEnv)
}
Gfunc2(df,"abc")

注意

  1. 最好将结果存储在列表中,而不是将它们发送到.GlobalEnv

【讨论】:

  • 很好的解决方案。 Mine 介绍了 Rstudio 最近分享的一种新方法
  • 完美运行,谢谢。不知道关于 dplyr i 函数......这两者以及 !!sum() 和 {{}} 都是真正的关键部分,不仅是这个特定问题,而且是整体。列表中的所有这些 PLUS 郊游,而不是将 envir == 更改为服务。非常感谢
【解决方案2】:

您可以通过将点传递给函数来创建函数。这样,您可以使用 NSE 一次分组并选择多个变量。

Gfunc1 <- function(.df, ...) {
  test1 <- .df %>%
    select(...)

  assign("test1", test1, envir = .GlobalEnv)
}

Gfunc2 <- function(.df, ...) {

    test2 <- .df %>%
      group_by(...)

    assign("test2", test2, envir = .GlobalEnv)
  }

 Gfunc1(df, abc)
 Gfunc2(df, abc)

结果

> test1
  abc
1   a
2   a
3   a
4   b
5   b
6   c

test2 %>%
   summarise(sum = sum(num))

  abc     sum
  <fct> <dbl>
1 a         6
2 b         9
3 c         6

要了解有关此的更多信息,请考虑从 RstudioConf 选择和使用 Tidy Eval 的材料 - slides - video

【讨论】:

  • 嗨,Johan,我还没有尝试过您的方法,但下次有机会时会这样做。我相信它完美无缺。非常感谢您的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-04
  • 2017-07-12
  • 2018-11-02
  • 2017-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多