当前位置: 首页 > 知识库问答 >
问题:

使用dplyr对多列进行不同操作的汇总

董琦
2023-03-14

我知道已经有很多相关的问题了,但是没有一个回答了我的特殊需求。

我想在一个有50列的表上使用dplyr“summary”,我需要对这些列应用不同的摘要函数。

“SUMMARE_all”和“SUMMARY_at”似乎都有缺点,即不可能将不同的函数应用于变量的不同子组。

例如,让我们假设iris数据集有50列,所以我们不想按名称寻址列。我需要前两列的总和、第三列的平均值以及所有剩余列的第一个值(在group_by(Species)之后)。我怎么能这样做?

共有3个答案

虞航
2023-03-14

您可以使用每个函数分别汇总数据,然后根据需要稍后联接数据。

因此,对于虹膜示例,如下所示:

sums <- iris %>% group_by(Species) %>% summarise_at(1:2, sum)
means <- iris %>% group_by(Species) %>% summarise_at(3, mean)
firsts <- iris %>% group_by(Species) %>% summarise_at(4, first)
full_join(sums, means) %>% full_join(firsts)

不过,如果您需要使用的总结函数不止一个,我会尝试想出其他方法。

葛修筠
2023-03-14

正如其他人所提到的,这通常是通过调用<code>summary_each/<code>sumary_at/<code>summy_if

对于您提到的示例,您可以尝试以下操作:

summarizer <- function(tb, colsone, colstwo, colsthree, 
                       funsone, funstwo, funsthree, group_name) {

return(bind_cols(
    summarize_all(select(tb, colsone), .funs = funsone),
    summarize_all(select(tb, colstwo), .funs = funstwo) %>% 
      ungroup() %>% select(-matches(group_name)),
    summarize_all(select(tb, colsthree), .funs = funsthree) %>% 
      ungroup() %>% select(-matches(group_name)) 
))

}

#With colnames
iris %>% as.tibble() %>% 
  group_by(Species) %>% 
  summarizer(colsone = contains("Sepal"), 
         colstwo = matches("Petal.Length"), 
         colsthree = c(-contains("Sepal"), -matches("Petal.Length")),
         funsone = "sum", 
         funstwo = "mean",
         funsthree = "first",
         group_name = "Species")

#With indexes
iris %>% as.tibble() %>% 
 group_by(Species) %>% 
 summarizer(colsone = 1:2, 
         colstwo = 3, 
         colsthree = 4,
         funsone = "sum", 
         funstwo = "mean",
         funsthree = "first",
         group_name = "Species")
孙海
2023-03-14

幸运的是,现在有一种更简单的方法。随着新的dplyr 1.0.0即将推出,您可以利用< code > cross 函数来实现这一目的。

你只需要输入:

iris %>% 
  group_by(Species) %>% 
  summarize(
    # I want the sum over the first two columns, 
    across(c(1,2), sum),
    #  the mean over the third 
    across(3, mean),
    # the first value for all remaining columns (after a group_by(Species))
    across(-c(1:3), first)
  )

太好了,不是吗?我最初认为跨是不必要的,因为作用域变体工作得很好,但这个用例正是函数非常有益的原因。

您可以通过devtools::install_github(“tidyverse/dplyr”)获取最新版本的dplyr

 类似资料:
  • 我试图计算许多列的行平均值。有人能解释一下为什么下面的代码只计算代码中两个变量(var_1和var_13)的平均值,而不是所有13列的平均值吗?

  • 我正在尝试使用创建一个新列,该列的值基于特定的列。 最后一个数据帧示例(我正在尝试创建): 这个问题基本上与此相反:dplyr-mutate:使用动态变量名。我不能使解决方案适应我的问题。

  • 我有一个spark数据帧,如: 以 如何构造一个在列上运行的UDF,即由火花创建的包装数组,以计算变量平均值?

  • 根据对条件dplyr评估的讨论,我想根据传递的数据帧中是否存在参考列,有条件地在管道中执行一个步骤。 和生成的结果应该是相同的。 对于可用列,传递的对象与初始数据帧不对应。原始代码返回错误消息: :未找到对象 我尝试过其他语法(运气不佳): 我想扩展这个问题,以解释调用中右侧的评估。例如,下面的语法试图过滤第一个可用值。mtcars% 预期的是,调用的结果是错误消息: 中出错:结果的长度必须为32

  • 我已经更新了dplyr(现在是0.7.1),我的很多旧代码都不能用了,因为mutate_each已经被弃用了。我曾经用mutate_each做类似这样的事情(代码如下),使用列索引。我会在数百个专栏中这样做。而我就是搞不清楚如何用mutate_at正确使用vars参数。我看到的所有例子都使用了列名...我不想这么做。我确信这是一个简单的答案,但是我已经花了太多的时间试图弄明白它,并且将非常感谢一些

  • 是否有一种内置方法可以将两个不同的聚合函数应用于同一列,而无需多次调用? 示例数据帧: 语法上错误,但直觉上正确的做法是: 显然,Python不允许重复的键。是否有其他方式来表达输入到?也许元组列表会更好地工作,以允许多个函数应用于同一列?但是似乎只接受字典。 除了定义一个只应用其中两个函数的辅助函数之外,还有其他解决方法吗?无论如何,这将如何与聚合工作?)