将样本n值添加到R中的Likert图中

时间:2016-08-20 19:56:30

标签: r ggplot2 bar-chart

Bryer Likert软件包有许多有用的功能,可用于绘制Likert型数据的不同条形图。但是,缺少一个基本功能 - 在打印出条形图时,似乎没有任何方法可以显示每个问题/组的采样点总数。如果想要包括直方图,那么这些n值将出现在直方图中。但我经常发现直方图使得整个情节太忙了。

例如,使用比萨数据集,我可以为下面按国家/地区分组的结果绘制一个发散条形图。

 data(pisaitems)

 items28 <- pisaitems[, substr(names(pisaitems), 1, 5) == "ST24Q"]

 # Create the likert object using country as a grouping variable.
 l28g <- likert(items28, grouping = pisaitems$CNT)

 # Optional - print a summary.
 print(l28g)

 # Plot the bar chart.
 plot(l28)

结果图应如下所示: diverging bar chart

但除非我还以某种方式包含直方图(我不想这样做),否则没有选项来报告每个组/问题下面的数据点数量。目前我无法知道(仅通过查看条形图)结果是基于5,000个回复还是10个回复。可以通过多种方式从基础数据轻松访问此信息,例如,以下代码生成问题ST24Q01的每个国家/地区的数据点数:

 margin.table(table(pisaitems$CNT, items28$ST24Q01), 1)

理想情况下,我可以在图表上创建数据图(可能在右侧,就像HH包那样?)报告图表上每个条形的n值(即每个问题/国家)。

我愚弄了likert函数,但到目前为止还无法弄清楚如何在输出中包含n值,然后将它们转换为最终的图/图表。

非常感谢任何见解!

1 个答案:

答案 0 :(得分:3)

在这种情况下,计数不会因问题而异,因此您只需要一个表来表示响应数。以下是在每个问题旁边放置响应数量的方法,以及响应数量变化的情况,或单个表格。

按问题添加回复数量

执行此操作的一种方法是修改likert.bar.plot的基础代码,以包括添加响应计数的功能。在这里,我刚刚攻击了likert.bar.plot的输出,以便在事后添加响应计数。

library(dplyr)
library(gridExtra)
library(reshape2)

首先,按Item为每个CNT获取响应计数。最后的variable=NA就在那里,因为likert.bar.plot在创建绘图时生成的原始数据框会创建并使用名为variable的列。即使我们在随后使用下面的新数据框调用geom_text时不使用该列,ggplot仍然希望colunmn出现在新数据框中。

counts = pisaitems %>%
  select(CNT, matches("ST24Q")) %>% 
  melt(id.var="CNT", variable.name="Item") %>%
  count(CNT, Item) %>%
  mutate(variable=NA)

我们使用geom_text按项添加响应计数,但我们需要对plot(l28g)的输出进行一些其他更改,如下所示:

  1. 使用scale_y_continuous out将y轴限制扩展为150,以便显示文本值(我放在145处)。这将覆盖由plot(l28g)(调用likert.bar.plot实际生成绘图)创建的原始绘图中的y刻度。

  2. 将可见的y轴范围设置为110.我们在coord_flip()内执行此操作,这将覆盖coord_flip()中的原始likert.bar.plot。我们这样做是为了使回复数量的文本位于绘图区域的右侧,而不是在其内部。

  3. 增加正确的地块边距,以便在地块的右边有一些空间。

  4. 关闭剪裁,以便在绘图区域外打印的文本可见。

  5. 这是情节代码。渲染可能需要几秒钟,所以请耐心等待。

    p = plot(l28g) + 
      geom_text(data=counts,
                aes(label=format(n,big.mark=","), x=CNT, y=145), 
                size=2.5, colour="grey30", hjust=1) +
      scale_y_continuous(limits=c(-100,150)) +
      coord_flip(ylim=c(-110,110)) +
      theme(plot.margin=unit(c(0.2,2,0.2,0.2),"cm"))
    
    # Turn off clipping
    # http://stackoverflow.com/a/9691256/496488
    p <- ggplot_gtable(ggplot_build(p))
    p$layout$clip <- "off"
    grid.draw(p)
    

    enter image description here

    在单个表中添加响应数

    一个选项是创建一个表格grob(grob =图形对象)并将其放在主图的侧面或下面。例如:

    library(dplyr)
    library(gridExtra)
    library(reshape2)
    
    tt <- ttheme_default(
      core=list(fg_params=list(fontsize=9)),
      colhead=list(fg_params=list(fontsize=9)),
      rowhead=list(fg_params=list(fontsize=9)))
    
    grid.arrange(plot(l28g),
                 arrangeGrob(nullGrob(),
                             textGrob("Number of Responses", 
                                      gp=gpar(fontsize=11,fontface="bold")),
                             tableGrob(pisaitems %>% 
                                         rename(Country=CNT) %>% 
                                         count(Country) %>%
                                         mutate(n=format(n, big.mark=",")), 
                                       theme=tt, rows=NULL),
                             nullGrob(),
                             heights=c(15,1,5,15)),
                 widths=c(3,1))
    

    enter image description here