效应量计算 & 转换




Meta 分析师经常面临的一个问题是,无法从所有纳入的研究中提取到合适的“原始”效应量数据。{meta} 程序包中的大多数函数,例如 metacont (第 @ref(pooling-smd) 章) 或 metabin (第 @ref(pooling-or-rr) 章),只能在有完整的原始效应量数据时才能使用。

在实践中,这通常会导致困难。一些已发表的文章,特别是较早的文章,其报告结果的方式无法提取所需的(原始)效应量数据。经常发现一项研究报告了 \(t\)-检验、单因素 ANOVA 或 \(\chi^2\)-检验的结果,但没有报告我们进行 meta 分析所需的组间均值和标准差,或研究条件下的事件数。

好消息是,我们有时可以将报告的信息转换为所需的效应量格式。这使得可以使用 metagen 将受影响的研究纳入具有预先计算数据(第 @ref(pre-calculated-es) 章)的 meta 分析中。例如,我们可以将双样本 \(t\)-检验的结果转换为标准化均值差及其标准误,然后使用 metagen 对预先计算的 SMD 执行 meta 分析。{esc} 程序包 [@esc] 提供了几个有用的函数,允许我们在 R 中直接执行此类转换。



均值 & 标准误


当从均值和标准误计算 SMD 或 Hedges’ \(g\) 时,我们可以利用均值的标准差定义为其标准误,并从中“分解出”样本大小的平方根 [@thalheimer2002calculate]

