2016-11-10 101 views
1
df = data.frame(week = as.factor(rep(c(1, 2), times = 5)), 
       name = as.factor(rep(LETTERS[1:5], times = 2)), 
       count = rpois(n = 10, lambda = 20)) 

    > df 
    week name count 
1  1  A 16 
2  2  B 14 
3  1  C 23 
4  2  D 15 
5  1  E 12 
6  2  A 15 
7  1  B 23 
8  2  C 22 
9  1  D 22 
10  2  E 26 

我想计算每周每个名字的计数份额。 起初我打算用下面的方法:如何计算一列中每个类别的份额?

transform(df, week1_share = ifelse(week == "1", round((df$count/sum(df$count) * 100),2), NA)) 
transform(df, week2_share = ifelse(week == "2", round((df$count/sum(df$count) * 100),2), NA)) 

但随后使每一列合并,最终把它作为对条形图标签,显得效率太低。必须有一些类型的快速解决方案,目前我还不知道。

基本上我想要做的是如下,但添加可能已经计算的份额%,如上所述匹配在每个框中。

ggplot(df, aes(reorder(week, -count),count, color = "white", group = name, fill = name))+ 
     geom_bar(position = "stack", stat = "identity") + 
     scale_y_continuous(labels=comma)+ 
     ggthemes::scale_color_tableau() 

enter image description here

我不知道为什么重新排序功能往往不能在我身上。如果您有任何提示以desc分类订单,请分享。

+0

你的意思'骨料(计数〜名,DF功能(I)圆(I * 100 /总和(I),2))'? (df,ave(count,name,FUN = function(i)(round(i * 100/sum(i),2))))' – Sotos

+0

对于每周的计数份额,您可以使用dplyr按周分组,并改变以添加列。 '库(dplyr)'和'df < - mutate(group_by(df,week),round(count/sum(count)* 100,2))' –

+0

嗨,好问题,你能解决你的错误:'data_frame'而不是'data.frame',用于复制粘贴数据的人员。 – snaut

回答

1

你所提供的数据已被使用:

# Loading the required data 
df = data.frame(week = as.factor(rep(c(1, 2), times = 5)), 
       name = as.factor(rep(LETTERS[1:5], times = 2)), 
       count = rpois(n = 10, lambda = 20)) 

使用plyr包功能,百分比和相对已经计算出标签的位置。

#Loading the required packages  
library(plyr) 
library(ggplot2) 

# Calculating the percentages 
df = ddply(df, .(week), transform, percent = round(count/sum(count) * 100)) 

# Calculating the position for plotting 
df = ddply(df, .(week), transform, pos = cumsum(percent) - (0.5 * percent)) 

使用上面计算的信息,已经完成了绘图。

# Basic graph 
p10 <- ggplot() + geom_bar(aes(y = percent, x = week, fill = name), 
         data = df, stat="identity") 

# Adding data labels 
p10 <- p10 + geom_text(data=df, aes(x = week, y = pos, 
           label = paste0(percent,"%")), size=4) 
p10 

这是您一直在寻找的?

enter image description here

+0

这正是我所期待的。非常感谢!我学到了新东西! – tmhs

+0

虽然我有一个额外的问题。“#计算绘图的位置”是将标签放在盒子中间的方法吗?这个怎么用?你能给我一些参考阅读吗? – tmhs

+0

它用于计算每个组内的累计和,这里是“周”。 您可以在ggplot plotting context [1](http://stackoverflow.com/a/15844938/4836511)中使用cumsum获取[cumsum](http://stackoverflow.com/a/16850230/4836511)的用法, ,[2](http://stackoverflow.com/a/15768612/4836511)。 – Prradep

2

在基R A溶液,使用splitunsplitprop.table将是:

df2 <- unsplit(lapply(split(df, df$week), 
        function(x){ 
        x$prop <- prop.table(x$count) 
        x} 
       ), df$week) 

总之split返回data.frames分裂accorting的第二个参数的列表,未分裂把背面togeter由分割产生的列表。

使用data.table包,这是更短:

library(data.table) 
dt <- data.table(df) 
dt[, prop := prop.table(count), by=week] 

我不是真的dplyr流利,但我敢肯定,也有一个很短的和直接的解决方案。

编辑:这是我在dplyr/magrittr想出了:

library(dplyr) 
df3 <- df %>% 
    group_by(week) %>% 
    mutate(freq = prop.table(count)) 
+0

我也更喜欢使用data.table到dplyr。感谢您分享你的知识! – tmhs

相关问题