2016-11-10 35 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

相關問題