Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将匿名函数传递给dplyr摘要_R_Dplyr_Anonymous Function - Fatal编程技术网

如何将匿名函数传递给dplyr摘要

如何将匿名函数传递给dplyr摘要,r,dplyr,anonymous-function,R,Dplyr,Anonymous Function,我有一个包含3列的简单数据框:名称、目标、和实际。 因为这是对更大数据帧的简化,所以我想使用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)) df解决方案使用: 您要求使用dplyr解决方案,但由于实际数据要大得多,您可以使用data.tablefo

我有一个包含3列的简单数据框:名称目标、和实际。 因为这是对更大数据帧的简化,所以我想使用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))
df解决方案使用:

您要求使用
dplyr
解决方案,但由于实际数据要大得多,您可以使用
data.table
foo
是您要应用的函数

foo <- function(x, y) {
    res <- 0
    if (x <= y) {
        res <- 1
    }
    return(res)
}

library(data.table)
setDT(df)
setkey(df, name)[, foo(goal, actual), .(name, 1:nrow(df))][, sum(V1), name]

我们在
目标
实际
中有相等长度的向量,因此关系运算符适合在这里使用。然而,当我们在一个简单的
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

将以您询问的方式工作。

发现自己需要再次执行类似的操作(一年后),但功能比原始问题中提供的简单功能更复杂。最初被接受的答案利用了问题的一个特定特征,但涉及了更一般的方法。使用这种方法,我最终得到的答案是这样的:

library(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))

my_func = function(act, goa) {
  if(act < goa) {
    return(0)
  } else {
    return(1)
  }
}

g <- group_by(df, name)
summ = df %>% group_by(name) %>%
  summarise(met_goal = sum(mapply(my_func, .data$actual, .data$goal)))

> summ
# A tibble: 2 x 2
  name  met_goal
  <fct>    <dbl>
1 Fred         2
2 Sally        1
g <- group_by(df, name)
summ = df %>% group_by(name) %>%
  summarise(met_goal = sum(mapply(function(act, go) {
                                    if(act < go) {
                                      return(0)
                                    } else {
                                      return(1)
                                    }
                                  }, .data$actual, .data$goal)))
库(dplyr)
df%
总结(满足目标=总和(映射(my_func、.data$actual、.data$goal)))
>总和
#一个tibble:2x2
名字达到了你的目标
1弗雷德2
莎莉1
最初的问题是指使用匿名函数。本着这种精神,最后一部分是这样的:

library(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))

my_func = function(act, goa) {
  if(act < goa) {
    return(0)
  } else {
    return(1)
  }
}

g <- group_by(df, name)
summ = df %>% group_by(name) %>%
  summarise(met_goal = sum(mapply(my_func, .data$actual, .data$goal)))

> summ
# A tibble: 2 x 2
  name  met_goal
  <fct>    <dbl>
1 Fred         2
2 Sally        1
g <- group_by(df, name)
summ = df %>% group_by(name) %>%
  summarise(met_goal = sum(mapply(function(act, go) {
                                    if(act < go) {
                                      return(0)
                                    } else {
                                      return(1)
                                    }
                                  }, .data$actual, .data$goal)))
g%groupby(name)%>%
总结(达成目标=总结(功能(行动、行动){
如果(行动
这很好地回答了这个问题。我确实故意使我的尝试过于复杂,因为我想看看如何使用更复杂/通用的匿名函数。@MichaelSzczepaniak-注意,您可以使用匿名函数。是
if()
语句让您感到不舒服。例如,
sum((函数(x,y)x)正是我想要的。谢谢你(两次;-)解释了这一点。我对数据表没有太多的研究,但我知道它们的好处,所以我相信我将来会使用类似的东西。
g <- group_by(df, name)
summ = df %>% group_by(name) %>%
  summarise(met_goal = sum(mapply(function(act, go) {
                                    if(act < go) {
                                      return(0)
                                    } else {
                                      return(1)
                                    }
                                  }, .data$actual, .data$goal)))