在ggplot2中使用长格式数据按id分组绘制measuredOnce条形图
解决长格式数据中按唯一参与者统计的条形图问题
我明白你的需求:你的长格式数据里每个参与者(id)有3条重复记录,但measuredOnce是每个参与者仅测量一次的变量,你需要绘制条形图时,让条形高度对应真实的参与者数量,而不是重复行的计数,同时不想转换为宽格式。
问题根源
原代码里的geom_bar()默认会统计所有行的数量,每个id重复3次,所以最终的计数是真实人数的3倍,这就是你看到的错误结果。
两种无需转宽的解决方案
方案1:在ggplot中直接去重(推荐)
因为每个id的measuredOnce、con1、con2都是一致的,我们可以在ggplot调用数据时,保留每个id的唯一一条记录,这样统计的就是真实的参与者数量:
library(tidyverse) # 需要加载tidyverse或者dplyr ggplot(data = dat %>% distinct(id, .keep_all = TRUE)) + aes(x = measuredOnce) + geom_bar() + facet_wrap(~con1*con2)
distinct(id, .keep_all = TRUE)会保留每个id的第一行数据,由于同一id的分组变量和measuredOnce都相同,完全不影响统计结果,而且全程还是基于长格式数据操作。
方案2:使用权重参数
如果你不想修改数据结构,可以给每行记录分配一个权重,让每个id的总权重等于1(因为每个id有3行,所以每行权重是1/3):
ggplot(data = dat) + aes(x = measuredOnce, weight = 1/3) + geom_bar() + facet_wrap(~con1*con2)
geom_bar()会根据权重来计算计数,每个id的3行加起来权重正好是1,最终的条形高度就是真实的参与者数量。
效果验证
这两种方法的输出结果,和你用spread()转换宽格式后绘制的图完全一致,而且都不需要把长格式转成宽格式。
内容的提问来源于stack exchange,提问作者userLL
相关产品推荐
相关产品推荐

