You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:51:23