如何将匿名函数传递给 dplyr summarise

Mic*_*iak 5 r anonymous-function dplyr

我有一个简单的数据框,包含 3 列:namegoalactual。因为这是更大数据帧的简化,所以我想使用 dplyr 来计算每个人实现目标的次数。

df <- data.frame(name = c(rep('Fred', 3), rep('Sally', 4)),
                 goal = c(4,6,5,7,3,8,5), actual=c(4,5,5,3,3,6,4))
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

结果应该是这样的:

在此输入图像描述

我应该能够传递类似于下面所示的匿名函数,但语法不太正确:

library(dplyr)
g <- group_by(df, name)
summ <- summarise(g, met_goal = sum((function(x,y) {
                                       if(x>y){return(0)}
                                       else{return(1)}
                                     })(goal, actual)
                                    )
                  )
Run Code Online (Sandbox Code Playgroud)

当我运行上面的代码时,我看到以下 3 个错误:

警告消息: 1:在 if (x == y) { 中:条件长度 > 1 并且仅使用第一个元素

Ric*_*ven 4

goal和中的向量长度相等actual,因此关系运算符适合在这里使用。然而,当我们在简单的语句中使用它们时,if()我们可能会得到意想不到的结果,因为if()需要长度为 1 的向量。由于我们有相等长度的向量并且需要二进制结果,因此采用逻辑向量之和是最好的方法,如下所示。

group_by(df, name) %>%
    summarise(met_goal = sum(goal <= actual))
# A tibble: 2 x 2
    name met_goal
  <fctr>    <int>
1   Fred        2
2  Sally        1
Run Code Online (Sandbox Code Playgroud)

运营商切换到<=因为你想要0goal > actual否则1

请注意,您可以使用匿名函数。正是这if()句话让你失望了。例如,使用

sum((function(x, y) x <= y)(goal, actual)) 
Run Code Online (Sandbox Code Playgroud)

会按照你所询问的方式工作。