r-dplyr的相对频率,动态创建的列属于每个组



下面是关于为多个类别创建摘要列的非常有用的解决方案。正如链接解决方案中所讨论的,我正在使用一个代码,该代码为每个子组生成百分比列。

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

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中的值汇总,如这里所讨论的,其中我将尝试仅针对指定条件sumBfoo = sum(B[A=="foo"]))执行dplyr语句。然而,这种方法在处理多个类别时效率低下。外部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 |           | 
-------------|-----------|-----------|-----------|-----------|

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

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

最新更新