2016-03-03 815 views
1

希望有人可以帮我用百分比标记分组条形图的列。我找不到可以成功工作的现有帖子。以下是基本示例数据框的代码。向GGplot2中的分组条形图添加百分比

Service<-c("AS","AS","PS","PS","RS","RS","ES","ES") 

Year<-c("2015","2016","2015","2016","2015","2016","2015","2016") 

Q1<-c("Dissatisfied","Satisfied","Satisfied","Satisfied","Dissatisfied","Dissatisfied","Satisfied","Satisfied") 

Q2<-c("Dissatisfied","Dissatisfied","Satisfied","Dissatisfied","Dissatisfied","Satisfied","Satisfied","Satisfied") 

Example<-data.frame(Service,Year,Q1,Q2) 

接着,我与Reshape2熔化它,这样我可以绘制沿x轴的Q1和Q2列变量。然后我用ggplot2创建了一个基本的分组条形图,其中y轴计数,然后是每年的一个方面。

ExampleM<-melt(Example,id.vars=c("Service","Year")) 

ggplot(ExampleM,aes(x=variable,stat="identity",fill=value)) + 
    geom_bar(position="dodge") + facet_grid(~Year) 

我在努力的是如何添加列标签。具体而言,我想知道如何添加基本频率计数以及百分比。不是两个在一起,而是在一个或另一个。我无法做任何工作。我尝试过使用“+ geom_text(aes(labels =”,但是我不确定把ggplot代码中使用stat =“identity”作为标签的内容。

另外,对于百分比,我需要先用dplyr进行计算,还是可以计算ggplot代码中的百分比?我对R中的标签也不太了解,所以不知道如何添加实际的%符号。给我一个基本的方式来实现这一切!

回答

6

您可以添加算作使用stat_countgeom="text"文本。..count..是内部变量ggplot创建保存的计数值。这位前下面的充足说明如何使用stat_count添加计数和百分比,但当然,您可以选择仅包含其中的一个。

stat="identity"aes内部没有做任何事情。你通常会把它放在geom中。但在这种情况下,您不需要stat="identity",因为您实际上需要ggplot来计算每个类别中值的数量。如果您使用的数据框的列已包含每个类别的计数,则您将使用stat="identity"geom_bar

要创建标签文本,请使用paste0将计算值(例如,..count../sum(..count..)*100是百分比)与%符号之类的文本进行组合。此外,在这种情况下,我使用换行符\n将百分比和计数放在单独的行中。 sprintf是一种格式化函数,在这种情况下会生成四舍五入至小数点后一位的值。

ggplot(ExampleM, aes(x=variable, fill=value)) + 
    geom_bar(position="dodge") + 
    stat_count(aes(label=paste0(sprintf("%1.1f", ..count../sum(..count..)*100), 
           "%\n", ..count..), y=0.5*..count..), 
      geom="text", colour="white", size=4, position=position_dodge(width=1)) + 
    facet_grid(~Year) 

enter image description here

下面是一个例子绘制时,你预先汇总数据,并使用stat="identity":都说而不是百分比是所有值的百分比,你要在每个百分比25美分硬币。我们还可以堆叠条形图并将百分比添加到条形文本中:

首先,创建数据汇总。我们将使用dplyr,以便我们可以使用链接(%>%)运算符。我们将计算值的数量,计算Yearvariable的每个组合内的百分比,并且我们还将添加n.pos以提供堆叠条形图中文本位置的y值。

library(dplyr) 

summary = ExampleM %>% group_by(Year, variable, value) %>% 
    tally %>% 
    group_by(Year, variable) %>% 
    mutate(pct = n/sum(n), 
     n.pos = cumsum(n) - 0.5*n) 

现在的情节。请注意,我们提供y=n。由于我们已经预先汇总了数据(而不是在geom_bar内计算和计算百分比),因此我们需要stat="identity"

ggplot(summary, aes(x=variable, y=n, fill=value)) + 
    geom_bar(stat="identity") + 
    facet_grid(.~Year) + 
    geom_text(aes(label=paste0(sprintf("%1.1f", pct*100),"%"), y=n.pos), 
      colour="white") 

enter image description here

您可以使用round代替,但我更喜欢sprintf,因为它在小数位保持为零,即使小数部分是零,而round回报只是整数部分时,小数部分为零。例如,比较round(3.04, 1)sprintf("%1.1f", 3.04)

UPDATE:要回答的问题在您的意见:

  1. 什么是第二个 “GROUP_BY线” 的原因是什么?我们已经计算了Year,Variable和Value的每个组合的计数。现在,我们想知道,在年份和变量的每个组合中,百分之多少的价值=“满意”,百分之几的价值=“不满意”。为此,我们只想按年和变量分组。

  2. 请解释y=n.pos一行。这是我们计算每个百分比标签的y位置的地方。我们希望标签位于每个酒吧的中间,但酒吧被堆叠。如果我们仅使用cumsum(n),标签将位于每个栏部分的顶部。我们减去0.5*n,这样每个标签的y位置就会减少包含该标签的条部分的高度的一半。下面是一个例子:假设我们有三个高度为1,2和3的条形截面(按照从下到上的顺序堆叠),我们想要计算出我们的标签的y轴位置。

    h = 1:3 
    cumsum(h) # 1 3 6 
    0.5 * h # 0.5 1.0 1.5 
    cumsum(h) - 0.5 * h # 0.5 2.0 4.5 
    

    这给出了y位置,垂直居中每个酒吧部分内的标签。

  3. 如何以百分比递减的顺序排列x轴列?默认情况下,ggplot通过x变量类别的排序来排序离散x轴。对于字符变量,排序将按字母顺序排列。对于因子变量,排序将是因子水平的排序。

    在我的例子,是summary$variable水平如下:

    levels(summary$variable) 
    [1] "Q1" "Q2" 
    

    要通过pct重新排序,一个办法是用reorder功能。比较这些(使用摘要数据帧从上方):

    summary$pct2 = summary$pct + c(0.3, -0.15, -0.45, -0.4, -0.1, -0.2, -0.15, -0.1) 
    
    ggplot(summary, aes(x=variable, y=pct2, fill=value)) + 
        geom_bar(position="stack", stat="identity") + 
        facet_grid(~Year) 
    
    ggplot(summary, aes(x=reorder(variable, pct2), y=pct2, fill=value)) + 
        geom_bar(position="stack", stat="identity") + 
        facet_grid(~Year) 
    

    请注意,在第二曲线,“Q1”和“Q2”的顺序已经反转。但是,请注意左侧面板中的Q1堆栈较高,而在右侧面板中,Q2堆栈较高。随着小平面你在每个面板相同的X轴排序,与顺序确定(据我可以告诉)通过比较所有Q1值的总和和所有Q2值。 Q2的总和较小,所以他们先走。同样的情况,当你使用position="dodge",但我用“堆”,使其更容易地看到发生了什么。下面的例子将有助于澄清事情。

    # Fake data 
    values = c(4.5,1.5,2,1,2,4) 
    dat = data.frame(group1=rep(letters[1:3], 2), group2=LETTERS[1:6], 
           group3=rep(c("W","Z"),3), pct=values/sum(values)) 
    
    levels(dat$group2) 
    [1] "A" "B" "C" "D" "E" "F" 
    
    # plot group2 in its factor order 
    ggplot(dat, aes(group2, pct)) + 
        geom_bar(stat="identity", position="stack", colour="red", lwd=1) 
    
    # plot group2, ordered by -pct 
    ggplot(dat, aes(reorder(group2, -pct), pct)) + 
        geom_bar(stat="identity", colour="red", lwd=1) 
    
    # plot group1 ordered by pct, with stacking 
    ggplot(dat, aes(reorder(group1, pct), pct)) + 
        geom_bar(stat="identity", position="stack", colour="red", lwd=1) 
    
    # Note that in the next two examples, the x-axis order is b, a, c, 
    # regardless of whether you use faceting 
    ggplot(dat, aes(reorder(group1, pct), pct)) + 
        geom_bar(stat="identity", position="stack", colour="red", lwd=1) + 
        facet_grid(.~group3) 
    
    ggplot(dat, aes(reorder(group1, pct), pct, fill=group3)) + 
        geom_bar(stat="identity", position="stack", colour="red", lwd=1) 
    

    更多关于通过设置系数订单订货轴值,this blog post可能会有所帮助。

+0

非常感谢这么长时间和彻底的解释。我有一个关于dplyr代码的问题。我还是dplyr的新手,第二个“group_by line”的原因是什么?另外,我不太了解y = n.pos行吗?它在我尝试代码时起作用,所以我只想更好地理解它。 – Mike

+0

ggplot(PlotsProp,aes(x = variable,y = percent,fill = value))+ geom_bar(position =“dodge”,stat =“identity”)+ geom_text(aes(label = percent(percent)),position = (标题=百分比)+ xlab(“问题”)+ ylab(“受访者百分比”)+ ggtitle(“受访者年份百分比”)+ facet_grid(〜Year) – Mike

+0

此外,我还发现了另一种添加百分比的方法,使用“scales”包。我在上面的评论中发布了代码。所以我的下一个问题是,如果你可以花时间做出另一个快速答案,那么我是如何按百分比降序排列x轴列的?我试图使用dplyr的安排,这工作,但它似乎并没有转化为ggplot2。这是我使用的dplyr代码:订单<-ExampleM%>%group_by(variable,Service,value)%>%summarize(count = n())%> mutate(percent = round((count/sum(count)),2) )%>%arrange(desc(percent)) – Mike