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

R新手咨询:如何合并两个独立数据集计算基于胎龄的疾病发病率

两独立数据集合并+胎龄别发病率计算实现(R语言初学者适配版)

核心实现逻辑

两个数据集的粒度完全不一致,不能直接逐行匹配合并:

  • 患者明细表是逐个体的长格式,每一行对应1名确诊患者,单条记录只包含该患者的出生年份、胎龄信息
  • 出生统计表是聚合后的分组格式,每一行对应「某年份+某胎龄」分组下的全人群总出生数

因此正确流程是:先把零散的患者明细按「出生年份+胎龄」维度聚合,统计每个分组的患病人数,再用这两个共同的维度作为匹配键,和出生统计表做关联,最后用患病人数除以对应总出生数得到发病率。

前置校验(避免合并失败的关键步骤)

  • 统一两个数据集的匹配字段命名:患者表、出生统计表里的出生年份、胎龄字段必须用完全一致的列名,包括大小写、字符空格都不能有差异
  • 统一匹配字段的数据类型:出生年份、胎龄必须都设为整数型,不能出现一个是文本(比如带“年”字的“1990年”)、一个是数值的情况,否则会导致匹配失败
  • 提前筛除明显异常值:比如胎龄小于28周、大于45周的异常记录,避免无效匹配

可直接复用的计算代码

代码采用tidyverse生态实现,语法简洁没有复杂嵌套,第一次运行前先执行安装命令:install.packages("tidyverse")

library(tidyverse)

# --------------------------
# 替换成自己导入的真实数据即可
# 1. 患者明细表(从Excel导入后重命名列匹配下述格式)
patient_data <- tibble(
  patient_id = 1:10,
  birth_year = c(1990,1990,1990,1990,1990,1990,1990,1990,1991,1991),
  gestational_age_week = c(40,40,40,40,40,40,40,40,38,38)
)

# 2. 出生统计表(从Excel导入后重命名列匹配下述格式)
birth_pop_data <- tibble(
  birth_year = c(1990,1990,1991,1991),
  gestational_age_week = c(40,39,38,39),
  total_birth = c(5000,4200,3600,2100)
)

# --------------------------
# 步骤1:聚合患者明细,统计每个「年份+胎龄」组的患病人数
patient_agg <- patient_data %>%
  group_by(birth_year, gestational_age_week) %>%
  summarise(case_count = n(), .groups = "drop")

# --------------------------
# 步骤2:按两个匹配键合并两个数据集
incidence_result <- patient_agg %>%
  # 保留所有有患者的分组,匹配对应的总出生人数
  left_join(birth_pop_data, by = c("birth_year", "gestational_age_week")) %>%
  # 计算发病率
  mutate(incidence_rate = case_count / total_birth)

# 查看最终计算结果
print(incidence_result)

初学者常见踩坑提醒

  • 切忌直接拿未聚合的患者明细和出生统计表合并:比如8名1990年40周胎龄的患者,如果不提前聚合就合并,会把对应分组的5000总出生数重复复制8行,最终计算的分母会严重失真
  • 合并后要第一时间检查结果里的缺失值:如果总出生数列出现NA,优先排查匹配键的类型是否一致——比如患者表的胎龄是浮点数40.0,统计表的胎龄是整数40,类型不匹配就会匹配失败
  • 如果需要把发病率转成千分率/万分率,只要在mutate计算的时候乘对应换算系数即可,比如千分率就是incidence_rate = case_count / total_birth *1000

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.27 16:06:05