【问题标题】:Relative frequencies with dplyr with dynamically created columns pertaining to each groupdplyr 的相对频率以及与每个组相关的动态创建的列
【发布时间】:2015-11-30 13:26:42
【问题描述】:

我正在关注 very useful solution 为多个类别创建摘要列。正如链接解决方案中所讨论的,我正在使用为每个子组生成百分比列的代码。

链接解决方案中的相关示例代码:

mtcars %>%
  group_by (am, gear) %>%
  summarise (n=n()) %>%
  mutate(rel.freq = paste0(round(100 * n/sum(n), 0), "%"))

代码生成所需的值:

## Source: local data frame [4 x 4]
## Groups: am
## 
##   am gear  n rel.freq
## 1  0    3 15      79%
## 2  0    4  4      21%
## 3  1    4  8      62%
## 4  1    5  5      38%

问题

我想修改此代码以动态创建与 dplyr 调用中传递的第二个类别中可用的唯一类别相关的列。 在附加示例的情况下,这将是 gear .因此,在附加示例的情况下,生成的数据框将如下所示:

   am gear  n rel.freq_gear3 rel.freq_gear4  rel.freq_gear5
 1  0    3 15      79%            21%
 2  1    4  8      0              62%            38%

尝试

对于少数类别,我认为我可以利用conditionally 中的值的汇总,正如here, 所讨论的那样,我将尝试仅针对指定条件执行dplyr 语句@987654331 @。但是,这种方法在处理多个类别时效率低下。 dplyr 之外的解决方案可以使用循环开发并跳过所需类别的唯一值,但我希望在 dplyr 中执行此操作。

样本表

一般来说,我想创建一个类似于下面的表格:

 library(gmodels)
 CrossTable(mtcars$am, mtcars$gear)


   Cell Contents
|-------------------------|
|                       N |
| Chi-square contribution |
|           N / Row Total |
|           N / Col Total |
|         N / Table Total |
|-------------------------|


Total Observations in Table:  32 


             | mtcars$gear 
   mtcars$am |         3 |         4 |         5 | Row Total | 
-------------|-----------|-----------|-----------|-----------|
           0 |        15 |         4 |         0 |        19 | 
             |     4.169 |     1.371 |     2.969 |           | 
             |     0.789 |     0.211 |     0.000 |     0.594 | 
             |     1.000 |     0.333 |     0.000 |           | 
             |     0.469 |     0.125 |     0.000 |           | 
-------------|-----------|-----------|-----------|-----------|
           1 |         0 |         8 |         5 |        13 | 
             |     6.094 |     2.003 |     4.339 |           | 
             |     0.000 |     0.615 |     0.385 |     0.406 | 
             |     0.000 |     0.667 |     1.000 |           | 
             |     0.000 |     0.250 |     0.156 |           | 
-------------|-----------|-----------|-----------|-----------|
Column Total |        15 |        12 |         5 |        32 | 
             |     0.469 |     0.375 |     0.156 |           | 
-------------|-----------|-----------|-----------|-----------|

但我只对的比例感兴趣,没有计数、总计和其他小工具。

【问题讨论】:

  • 这让你更接近,但我不清楚你是如何决定从n-列中删除一些行的。 library(tidyr); count(mtcars, am, gear) %>% mutate(rel.freq = paste0(round(100 * n/sum(n), 0), "%")) %>% spread(gear, rel.freq)
  • @docendodiscimus 非常感谢您对我的小问题表现出兴趣。我还在考虑实现一种创建大小矩阵的方法 category 1 x category 2,然后在每个单元格中为特定的组组合插入值。相当繁重的解决方案,我希望也许有办法通过dplyr 以更有效的方式做到这一点。
  • 有一个类似的解决方案here使用我刚刚找到的plyr
  • 我仍然不明白您是如何删除某些信息的(从“n”列中删除)。也许其他人会这样做。
  • 我同意,您预期输出中的 n 列似乎是错误的。您还缺少第一行最后一列中的 0(或 NA)。

标签: r dataframe dplyr summary group-summaries


【解决方案1】:

dplyr

@docendo discimus的评论建设:

library(tidyr)
count(mtcars, am, gear) %>% 
  mutate(rel.freq = n/sum(n)) %>% 
  spread(gear, rel.freq) %>% 
  group_by(am) %>%
  summarize_each(funs(sum2 = sum(., na.rm = TRUE))) %>%
  mutate_each(funs(perc = paste0(round(100 * ., 0), "%")), -am, -n)

生产:

Source: local data frame [2 x 5]

     am     n     3     4     5
  (dbl) (int) (chr) (chr) (chr)
1     0    19   79%   21%    0%
2     1    13    0%   62%   38%

base

prop.table(table(mtcars$am, mtcars$gear), 1) %>% 
  round(2) %>% 
  '*'(100)

生产:

   3  4  5
0 79 21  0
1  0 62 38

【讨论】:

  • 非常感谢您的贡献,这是一个很好的解决方案。请问,我怎么能改变生成的列名。因此,例如,而不是3,列名将对应于gear_3?
  • names(output)[-(1:2)] <- paste("gear", names(output)[-(1:2)], sep = "_")
  • 很公平,我的问题很愚蠢。不知道为什么,我正在考虑重命名dplyr 中的列,而不是使用base
  • 可能有办法,但这似乎更容易。
猜你喜欢
  • 2022-08-18
  • 2020-04-24
  • 2014-08-25
  • 1970-01-01
  • 2017-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多