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

如何在R中计算百分比的标准误与95%置信区间并绘图

问题描述

我先按项目状态分组,计算不同人口统计群体中高中毕业受访者的百分比,使用的代码如下:

d_perc <- d %>% 
  group_by(group, levels, program_cat, highschool) %>% 
  summarize(n = n()) %>% 
  mutate(percent = n/sum(n)*100) %>% 
  select(-n)

接下来想为这些百分比计算误差项,请问计算标准误(SE)及对应95%置信区间(CI)的最佳方法是什么?最终目标是用geom_point()和geom_errorbar()做可视化,绘图代码已准备好。

我尝试了以下代码,但运行后se列全为NaN:

d_perc$se <- sqrt(d_perc$percent*(1-d_perc$percent)/d_perc$percent)

原本计划通过±1.96*d_perc$se得到置信区间上下限。

附前100行数据:

d_perc <- structure(list(highschool= structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L), levels = c("no", 
"yes"), class = "factor"), program_cat = structure(c(2L, 2L, 2L, 
2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 
1L), levels = c("0", "1", "2"), class = "factor"), group = c("gender", 
"race", "cohort", "gender", "race", "cohort", "gender", "race", 
"cohort", "gender", "race", "cohort", "gender", "race", "cohort", 
"gender", "race", "cohort", "gender", "race", "cohort", "gender", 
"race", "cohort", "gender", "race", "cohort", "gender", "race", 
"cohort", "gender", "race", "cohort", "gender", "race", "cohort", 
"gender", "race", "cohort", "gender", "race", "cohort", "gender", 
"race", "cohort", "gender", "race", "cohort", "gender", "race", 
"cohort", "gender", "race", "cohort", "gender", "race", "cohort", 
"gender", "race", "cohort", "gender", "race", "cohort", "gender", 
"race", "cohort", "gender", "race", "cohort", "gender", "race", 
"cohort", "gender", "race", "cohort", "gender", "race", "cohort", 
"gender", "race", "cohort", "gender", "race", "cohort", "gender", 
"race", "cohort", "gender", "race", "cohort", "gender"), levels = structure(c(1L, 3L, 7L, 2L, 5L, 7L, 1L, 3L, 
6L, 2L, 4L, 6L, 1L, 5L, 7L, 1L, 3L, 7L, 1L, 3L, 6L, 1L, 3L, 6L, 
1L, 3L, 7L, 1L, 5L, 6L, 2L, 5L, 7L, 1L, 5L, 6L, 1L, 3L, 6L, 2L, 
3L, 7L, 1L, 3L, 6L, 1L, 4L, 6L, 1L, 5L, 6L, 1L, 5L, 6L, 1L, 4L, 
6L, 2L, 3L, 6L, 2L, 3L, 7L, 1L, 3L, 7L, 1L, 3L, 6L, 1L, 4L, 7L, 
1L, 4L, 7L, 1L, 3L, 7L, 1L, 3L, 7L, 1L, 4L, 7L, 1L, 3L, 7L, 1L, 
3L, 6L, 1L, 3L, 7L, 2L, 3L, 7L, 2L, 5L, 6L, 2L), levels = c("Female", 
"Male", "Black", "Hispanic", "White", "CohortA", "CohortB"), class = "factor")), row.names = c(NA, 
-100L), class = c("tbl_df", "tbl", "data.frame"))
问题原因

你当前的标准误计算公式存在两个核心错误:

  1. 分母误用了百分比而非分组总样本量,当百分比为0时会触发除以0的情况,直接导致NaN;
  2. 直接用百分比(0-100)代入公式,而公式要求的是0-1区间的比例,数值逻辑完全错误。
正确解决步骤

1. 保留分组总样本量

修改初始的百分比计算代码,保留每组的总人数(这是计算误差的核心依据):

d_perc <- d %>% 
  group_by(group, levels, program_cat) %>% 
  mutate(total_n = n()) %>%  # 计算每组总人数
  group_by(group, levels, program_cat, highschool) %>% 
  summarize(n = n(), total_n = first(total_n)) %>%  # 保留总人数
  mutate(
    p = n/total_n,  # 先计算0-1区间的比例
    percent = p*100  # 转换为百分比形式
  )

2. 计算标准误与95%置信区间

常规正态近似法(适用于大样本,total_n ≥30)

用比例计算标准误,再转换为百分比对应的误差:

d_perc <- d_perc %>% 
  mutate(
    se = sqrt(p*(1-p)/total_n),  # 比例的标准误
    se_percent = se*100,  # 百分比的标准误
    ci_low = percent - 1.96*se_percent,  # 95% CI下限
    ci_high = percent + 1.96*se_percent   # 95% CI上限
  )

威尔逊区间法(适用于小样本或极端比例)

如果存在小样本(total_n <30)或比例接近0%/100%的情况,推荐用威尔逊区间避免不合理的区间范围:

d_perc <- d_perc %>% 
  mutate(
    ci_low_wilson = (p + (1.96^2)/(2*total_n) - 1.96*sqrt((p*(1-p) + (1.96^2)/(4*total_n))/total_n)) / (1 + (1.96^2)/total_n) * 100,
    ci_high_wilson = (p + (1.96^2)/(2*total_n) + 1.96*sqrt((p*(1-p) + (1.96^2)/(4*total_n))/total_n)) / (1 + (1.96^2)/total_n) * 100
  )

3. 可视化适配

直接用计算好的字段做可视化即可:

ggplot(d_perc, aes(x = levels, y = percent, color = highschool)) +
  geom_point() +
  geom_errorbar(aes(ymin = ci_low, ymax = ci_high), width = 0.2) +
  facet_wrap(~group + program_cat)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:07:34