Julia中基于DataFrame列联表实现Fisher精确检验的优雅写法
Julia 下基于DataFrame优雅实现Fisher精确检验的方案
HypothesisTests.jl原生的FisherExactTest构造函数接收4个标量计数或按固定顺序排列的输入,没有内置DataFrame适配逻辑,无需逐单元格筛选取值,用矩阵转置+splat展开的写法即可达到和R、Python一致的简洁度。
最简一行写法
不需要硬编码行标签做反复筛选,直接提取数值列转矩阵,转置适配Julia列优先的参数展开顺序即可:
using DataFrames, HypothesisTests # 构造示例DataFrame,和测试数据结构完全一致 df = DataFrame(index=["Died", "Survived"], Treatment=[39,30961], Control=[63, 30937]) # 直接传入DataFrame计算,代码长度和R、Python写法相当 ft = FisherExactTest(Matrix(df[:, Not(:index)])'...) # 左单侧检验,结果和R、Python输出完全匹配 pvalue(ft; tail = :left) # 输出: 0.011094091841433727
写法说明:逐行匹配标签取数的原始写法既冗余,又容易因为标签拼写错误、行顺序变动报错。上述写法自动提取所有非行标签的数值列,只要DataFrame满足「行对应列联表事件、列对应列联表分组」的标准结构就能稳定运行。如果你的列联表没有单独存行标签的列,所有列都是分组计数,直接用
FisherExactTest(Matrix(df)'...)即可,不需要做列排除。
一劳永逸的扩展方法
如果需要频繁做这类计算,可以直接给FisherExactTest新增DataFrame类型的支持方法,后续调用完全不需要关心矩阵转换逻辑:
using DataFrames, HypothesisTests # 扩展原生方法,支持直接传入DataFrame function HypothesisTests.FisherExactTest(df::DataFrame; label_col=:index) count_mat = Matrix(df[:, Not(label_col)]) return FisherExactTest(count_mat'...) end # 后续调用体验和R、Python完全一致 df = DataFrame(index=["Died", "Survived"], Treatment=[39,30961], Control=[63, 30937]) ft = FisherExactTest(df) pvalue(ft; tail=:left) # 直接输出检验结果
结果一致性验证
上述写法返回的OR点估计值0.6186、双侧p值0.0222、单侧左尾p值0.0111,和R、Python对应代码的运行结果完全匹配,无精度损失。
内容的提问来源于stack exchange,提问作者PatrickT
相关产品推荐
相关产品推荐

