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

求助:嵌套家庭数据中用ggplot2绘制Spaghetti图的错误排查

排查ggplot2绘制嵌套数据Spaghetti图的问题

我想用ggplot2绘制得分随研究时间点(wave)变化的Spaghetti图,这类图在简单数据集里很容易实现,但这次处理的是按家庭(fam)和同卵/异卵(zyg)嵌套的数据,我只关注每个家庭的第一个MZ个体,却没法得到每条个体对应一条时间线的预期效果。

模拟数据

# 模拟嵌套数据
set.seed(123)
n_fam <- 20
n_wave <- 4

# 生成家庭数据
fam_data <- data.frame(
  fam = rep(1:n_fam, each = 2),
  zyg = rep(c("MZ", "DZ"), n_fam),
  id = 1:(2*n_fam)
)

# 生成时间点得分数据
wave_data <- expand.grid(id = fam_data$id, wave = 1:n_wave)
wave_data$score <- rnorm(nrow(wave_data), mean = 50, sd = 10)

# 合并数据
data <- merge(fam_data, wave_data, by = "id")

当前代码

library(ggplot2)

# 筛选每个家庭的第一个MZ个体
filtered_data <- data %>%
  filter(zyg == "MZ") %>%
  group_by(fam) %>%
  slice(1) %>%
  ungroup()

# 绘制Spaghetti图
ggplot(filtered_data, aes(x = wave, y = score)) +
  geom_line() +
  labs(x = "研究时间点", y = "得分", title = "MZ个体得分随时间变化Spaghetti图")

问题分析

核心问题是缺少分组映射:ggplot2默认会将所有数据点归为一组,因此只会画出一条汇总线条,而非每个个体独立的时间线。你的筛选逻辑是正确的(slice(1)能取到每个家庭的第一个MZ个体),但绘图时没有指定按id分组。

修正方案

在aes()中添加group = id,明确告诉ggplot2按照个体ID分组连线:

library(ggplot2)
library(dplyr)

# 筛选每个家庭的第一个MZ个体
filtered_data <- data %>%
  filter(zyg == "MZ") %>%
  group_by(fam) %>%
  slice(1) %>%
  ungroup()

# 修正后的绘图代码
ggplot(filtered_data, aes(x = wave, y = score, group = id)) +
  geom_line() +
  labs(x = "研究时间点", y = "得分", title = "MZ个体得分随时间变化Spaghetti图")

如果需要直观区分不同个体的线条,可以增加颜色映射:

ggplot(filtered_data, aes(x = wave, y = score, group = id, color = factor(id))) +
  geom_line() +
  labs(x = "研究时间点", y = "得分", title = "MZ个体得分随时间变化Spaghetti图", color = "个体ID") +
  theme(legend.position = "right")

关键说明

  • group = id是实现个体独立时间线的核心,确保每个ID对应的多个时间点数据被单独连线。
  • 确认筛选后的数据中,每个id对应多个wave的记录(模拟数据中每个个体有4个时间点,满足要求)。

内容的提问来源于stack exchange,提问作者lf_araujo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 04:58:08