【问题标题】:Using dplyr to create summary proportion table with several categorical/factor variables使用 dplyr 创建包含多个分类/因子变量的汇总比例表
【发布时间】:2016-04-07 20:08:45
【问题描述】:

我正在尝试创建一个表格,通过另一个变量汇总几个分类变量(使用频率和比例)。我想使用 dplyr 包来做到这一点。

这些以前的 Stack Overflow 讨论部分包含了我正在寻找的内容: Relative frequencies / proportions with dplyrCalculate relative frequency for a certain group

使用 mtcars 数据集,如果我只想查看 gearam 类别的比例,这就是输出的样子:

    mtcars %>%
    group_by(am, gear) %>%
    summarise (n = n()) %>%
    mutate(freq = n / sum(n))

    #   am gear  n      freq
    # 1  0    3 15 0.7894737
    # 2  0    4  4 0.2105263
    # 3  1    4  8 0.6153846
    # 4  1    5  5 0.3846154

但是,我实际上不仅想查看amgears,还希望在同一张表中分别查看amcarbamcyl。如果我将代码修改为:

    mtcars %>%
    group_by (am, gear, carb, cyl) %>%
    summarise (n = n()) %>%
    mutate(freq = n / sum(n))

我得到amgearcarbcyl 的每个组合的频率。这不是我想要的。有没有办法用 dplyr 做到这一点?

编辑

此外,如果有人知道生成我想要的表格的方法,但将am 的类别作为列(如经典的 2x2 表格格式),那将是一个额外的好处。这是我所指的一个例子。它来自我以前的出版物之一。我想在 R 中生成这个表格,这样我就可以使用 RMarkdown 将它直接输出到 Word 文档中:

【问题讨论】:

  • 是否有理由必须在 dplyr 中完成?并且“组”之一总是相同的吗? (这里是am
  • 你能举一个你想要的表格的例子吗?进行一些重塑当然是可能的,但我不确定你在追求什么。
  • 没有非常重要的原因必须在 dplyr 中完成,除了我正在努力学习该软件包,以便我有一个一致的方法可用于生成我的表格。 dplyr 的另一个驱动原因是它生成一个数据框作为输出,这使我可以使用 stargazer 包来生成值得发表的表格,然后我可以使用 RMarkdown 将其输出到 Word 文档。当然,我对其他人认为更适合这样做的替代方法持开放态度。
  • 我也有类似的问题。 @RNB 你最后是怎么建表的?

标签: r dplyr


【解决方案1】:

分组依据然后汇总的替代方法是使用 count()。

这只是让代码1行更简洁

library(reshape2)
library(dplyr)

m_mtcars <- melt(mtcars,measure.vars=c("gear","carb","cyl"))

res <- m_mtcars %>%
  count(am, variable, value) %>%
  mutate(freq = n / sum(n))

另一个好处是,这将保存 group_by 汇总中丢失的其他值。结果表如下所示

enter image description here

【讨论】:

    【解决方案2】:

    解决此问题的一种方法是将您的数据转换为较长的格式。然后,您可以使用相同的代码来计算您想要的结果,并增加一个 group_by:

    library(reshape2)
    library(dplyr)
    
    m_mtcars <- melt(mtcars,measure.vars=c("gear","carb","cyl"))
    
    res <- m_mtcars %>%
      group_by(am, variable, value) %>%
      summarise (n = n()) %>%
      mutate(freq = n / sum(n))
    

    在此基础上,可以使用更多的整形和一些字符串格式化来获得所需的输出

    #make an 'export' variable
    res$export <- with(res, sprintf("%i (%.1f%%)", n, freq*100))
    
    #reshape again
    output <- dcast(variable+value~am, value.var="export", data=res, fill="missing") #use drop=F to prevent silent missings 
    #'silent missings'
    output$variable <- as.character(output$variable)
    #make 'empty lines' 
    empties <- data.frame(variable=unique(output$variable), stringsAsFactors=F)
    empties[,colnames(output)[-1]] <- ""
    
    #bind them together
    output2 <- rbind(empties,output)
    output2 <- output2[order(output2$variable,output2$value),]
    
    #optional: 'remove' variable if value present
    
    output2$variable[output2$value!=""] <- ""
    

    这会导致:

       variable value          0         1
    2      carb                           
    7               1  3 (15.8%) 4 (30.8%)
    8               2  6 (31.6%) 4 (30.8%)
    9               3  3 (15.8%)   missing
    10              4  7 (36.8%) 3 (23.1%)
    11              6    missing  1 (7.7%)
    12              8    missing  1 (7.7%)
    3       cyl                           
    13              4  3 (15.8%) 8 (61.5%)
    14              6  4 (21.1%) 3 (23.1%)
    15              8 12 (63.2%) 2 (15.4%)
    1      gear                           
    4               3 15 (78.9%)   missing
    5               4  4 (21.1%) 8 (61.5%)
    6               5    missing 5 (38.5%)
    

    【讨论】:

    • 如果您使用dplyr,另一个选项是gather from tidyr 并与%&gt;% 连接
    【解决方案3】:

    使用 tidyr/dplyr 组合,您可以这样做:

    library(tidyr)
    library(dplyr)
    
    mtcars %>%
      gather(variable, value, gear, carb, cyl) %>%
      group_by(am, variable, value) %>%
      summarise (n = n()) %>%
      mutate(freq = n / sum(n))
    

    【讨论】:

    • 来自gather() 帮助:“gather() 的开发已完成,对于新代码,我们建议切换到pivot_longer(),它更易于使用、功能更多,并且仍在积极开发中.df %&gt;% gather("key", "value", x, y, z) 等价于df %&gt;% pivot_longer(c(x, y, z), names_to = "key", values_to = "value")。"
    猜你喜欢
    • 1970-01-01
    • 2016-04-08
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-04
    • 1970-01-01
    • 2014-11-06
    相关资源
    最近更新 更多