标签 Meta Analysis 下的文章

尽管网络上Meta分析的教程很容易检索到,学习的难度也不大。但实际操作过程中,想要自动化 或者半自动化地 在一个小时内产出一篇文章,仍然相当困难。

选题困难

恰当的检索题目,让检索出来的文章数量不会太少(太少的话,没法产生倾向性结论),数量也不能太多(文献较多说明证据已经较为明确)。

文献检索困难

需要购买数据库访问权限。需要按照多个规则(去重、去包含、使用通配符)来准确检索条件。需要构造复杂的检索表达式。

文件检索后初筛困难

在不使用如Endnote或者NoteExpress等文献管理工具时,快速去重、分别、排除掉与研究无关的文献,仍然需要较高的软件开发能力。

数据整理、文献评价和出图容易

为了尽快出文章,我打算写一系列的文章,包含研究思路介绍及软件实现。

  1. 1分钟完成最简Meta分析——系列(一)
  2. 常规Meta分析——系列(二)

我们直接演示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分析仍然能汇总出有效的结果。