\[\begin{equation} \text{SD} =\text{SE}\sqrt{n} (\#eq:esc1) \end{equation}\]

我们可以使用 esc_mean_se 函数计算 SMD 或 Hedges’ \(g\)。这是一个例子:

library(esc)

esc_mean_se(grp1m = 8.5,   # 第 1 组的均值
            grp1se = 1.5,  # 第 1 组的标准误
            grp1n = 50,    # 第 1 组的样本量
            grp2m = 11,    # 第 2 组的均值
            grp2se = 1.8,  # 第 2 组的标准误
            grp2n = 60,    # 第 2 组的样本量
            es.type = "d") # 转换为 SMD;使用 "g" 表示 Hedges' g

Effect Size Calculation for Meta Analysis

     Conversion: mean and se to effect size d
    Effect Size:  -0.2012
 Standard Error:   0.1920
       Variance:   0.0369
       Lower CI:  -0.5774
       Upper CI:   0.1751
         Weight:  27.1366



回归系数


可以从标准化或非标准化回归系数计算 SMD、Hedges’ \(g\) 或相关系数 \(r\) [@lipsey2001practical, Appendix B]。对于非标准化系数,我们可以使用 {esc} 中的 esc_B 函数。这是一个例子:

library(esc)

esc_B(b = 3.3,       # 非标准化回归系数
      sdy = 5,       # 预测变量 y 的标准差
      grp1n = 100,   # 第一组的样本量
      grp2n = 150,   # 第二组的样本量
      es.type = "d") # 转换为 SMD;使用 "g" 表示 Hedges' g

Effect Size Calculation for Meta Analysis

     Conversion: unstandardized regression coefficient to effect size d
    Effect Size:   0.6962
 Standard Error:   0.1328
       Variance:   0.0176
       Lower CI:   0.4359
       Upper CI:   0.9565
         Weight:  56.7018
esc_B(b = 2.9,       # 非标准化回归系数
      sdy = 4,       # 预测变量 y 的标准差
      grp1n = 50,    # 第一组的样本量
      grp2n = 50,    # 第二组的样本量
      es.type = "r") # 转换为相关系数
## Effect Size Calculation for Meta Analysis
## 
##      Conversion: unstandardized regression coefficient 
##                  to effect size correlation
##     Effect Size:   0.3611
##  Standard Error:   0.1031
##        Variance:   0.0106
##        Lower CI:   0.1743
##        Upper CI:   0.5229
##          Weight:  94.0238
##      Fisher's z:   0.3782
##       Lower CIz:   0.1761
##       Upper CIz:   0.5803

可以使用 esc_beta 转换标准化回归系数。

esc_beta(beta = 0.32,   # 标准化回归系数
         sdy = 5,       # 预测变量 y 的标准差
         grp1n = 100,   # 第一组的样本量
         grp2n = 150,   # 第二组的样本量
         es.type = "d") # 转换为 SMD;使用 "g" 表示 Hedges' g

Effect Size Calculation for Meta Analysis

     Conversion: standardized regression coefficient to effect size d
    Effect Size:   0.6867
 Standard Error:   0.1327
       Variance:   0.0176
       Lower CI:   0.4266
       Upper CI:   0.9468
         Weight:  56.7867
esc_beta(beta = 0.37,   # 标准化回归系数
         sdy = 4,       # 预测变量 y 的标准差
         grp1n = 50,    # 第一组的样本量
         grp2n = 50,    # 第二组的样本量
         es.type = "r") # 转换为相关系数
## Effect Size Calculation for Meta Analysis
## 
##      Conversion: standardized regression coefficient 
##                  to effect size correlation
##     Effect Size:   0.3668
##  Standard Error:   0.1033
##        Variance:   0.0107
##        Lower CI:   0.1803
##        Upper CI:   0.5278
##          Weight:  93.7884
##      Fisher's z:   0.3847
##       Lower CIz:   0.1823
##       Upper CIz:   0.5871

请注意,在 meta 分析中使用回归系数可能很棘手,因为我们假设所有研究都使用了相同的模型。如果系数是从多个回归模型中提取的,这尤其成问题,因为研究可能在其模型中控制了不同的协变量,这意味着 \(b\) 值不具有直接可比性。



相关系数


对于组大小相等的情况 (\(n_1=n_2\)),我们可以使用以下公式从点二列相关系数推导出 SMD [@lipsey2001practical, chapter 3]

\[\begin{equation} r_{pb} = \frac{\text{SMD}}{\sqrt{\text{SMD}^2+4}} ~~~~~~~~ \text{SMD}=\frac{2r_{pb}}{\sqrt{1-r^2_{pb}}} (\#eq:esc2) \end{equation}\]

对于组大小不相等的情况,必须使用不同的公式 [@aaron1998equating]

\[\begin{align} r_{pb} &= \frac{\text{SMD}}{\sqrt{\text{SMD}^2+\dfrac{(N^2-2N)}{n_1n_2}}} \notag \\ \text{SMD} &= \dfrac{r_{pb}}{\sqrt{(1-r^2)\left(\frac{n_1}{N}\times\left(1-\frac{n_1}{N}\right)\right)}} (\#eq:esc3) \end{align}\]

要将 \(r_{pb}\) 转换为 SMD 或 Hedges’ \(g\),我们可以使用 esc_rpb 函数。

library(esc)

esc_rpb(r = 0.25,      # 点二列相关系数
        grp1n = 99,    # 第 1 组的样本量
        grp2n = 120,   # 第 2 组的样本量
        es.type = "d") # 转换为 SMD;使用 "g" 表示 Hedges' g

Effect Size Calculation for Meta Analysis

     Conversion: point-biserial r to effect size d
    Effect Size:   0.5188
 Standard Error:   0.1380
       Variance:   0.0190
       Lower CI:   0.2483
       Upper CI:   0.7893
         Weight:  52.4967



单因素 ANOVA


我们还可以从具有个组的单因素 ANOVA 的 \(F\)-值推导出 SMD。可以通过查看自由度来识别此类 ANOVA。在具有两个组的单因素 ANOVA 中,自由度应始终以 1 开头(例如,\(F_{\text{1,147}}\)=5.31)。

用于转换的公式如下 [基于 @rosnow1996computing; @rosnow2000contrasts; 参见 @thalheimer2002calculate]

\[\begin{equation} \text{SMD} = \sqrt{ F\left(\frac{n_1+n_2}{n_1 n_2}\right)\left(\frac{n_1+n_2}{n_1+n_2-2}\right)} (\#eq:esc4) \end{equation}\]

要从 \(F\)-值计算 SMD 或 Hedges’ \(g\),我们可以使用 esc_f 函数。这是一个例子:

esc_f(f = 5.04,      # 单因素方差分析的 F 值
      grp1n = 519,   # 第 1 组的样本量
      grp2n = 528,   # 第 2 组的样本量
      es.type = "g") # 转换为 Hedges' g;使用 "d" 表示 SMD

Effect Size Calculation for Meta Analysis

     Conversion: F-value (one-way-Anova) to effect size Hedges' g
    Effect Size:   0.1387
 Standard Error:   0.0619
       Variance:   0.0038
       Lower CI:   0.0174
       Upper CI:   0.2600
         Weight: 261.1022



双样本 \(t\)-检验


效应量表示为标准化均值差也可以从独立双样本 \(t\)-检验值导出,使用以下公式 [@rosnow2000contrasts; @thalheimer2002calculate]

\[\begin{equation} \text{SMD} = \frac {t(n_1+n_2)}{\sqrt{(n_1+n_2-2)(n_1n_2)}} (\#eq:esc5) \end{equation}\]

R 中,我们可以使用 esc_t 函数从 \(t\)-值计算 SMD 或 Hedges’ g。这是一个例子:

esc_t(t = 3.3,     # t 值
      grp1n = 100, # group1 的样本量
      grp2n = 150, # group 2 的样本量
      es.type="d") # 转换为 SMD;使用 "g" 表示 Hedges' g

Effect Size Calculation for Meta Analysis

     Conversion: t-value to effect size d
    Effect Size:   0.4260
 Standard Error:   0.1305
       Variance:   0.0170
       Lower CI:   0.1703
       Upper CI:   0.6818
         Weight:  58.7211



\(p\)-值


有时,研究仅报告效应量(例如,Cohen’s \(d\) 值)、该效应的 \(p\)-值,仅此而已。然而,要在 meta 分析中汇集结果,我们需要一种衡量效应量精确度的方法,最好是标准误。

在这种情况下,我们必须从效应量的 \(p\)-值估计标准误。对于基于差异(即 SMD)或比率(即风险或优势比)的效应量,这是可行的,使用 Altman 和 Bland 的公式 [-@altman2011obtain]。这些公式在 Rse.from.p 函数中实现。

“se.from.p”函数

se.from.p 函数包含在 {dmetar} 程序包中。一旦在您的计算机上安装并加载 {dmetar},该函数就可以使用了。如果您没有安装 {dmetar},请按照以下说明操作:

  1. 在线访问该函数的源代码 online
  2. 通过将源代码的全部内容复制并粘贴到控制台(R Studio 的左下窗格)中,然后按“Enter”,让 R “学习”该函数。

假设一项研究有 \(N=\) 71 名参与者,报告的效应量为 \(d=\) 0.71,其中 \(p=\) 0.013,我们可以这样计算标准误:

library(dmetar)

se.from.p(0.71,
          p = 0.013,
          N = 71,
          effect.size.type = "difference")
##   EffectSize StandardError StandardDeviation  LLCI  ULCI
## 1       0.71         0.286             2.410 0.149 1.270

对于一项有 \(N=\) 200 名参与者的研究,报告的效应量为 OR = 0.91,其中 \(p=\) 0.38,标准误的计算方式如下:

library(magrittr) # for pipe

se.from.p(0.91, p = 0.38, N = 200,
          effect.size.type = "ratio") %>% t()
##                        [,1]
## logEffectSize        -0.094
## logStandardError      0.105
## logStandardDeviation  1.498
## logLLCI              -0.302
## logULCI               0.113
## EffectSize            0.910
## LLCI                  0.739
## ULCI                  1.120

effect.size.type = "ratio" 时,该函数还会自动计算对数转换的效应量和标准误,这是使用 metagen 函数(第 @ref(pre-calculated-es) 章)所必需的。



\(\chi^2\) 检验


要将 \(\chi^2\) 统计量转换为优势比,可以使用 esc_chisq 函数(假设 d.f. = 1;例如,\(\chi^2_1\) = 8.7)。这是一个例子:

esc_chisq(chisq = 7.9,        # 卡方值
          totaln = 100,       # 总样本量
          es.type = "cox.or") # 转换为优势比

Effect Size Calculation for Meta Analysis

     Conversion: chi-squared-value to effect size Cox odds ratios
    Effect Size:   2.6287
 Standard Error:   0.3440
       Variance:   0.1183
       Lower CI:   1.3394
       Upper CI:   5.1589
         Weight:   8.4502



需治人数


Cohen’s \(d\) 或 Hedges’ \(g\) 等效应量通常难以从实践角度解释。想象一下,我们在 meta 分析中发现干预效果为 \(g=\) 0.35。我们如何向患者、政府官员、医疗专业人员或其他利益相关者传达这种效果的含义

为了让其他人更容易理解结果,meta 分析通常还会报告需治人数 (NNT)。该指标最常用于医学研究。它表示必须接受研究治疗的额外患者人数,才能预防一个额外的负面事件(例如,复发)或实现一个额外的正面事件(例如,症状缓解、反应)。例如,如果 NNT = 3,我们可以说必须接受治疗的三个人才能避免一个额外的复发病例;或者必须治疗三名患者才能实现一个额外的可靠症状缓解病例,具体取决于研究问题。

当我们处理二元效应量数据时,NNT 的计算相对容易。公式如下:

\[\begin{equation} \text{NNT} = (p_{e_{\text{treat}}}-p_{e_{\text{control}}})^{-1} (\#eq:esc6) \end{equation}\]

在此公式中,\(p_{e_{\text{treat}}}\)\(p_{e_{\text{control}}}\) 是在治疗组和对照组中经历该事件的参与者比例。这些比例与用于计算风险比的“风险”(第 @ref(rr) 章)相同,也称为实验组事件率 (EER) 和对照组事件率 (CER)。鉴于其公式,NTT 也可以描述为(绝对)风险差异的倒数。

将标准化均值差或 Hedges’ \(g\) 转换为 NNT 更为复杂。有两种常用的方法:

  • Kraemer 和 Kupfer 的方法 [-@kraemer2006size],该方法从曲线下面积 (AUC) 计算 NNT,AUC 定义为治疗组患者的结果优于对照组患者结果的概率。此方法允许直接从 SMD 或 \(g\) 计算 NNT,而无需任何额外信息。

  • Furukawa 和 Leucht 的方法使用 CER 或其合理估计值从 SMD 计算 NNT 值。与 Kraemer & Kupfer 方法相比,Furukawa 的方法已被证明在估计真实 NNT 值方面更优 [@furukawa2011obtain]。如果我们可以对 CER 进行合理的估计,则应始终首选 Furukawa 的方法。

当我们使用风险比或优势比作为效应量指标时,可以使用 nnt 函数直接从 {meta} 对象计算 NNT。在使用 metabin 运行 meta 分析(第 @ref(pooling-or-rr) 章)后,我们只需将结果插入 nnt 函数即可。这是一个例子:

library(meta)
Loading required package: metadat
Loading 'meta' package (version 8.1-0).
Type 'help(meta)' for a brief overview.
data(Olkin1995)

# 使用二元效应量数据运行 meta 分析
m.b <- metabin(ev.exp, n.exp, ev.cont, n.cont, 
               data = Olkin1995,
               sm = "RR")
nnt(m.b)
Number needed to treat (common effect model): 

     RR    p.c    NNTB             95%-CI
 0.7728 0.1440 30.5677 [26.1222; 37.2386]
 0.7728 0.3750 11.7383 [10.0312; 14.3001]

Number needed to treat (random effects model): 

     RR    p.c    NNTB             95%-CI
 0.7694 0.1440 30.1139 [24.0662; 41.3519]
 0.7694 0.3750 11.5641 [ 9.2417; 15.8796]

nnt 函数提供了针对不同假设 CER 的需治人数。这三行显示了数据集中最小、平均和最大 CER 的结果。平均 CER 估计值是通常报告的“典型”NNT。

只要摘要度量 sm"RR""OR",也可以将 nntmetagen 模型一起使用。对于此类模型,我们还需要在 nntp.c 参数中指定假设的 CER。以下是使用我们在第 @ref(m-gen-bin) 章中创建的 m.gen_bin meta 分析对象的示例:

# Also show fixed-effect model results
m.gen_bin <- update(m.gen_bin, fixed = TRUE)
Warning: Use argument 'common' instead of 'fixed' (deprecated).
nnt(m.gen_bin, 
    p.c = 0.1) # 使用 0.1 的 CER
Number needed to treat (common effect model): 

     RR    p.c   NNTH            95%-CI
 2.0319 0.1000 9.6906 [8.2116; 11.6058]

Number needed to treat (random effects model): 

     RR    p.c   NNTH            95%-CI
 2.0218 0.1000 9.7870 [6.4761; 16.4843]

可以使用 {dmetar} 中的 NNT 函数将标准化均值差或 Hedges’ \(g\) 转换为 NNT。

“NNT”函数

如果您没有安装 {dmetar},请按照以下说明操作:

  1. 在线访问 NNT 函数的源代码 online
  2. 通过将源代码的全部内容复制并粘贴到控制台(R Studio 的左下窗格)中,然后按“Enter”,让 R “学习”该函数。

要使用 Kraemer & Kupfer 方法,我们只需要为 NNT 函数提供一个效应量(SMD 或 \(g\))。只要提供了 CER 值,就会自动使用 Furukawa 的方法。

source('./NNT.R') # load NNT function
NNT(d = 0.245)
[1] 7.270711
attr(,"class")
[1] "NNT"     "kk"      "numeric"
NNT(d = 0.245, CER = 0.35)
[1] 10.61533
attr(,"class")
[1] "NNT"     "fl"      "numeric"

一个需要谨慎对待的数字:对 NNT 的批评

虽然很常见,但使用 NNT 来传达临床试验的结果并非没有争议。批评包括外行人经常误解它 [尽管据称它是其他效应量指标的“直观”替代方案,@christensen2006number];以及研究人员经常错误地计算 NNT [@mendes2017number]

此外,无法计算 NNT 的可靠标准误(和置信区间),这意味着它们不能用于 meta 分析 [@hutton2010misleading]。只能在使用其他效应量指标进行合并后,才能将结果转换为 NNT。



多臂研究


为避免单元分析错误(第 @ref(unit-of-analysis) 章),有时需要在计算(标准化)均值差之前,合并两个或多个试验组的均值和标准差。要合并两个组的连续效应量数据,我们可以使用以下等式:

\[\begin{align} n_{\text{pooled}} &= n_1 + n_2 \\ m_{\text{pooled}} &= \frac{n_1m_1+n_2m_2}{n_1+n_2} \\ SD_{\text{pooled}} &= \sqrt{\frac{(n_1-1)SD^{2}_{1}+ (n_2-1)SD^{2}_{2}+\frac{n_1n_2}{n_1+n_2}(m^{2}_1+m^{2}_2-2m_1m_2)} {n_1+n_2-1}} \end{align}\]

我们可以使用 pool.groups 函数在 R 中应用此公式。

“pool.groups”函数

pool.groups 函数包含在 {dmetar} 程序包中。一旦在您的计算机上安装并加载 {dmetar},该函数就可以使用了。如果您没有安装 {dmetar},请按照以下说明操作:

  1. 在线访问该函数的源代码 online
  2. 通过将源代码的全部内容复制并粘贴到控制台(R Studio 的左下窗格)中,然后按“Enter”,让 R “学习”该函数。

这是一个例子:

library(dmetar)
Extensive documentation for the dmetar package can be found at: 
 www.bookdown.org/MathiasHarrer/Doing_Meta_Analysis_in_R/

Attaching package: 'dmetar'
The following object is masked _by_ '.GlobalEnv':

    NNT
pool.groups(n1 = 50,   # 组 1 的样本量
            n2 = 50,   # 组 2 的样本量
            m1 = 3.5,  # 组 1 的均值
            m2 = 4,    # 组 2 的均值
            sd1 = 3,   # 组 1 的标准差
            sd2 = 3.8) # 组 2 的标准差
  Mpooled SDpooled Npooled
1    3.75 3.415369     100



效应量的聚合


{metafor} 中的 aggregate 函数可用于将几个相关的、预先计算的效应量聚合为一个估计值,例如因为它们是同一研究或集群的一部分。这是避免单元分析错误的一种方法(参见第 @ref(unit-of-analysis) 章),但这需要我们假设研究内部相关性的值,这通常是未知的。处理效应量依赖性的另一种(通常是更可取的)方法是(相关)分层模型,这将在第 @ref(multilevel-ma) 章中进行说明。

在本例中,我们聚合 Chernobyl 数据集(参见第 @ref(multilevel-R) 章)的效应量,以便每个研究仅提供一个效应量:

library(metafor)
library(dmetar)
data("Chernobyl")

# 将 'Chernobyl' 数据转换为 'escalc' 对象
Chernobyl <- escalc(yi = z,           # 效应量
                    sei = se.z,       # 标准误
                    data = Chernobyl)

# 在研究层面聚合效应量
# 我们假设相关性为 rho=0.6
Chernobyl.agg <- aggregate(Chernobyl, 
                           cluster = author,
                           rho = 0.6)

# 显示聚合结果
Chernobyl.agg[,c("author", "yi", "vi")]
##                       author     yi     vi 
## 1 Aghajanyan & Suskov (2009) 0.2415 0.0079 
## 2     Alexanin et al. (2010) 1.3659 0.0012 
## 3             Bochkov (1993) 0.2081 0.0014 
## 4      Dubrova et al. (1996) 0.3068 0.0132 
## 5      Dubrova et al. (1997) 0.4453 0.0110
## [...]

请注意,aggregate 返回聚合的效应量 yi 以及它们的 方差 vi,其平方根是标准误。

\[\tag*{$\blacksquare$}\]