将百分比添加到GGplot2中的分组条形图列

Mik*_*ike 1 r ggplot2 reshape2 dplyr

希望有人可以帮我标记带百分比的分组条形图的列.我找不到一个可以成功完成工作的现有帖子.下面是基本示例数据帧的代码.

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)
Run Code Online (Sandbox Code Playgroud)

接下来,我用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)
Run Code Online (Sandbox Code Playgroud)

我正在努力的是如何添加列标签.具体来说,我想知道如何添加基本频率计数以及百分比.不是一起,而是一个或另一个.我不能做任何工作.我尝试过使用"+ geom_text(aes(labels ="但我不知道该放什么标签,因为我在ggplot代码中使用了stat ="identity").

另外,对于百分比,我是否需要先用dplyr计算它,还是可以计算ggplot代码中的百分比?我对R中的标签也不太了解,所以不确定如何添加实际的%符号.

希望有人能告诉我实现这一切的基本方法!

eip*_*i10 9

您可以使用stat_countwith 将计数添加为文本geom="text"...count..ggplot用于保存计数值的内部变量.下面的示例显示了如何使用添加计数和百分比stat_count,当然,您可以选择仅包含其中一个.

stat="identity"内心没有做任何事aes.你通常把它放在geom里面.但在这种情况下你不想要,stat="identity"因为你实际上想要ggplot计算每个类别中的值的数量.你可以使用stat="identity"带有geom_bar如果你使用与已经包含每种类别的数列的数据帧.

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

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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

下面是一个示例,您可以预先汇总数据并stat="identity"在绘制时使用:比如说百分比是所有值的百分比,您需要在每个季度内使用百分比.让我们也堆叠条形图并将百分比添加到条形图中作为文本:

首先,创建数据摘要.我们将使用,dplyr以便我们可以使用chaining(%>%)运算符.我们将计算值的数量,计算每个组合中的百分比Year,variable并且我们还将添加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)
Run Code Online (Sandbox Code Playgroud)

现在为情节.请注意,我们提供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") 
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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

更新:回答您的评论中的问题:

  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
    
    Run Code Online (Sandbox Code Playgroud)

    这给出了在每个条形部分内垂直居中标签的y位置.

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

    在我的例子中,级别summary$variable如下:

    levels(summary$variable)
    [1] "Q1" "Q2"
    
    Run Code Online (Sandbox Code Playgroud)

    要重新排序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) 
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,在第二个图中,"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) 
    
    Run Code Online (Sandbox Code Playgroud)

    有关通过设置因子顺序排序轴值的更多信息,此博客文章可能会有所帮助.