使用group_by和summarise在子组中查找百分比。

61
我对dplyr还不熟悉,尝试进行以下转换但没有成功。我在互联网上搜索到了在ddply中进行相同转换的示例,但我想使用dplyr来实现。
我有以下数据:
   month   type  count
1  Feb-14  bbb   341
2  Feb-14  ccc   527
3  Feb-14  aaa  2674
4  Mar-14  bbb   811
5  Mar-14  ccc  1045
6  Mar-14  aaa  4417
7  Apr-14  bbb  1178
8  Apr-14  ccc  1192
9  Apr-14  aaa  4793
10 May-14  bbb   916
..    ...  ...   ...

我想使用dplyr来计算每个类型(aaa,bbb,ccc)在月份级别上的百分比。
   month   type  count  per
1  Feb-14  bbb   341    9.6%
2  Feb-14  ccc   527    14.87%
3  Feb-14  aaa  2674    ..
..    ...  ...   ...

我已经尝试过了。
data %>%
  group_by(month, type) %>%
  summarise(count / sum(count))

这将每个值都设为1。我如何使sum(count)在一个月内跨越所有类型进行求和?
MWE:
library(dplyr)

data <- data.frame(month = c("Feb-14","Feb-14","Feb-14","Mar-14","Mar-14","Mar-14","Apr-14","Apr-14","Apr-14","May-14"),
                   type = c("bbb","ccc","aaa","bbb","ccc","aaa","bbb","ccc","aaa","bbb"),
                   count = c(341,527,2674,811,1045,4417,1178,1192,4793,916))
3个回答

86
尝试
library(dplyr)
data %>%
    group_by(month) %>%
    mutate(countT= sum(count)) %>%
    group_by(type, add=TRUE) %>%
    mutate(per=paste0(round(100*count/countT,2),'%'))

或者使它更简单,而不需要创建额外的列。

data %>%
    group_by(month) %>%
    mutate(per =  100 *count/sum(count)) %>% 
    ungroup

在按“月份”汇总count之后,我们也可以使用left_join

或者使用data.table的选项。

 library(data.table)
 setkey(setDT(data), month)[data[, list(count=sum(count)), month], 
               per:= paste0(round(100*count/i.count,2), '%')][]

49

用更少的代码:

df <- data.frame(month=c("Feb-14", "Feb-14", "Feb-14", "Mar-14", "Mar-14", "Mar-14", "Apr-14", "Apr-14", "Apr-14", "May-14"),
             type=c("bbb", "ccc", "aaa", "bbb", "ccc", "aaa", "bbb", "ccc", "aaa", "bbb"),
             count=c(341, 527, 2674, 811, 1045, 4417, 1178, 1192, 4793, 916))


library(dplyr)

df %>% group_by(month) %>% 
       mutate(per=paste0(round(count/sum(count)*100, 2), "%")) %>% 
       ungroup

如果你想“保留”原数据框,那么不应该使用summarise,而mutate就足够了。


17
我们可以使用prop.table来获取每个组内的比例。

这可以用dplyr写成:

library(dplyr)
df %>% group_by(month) %>% mutate(per= prop.table(count) * 100)

#  month  type  count    per
#   <chr>  <chr> <dbl>  <dbl>
# 1 Feb-14 bbb     341   9.63
# 2 Feb-14 ccc     527  14.9 
# 3 Feb-14 aaa    2674  75.5 
# 4 Mar-14 bbb     811  12.9 
# 5 Mar-14 ccc    1045  16.7 
# 6 Mar-14 aaa    4417  70.4 
# 7 Apr-14 bbb    1178  16.4 
# 8 Apr-14 ccc    1192  16.6 
# 9 Apr-14 aaa    4793  66.9 
#10 May-14 bbb     916 100   

基本 R :

df$per <- with(df, ave(count, month, FUN = prop.table) * 100)

data.table

library(data.table)
setDT(df)[, per := prop.table(count) * 100, month]

哇,这真的非常有帮助!谢谢你! - oatmilkyway
是的,好提示! - Stefan Jelkovich
最佳答案!!! - its.me.adam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接