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

如何为数据框每行执行双比例prop.test?为何p值一致?

问题描述

我想要检验基线(Baseline)与终线(Endline)的比例差异,数据如下:

group n_Baseline n_Endline sample_Baseline sample_Endline
  <chr>      <int>     <int>           <dbl>          <dbl>
1 A            164       158             305            273
2 B             89        65             131            106
3 C             59        68             118            108
4 D             52        48              90             84
5 E            141       107             224            186

我尝试用以下代码计算每行的p值:

df$P_Values <- apply(df, 1, function(x) prop.test(x = c(df$n_Baseline, df$n_Endline), n = c(df$sample_Baseline, df$sample_Endline))$p.value)

结果所有行的p值均为0.109:

group n_Baseline n_Endline sample_Baseline sample_Endline P_Values
  <chr>      <int>     <int>           <dbl>          <dbl>    <dbl>
1 A            164       158             305            273    0.109
2 B             89        65             131            106    0.109
3 C             59        68             118            108    0.109
4 D             52        48              90             84    0.109
5 E            141       107             224            186    0.109

但单独计算每行时p值差异很大,例如第一行执行:

prop.test(x = c(164, 158), n = c(305, 273))

得到的p值为0.3639。请问为何会出现这种情况?如何获取每行对应的准确p值?


问题原因

你在apply的匿名函数中错误引用了整个数据框的列(df$n_Baseline、df$sample_Baseline等),而非当前行的对应值。这导致每次循环都在对所有行的合并数据执行比例检验,而非单独处理每行数据,因此所有行得到的都是同一整体数据的检验结果,p值完全相同。


解决方法

方法1:修正apply的匿名函数

在apply的函数内部,通过x提取当前行的元素(注意apply处理数据框时会将行转为字符向量,需先转换类型):

df$P_Values <- apply(df, 1, function(x) {
  # 提取当前行的数值并转换类型
  n_baseline <- as.integer(x["n_Baseline"])
  n_endline <- as.integer(x["n_Endline"])
  sample_baseline <- as.numeric(x["sample_Baseline"])
  sample_endline <- as.numeric(x["sample_Endline"])
  # 执行比例检验
  prop.test(x = c(n_baseline, n_endline), n = c(sample_baseline, sample_endline))$p.value
})

方法2:使用dplyr逐行处理(更直观)

借助dplyr的rowwise()函数实现逐行操作:

library(dplyr)

df <- df %>%
  rowwise() %>%
  mutate(P_Values = prop.test(x = c(n_Baseline, n_Endline), n = c(sample_Baseline, sample_Endline))$p.value) %>%
  ungroup()

方法3:使用purrr的pmap函数

通过purrr的pmap_dbl按行映射参数,代码更简洁:

library(purrr)

df$P_Values <- pmap_dbl(df[, c("n_Baseline", "n_Endline", "sample_Baseline", "sample_Endline")], 
                        function(nB, nE, sB, sE) prop.test(x = c(nB, nE), n = c(sB, sE))$p.value)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 23:26:30