簡體   English   中英

使用 dplyr 創建具有多個分類/因子變量的匯總比例表

[英]Using dplyr to create summary proportion table with several categorical/factor variables

我正在嘗試創建一個表格,該表格匯總了另一個變量的幾個分類變量(使用頻率和比例)。 我想使用 dplyr 包來做到這一點。

這些以前的 Stack Overflow 討論部分滿足了我的要求: Relative frequency / ratios with dplyrCalculate relative frequency for a specific group

使用 mtcars 數據集,如果我只想按am類別查看gear的比例,則輸出將如下所示:

    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

不過,其實我是想看看不僅gearsam ,也carb通過amcylam ,分別在同一個表。 如果我將代碼修改為:

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

我得到了amgearcarbcyl每種組合的頻率。 這不是我想要的。 有沒有辦法用 dplyr 做到這一點?

編輯

此外,如果有人知道生成我想要的表格的方法,但將am的類別作為列(如經典的 2x2 表格格式),這將是一個額外的好處。 這是我所指的一個例子。 它來自我以前的出版物之一。 我想在 R 中生成這個表,以便我可以使用 RMarkdown 將它直接輸出到 word 文檔:

在此處輸入圖片說明

解決此問題的一種方法是將您的數據轉換為長(er)格式。 然后,您可以使用相同的代碼來計算您想要的結果,並添加一個額外的 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%)

使用 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))

分組依據然后匯總的另一種方法是使用 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 匯總中丟失的其他值。 結果表如下所示

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM