【问题标题】:Adding sample n-values to Likert plot in R将样本 n 值添加到 R 中的李克特图
【发布时间】:2016-12-27 17:51:40
【问题描述】:

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

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

 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 值,然后将它们转换为最终的绘图/图表。

非常感谢任何见解!

【问题讨论】:

    标签: r ggplot2 bar-chart


    【解决方案1】:

    在这种情况下,计数不会因问题而异,因此您只需要一张表格来记录回复的数量。以下是在每个问题旁边放置回复数量的方法,适用于回复数量变化的情况,或作为单个表格。

    按问题添加回复数

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

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

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

    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 将 y 轴范围扩大到 150,以便文本值(我设置为 145)可见。这将覆盖plot(l28g) 创建的原始图中的 y 比例(调用likert.bar.plot 来实际生成图)。

    2. 将可见的 y 轴范围设置为停止在 110。我们在 coord_flip() 内执行此操作,这会覆盖来自 likert.bar.plot 的原始 coord_flip()。我们这样做是为了使响应数量的文本恰好位于绘图区域的右侧,而不是在绘图区域内。

    3. 增加绘图右侧边距,使绘图右侧有一些空间。

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

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

    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)
    

    在单个表中添加响应数

    一种选择是创建一个表格 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))
    

    【讨论】:

    • 这是一个很好的观点,虽然我猜很难为条形图中的每个问题创建一个 grob 表(考虑到每个问题的计数可能略有不同)并制作确保它们完美对齐。我的另一个想法是修改左侧的组名,以在括号中包含样本点的数量。例如,对于问题 ST24Q01,它可能不是“美国”,而是“美国 (n=5,233)”。但是对于其他问题,这个值可能会有所不同。显然,如果不按组报告结果,这会更简单。
    • 查看更新后的答案,如果您需要的话,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多