2015-11-30 18 views
2

我正在关注为多个类别创建摘要列的very useful solution。正如链接解决方案中所讨论的那样,我正在使用为每个子组生成百分比列的代码。从链接溶液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% 

问题

我想修改此代码动态地创建与s中可用的唯一类别有关的列第二类在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陈述仅限于指定的条件sumBfoo = sum(B[A=="foo"]))。但是,这种方法在处理多个类别时效率不高。在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 |   | 
-------------|-----------|-----------|-----------|-----------| 

但我只在行很感兴趣比例没有统计和汇总等小玩意。

+1

这让你更接近,但我不清楚你是如何决定从'n'-列删除一些行。 '库(tidyr); count(mtcars,am,gear)%>%mutate(rel.freq = paste0(round(100 * n/sum(n),0),“%”))%>%spread(gear,rel.freq) –

+0

@docendodiscimus非常感谢您对我的小问题表现出兴趣。我也在考虑实现一种创建尺寸矩阵的方法**类别1 x类别2 **,然后在每个单元格中为特定的组合组合插入值。相当繁琐的解决方案,我希望可以通过'dplyr'以更高效的方式做到这一点。 – Konrad

+0

有一个类似的解决方案[这里](http://stackoverflow.com/questions/19500474/find-proportion-across-categories-grouped-by-a-second-category-using-ddply)使用'plyr',我刚刚找到。 – Konrad

回答

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) 

P产品:

3 4 5 
0 79 21 0 
1 0 62 38 
+0

非常感谢您的贡献,这是一个很好的解决方案。我可以问,我怎么能改变生成的列名称。因此,例如,而不是'3'列名称将对应'gear_3'? – Konrad

+0

'name(output)[ - (1:2)] < - paste(“gear”,names(output)[ - (1:2)],sep =“_”) – Axeman

+0

侧。不知道为什么,我在考虑重命名'dplyr'中的列,而不是使用'base'。 – Konrad

相关问题