【问题标题】:how to use a function with multiple results with groups如何将具有多个结果的函数与组一起使用
【发布时间】:2021-12-11 02:56:20
【问题描述】:

我有一个小问题需要帮助。我定义了一个基于 2 个向量计算多个向量的函数。一般的想法是结果是相互关联的(这就是为什么我只有一个函数),并且计算意味着聚合(结果的元素不仅取决于参数的相同元素,还取决于其他元素)。

我的问题实际上很简单:我想在数据帧上调用我的函数,以便按组计算结果,并将其存储到多个变量中。

基本上,这是我想做的:

myFunction <- function(x, y){
  list(a = x + y,
       b = cumsum(x))
}

data <- data.frame(var1 = c(1,2,4,7,2),
           var2 = c(2,6,2,4,6),
           groups = c("a", "a", "b", "b", "b"))

data %>% group_by(groups) %>% mutate(new1 = myFunction(var1, var2)[[1]],
                                     new2 = myFunction(var1, var2)[[2]])

但是,与示例不同,我只想调用我的函数一次。

有没有人有这样做的想法?非常感谢!

弗朗索瓦

【问题讨论】:

    标签: r list dplyr iteration


    【解决方案1】:

    喜欢这样吗?我们可以稍微改变一下函数,直接调用它作为自己的步骤。

    data <- data.frame(var1 = c(1,2,4,7,2),
                       var2 = c(2,6,2,4,6),
                       groups = c("a", "a", "b", "b", "b"))
    
    myFunction <- function(dt, x, y){
      dt %>%
        mutate(new1 = {{ x }} + {{ y }},
               new2 = cumsum({{ x }}))
    }
    
    data %>%
      group_by(groups) %>%
      myFunction(var1, var2)
    
    # A tibble: 5 x 5
    # Groups:   groups [2]
       var1  var2 groups  new1  new2
      <dbl> <dbl> <chr>  <dbl> <dbl>
    1     1     2 a          3     1
    2     2     6 a          8     3
    3     4     2 b          6     4
    4     7     4 b         11    11
    5     2     6 b          8    13
    

    解释> rlang 的{{ }} 是一种在单个插值步骤中引用和取消引用的方法。其目的是延迟评估,即处理管道的非标准评估,函数的变量到需要的时候。

    【讨论】:

    • 这是一个非常好的开始,非常感谢!这里唯一的问题是我需要知道数据中新变量的名称。因此,Allan 的解决方案更适合我的需求。
    【解决方案2】:

    如果您将myFunction 的输出转换为数据框,它只会在mutate 内自动工作:

    data %>% 
       group_by(groups) %>% 
       mutate(as.data.frame(myFunction(var1, var2)))
    
    #> # A tibble: 5 x 5
    #> # Groups:   groups [2]
    #>    var1  var2 groups     a     b
    #>   <dbl> <dbl> <chr>  <dbl> <dbl>
    #> 1     1     2 a          3     1
    #> 2     2     6 a          8     3
    #> 3     4     2 b          6     4
    #> 4     7     4 b         11    11
    #> 5     2     6 b          8    13
    

    显然,您可以在函数内部执行此操作以使 mutate 调用看起来更好,或者像我的示例中那样在 mutate 调用内部执行此操作,具体取决于您的函数返回列表而不是数据框。

    【讨论】:

    • 看起来很完美,谢谢!
    猜你喜欢
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多