【问题标题】:How to quickly create multiple summary tables with group_by() / summarise()?如何使用 group_by() / summarise() 快速创建多个汇总表?
【发布时间】:2018-08-13 22:38:01
【问题描述】:

我有一个包含 N 个变量、M 个分类和 2 个数字的数据框。我想创建 M 个数据框,每个类别变量一个。

例如,

data %>%
group_by(var1) %>%
summarise(sumVar5 = sum(var5),
meanVar6 = mean(var6))

data %>%
group_by(varM) %>%
summarise(sumVar5 = sum(var5),
meanVar6 = mean(var6))

等等……

有没有办法遍历分类变量并生成每个汇总表?也就是说,不需要将上述块重复 M 次。

或者,这些汇总表不必是单独的对象,只要我可以轻松引用/提取每个 M 变量的汇总即可。

【问题讨论】:

标签: r dplyr


【解决方案1】:

这是一个解决方案(我希望如此)。使用您拥有的公式创建数据框列表:

library(tidyverse)

# Create sample data frame
data <- data.frame(var1 = sample(1:2, 5, replace = T),
                   var2 = sample(1:2, 5, replace = T),
                   var3 = sample(1:2, 5, replace = T),
                   varM = sample(1:2, 5, replace = T),
                   var5 = rnorm(5, 3, 6),
                   var6 = rnorm(5, 3, 6))

# Vars to be grouped (var1 until varM in this example)
vars_to_be_used <- names(select(data, var1:varM))

# Function to be used
group_fun <- function(x, .df = data) {
  .df %>%
      group_by_(.x) %>%
      summarise(sumVar5  = sum(var5),
                meanVar6 = mean(var6))
  }

# Loop over vars
results <- map(vars_to_be_used, group_fun)

# Nice list names
names(results) <- vars_to_be_used

print(results)

【讨论】:

    【解决方案2】:

    您没有提供示例 data.set,因此我创建了一个小示例来展示它的工作原理。

    data <- data_frame(var1 = rep(letters[1:5], 2),
                       var2 = rep(LETTERS[11:15], 2),
                       var3 = 1:10,
                       var4 = 11:20)
    

    tidyverse 软件包的组合可以让您到达需要的地方。 使用的步骤:首先,我们将要分组的所有列收集在 cols 列中,并将数字变量分开。接下来,我们将 data.frame 拆分为 data.frames 列表,以便我们要分组的每一列都有自己的表,其中包含 2 个数字变量。现在所有内容都在列表中,我们需要使用 purrr 包中的 map 功能。使用 map,我们再次传播 data.frame,以便列名与我们预期的一样。最后使用 map 我们使用group_by_if 对字符列进行分组并总结其余部分。所有结果都存储在一个列表中,您可以在其中访问您需要的内容。

    分段运行代码以查看每个步骤的作用。

    library(dplyr)
    library(purrr)
    library(tidyr)
    
    outcomes <- data %>% 
      gather(cols, value, -c(var3, var4)) %>% 
      split(.$cols) %>%
      map(~ spread(.x, cols, value)) %>% 
      map(~ group_by_if(.x, is.character) %>% 
            summarise(sumvar3 = sum(var3),
                      meanvar4 = mean(var4)))
    
    outcomes
    
    $`var1`
    # A tibble: 5 x 3
      var1  sumvar3 meanvar4
      <chr>   <int>    <dbl>
    1 a           7     13.5
    2 b           9     14.5
    3 c          11     15.5
    4 d          13     16.5
    5 e          15     17.5
    
    $var2
    # A tibble: 5 x 3
      var2  sumvar3 meanvar4
      <chr>   <int>    <dbl>
    1 K           7     13.5
    2 L           9     14.5
    3 M          11     15.5
    4 N          13     16.5
    5 O          15     17.5
    

    【讨论】:

    • 我尝试了这个解决方案,但我在 L4 中遇到了这个错误:Error: Duplicate identifiers for rows. 也许我没有正确替换某些东西——.x 应该是另一个值吗?
    • @Khashir,在这种情况下,您需要在问题中提供数据的(部分)输入。当传播的数据在 vars 中有重复的值组合时会出现此错误。
    • 明白了。我将不得不更仔细地查看数据以了解为什么会出现此错误 - 我不明白为什么会有重复。我猜这些出现在中间步骤中?无论如何,我更喜欢这个答案,因为它不需要编写函数(并且更简洁/更简洁),但另一个不管重复都可以工作。我猜没有简单的方法可以绕过传播限制?
    猜你喜欢
    • 2011-12-05
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 2022-01-14
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    相关资源
    最近更新 更多