我们直接演示Meta分析究竟在干什么。

为了确认“氟哌啶”治疗“精神分裂”疾病是否有效,我们需要整合多个RCT(随机对照实验)的研究证据。

1. 从多篇文献中提取如下数据

作者年份用药有效人数用药总人数安慰剂有效人数安慰剂总人数
Arvanitis199725501851
Beasley199629472034
Bechelli19831229230
Borison1992312012
Chouinard19931021322
Durost19641119115
Garry1962725425
Howard1974817313
Marder199419641464
Nishikawa1982110010
Nishikawa19841134013
Reschke19742029211
Selman19761718711
Serafetinides1972414013
Simpson196721607
Spencer19921112112
Vichaiya1971929029

Table 1. 从17篇文献中,整理了作者年份、用药有效人数、用药总人数、安慰剂有效人数和安慰剂总人数

2. 计算每篇文献中结果的p

我们注意到,整理的各个组的数量,其实就是2x2四格表。以Table 1最后一行数据为例,可转换为如下2x2四格表。

组别有效人数无效人数
实验组a(9)b(20)
安慰剂组c(0)d(29)

n = a+b+c+d = 58
转换成四格表的目的,是为了计算p值。就是用数值结果来说明药物是否有效(实验组和对照组是否存在显著性差别)。对于四格表,可以使用卡方检验。
卡方值计算公式如下图
卡方值计算公式.png
于是
分子是 (ad-bc)^2 n = (929 + 200 )^2 58 =3951018
分母是 (a+b)(c+d)(a+c)(b+d) = 29299*49 = 370881
chi_squar = 分子/分母 = 3951018 / 370881 = 10.65
再根据如下推理,可知p<0.01 具体是多少呢p=0.0010

对于四格表,只要计算出来的*卡方值大于3.841,说明p<0.05.卡方值大于6.635,说明p*值<0.01. Bruce Wayne (2024)

对每一篇文献计算卡方值,可以使用如下代码

from scipy.stats import chi2
strings = '''
Arvanitis1997|25|50|18|51
Beasley1996|29|47|20|34
Bechelli1983|12|29|2|30
Borison1992|3|12|0|12
Chouinard1993|10|21|3|22
Durost1964|11|19|1|15
Garry1962|7|25|4|25
Howard1974|8|17|3|13
Marder1994|19|64|14|64
Nishikawa1982|1|10|0|10
Nishikawa1984|11|34|0|13
Reschke1974|20|29|2|11
Selman1976|17|18|7|11
Serafetinides1972|4|14|0|13
Simpson1967|2|16|0|7
Spencer1992|11|12|1|12
Vichaiya1971|9|29|0|29
'''
for line in strings.split('\n'):
    if len(line) >0:
        a = int(line.split("|")[1])
        b = int(line.split("|")[2]) - int(line.split("|")[1])
        c = int(line.split("|")[3])
        d = int(line.split("|")[4]) - int(line.split("|")[3])
        numerator = (a*d - b*c)*(a*d - b*c)*(a+b+c+d)
        
        denominator = (a+b)*(c+d)*(a+c)*(b+d)
        chi_square = numerator / denominator
        p_value = chi2.sf(chi_square,1)
        print(numerator,denominator,chi_square,p_value)

于是表格变成这样。

作者年份用药有效人数用药总人数安慰剂有效人数安慰剂总人数p_valueln(p_value)
Arvanitis1997255018510.1351-2.0020
Beasley1996294720340.7937-0.2311
Bechelli198312292300.0017-6.3605
Borison19923120120.0641-2.7477
Chouinard199310213220.0153-4.1804
Durost196411191150.0019-6.2598
Garry19627254250.3057-1.1850
Howard19748173130.1768-1.7328
Marder1994196414640.3123-1.1636
Nishikawa19821100100.3049-1.1878
Nishikawa198411340130.0191-3.9573
Reschke197420292110.0039-5.5359
Selman197617187110.0331-3.4088
Serafetinides19724140130.0368-3.3026
Simpson1967216070.3276-1.1159
Spencer199211121120.0000-10.0187
Vichaiya19719290290.0011-6.8135
abc80300505000.0000-21.2078

3. 直接进行P值合并

按照fisher转换法进行计算

fisher_chi_square = -2 * sum( ln(p_value) )
自由度df = p值的个数 * 2

就是把全部的p值算一下对数再加起来,所得的和乘以(-2),即可得fisher卡方值。
fisher_chi_square = -2 *(-61.207) = 122.4068
df = 17 * 2 = 34
查表,或者使用python计算得到合并后的p值:6.5444e-12,也就是0.0000000000065444。这是个非常小的数,说明实验组和对照组有显著区别。证明了使用“氟哌啶”治疗“精神分裂”是有效的。

4. 总结

由多篇研究证据,汇总成更强的研究证据,就是Meta分析。
我们可以看到即使存在Beasley1996(p值为0.7937)以及Garry1962(p值为0.3057),Marder1994(p值为0.3123)这样的阴性结论,Meta分析仍然能汇总出有效的结果。

标签: Meta Analysis