-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy path12_Meta.Rmd
2003 lines (1561 loc) · 141 KB
/
12_Meta.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Meta-analysis and Publication Bias {#meta}
When several research teams work on a similar topic, they obtain and publish several estimates for the same program of for similar programs.
For example, teams of doctors regularly test the same treatment on different samples or populations in order to refine the estimated effect.
Similarly, economists report on the effects of similar types of programs (Conditional and Unconditional Cash Transfers, Job Training Programs, microcredit, etc) implemented in different countries.
Meta-analysis aims at summarizing and synthetizing the available evidence with two main goals in mind:
1. Increasing precision by providing an average estimated effect combining several estimates
2. Explaining variations in treatment effectiveness by relating changes in effect size to changes in sample characteristics.
One key issue that meta-analysis has to face -- actually, we all have to face it, meta-analysis simply makes it more apparent -- is that of publication bias.
Publication bias is due to the fact that referees and editors have a marked preference for publishing statistically significant results.
The problem with this approach is that the distribution of published results is going to be censored on the left: we will have more statistically significant results in the published record, and as a consequence, the average published result will be an upward biased estimate of the true treatment effect in the population.
This is potentially a very severe problem if the amount of censoring due to publication bias is large.
Eventually, this hinges on the true distribution of treatment effects: if it is centered on zero or close to zero, we run the risk of having very large publication bias.
In this chapter, I present first the tools for meta-analysis, and I then move on to testing and correcting for publication bias.
Most of the material presented here stems from the reference book by [Hedges and Olkin](https://www.sciencedirect.com/book/9780080570655/statistical-methods-for-meta-analysis).
When needed, I update this book with new references that I then cite.
the R code comes mainly from a [wonderful set of slides](http://www.edii.uclm.es/~useR-2013/Tutorials/kovalchik/kovalchik_meta_tutorial.pdf) explaining of the `metafor` package works.
## Meta-analysis
There are several approaches and refinements to meta-analysis.
In this section, I am going to present only the most important ones.
I'll defer the reader to other more specialized publications if needed.
I first present the basics of meta-analysis: the constitution and structure of the sample.
Second, I present the problems of the intuitive "vote-counting" method.
Third, I present the methods used when treatment effects are homogeneous across studies, called fixed effects models.
Fourth, I move to the methods used when effects are heterogeneous across studies, or random effects models, and the tests used to decide whether we are in a fixed or random effects framework.
Fifth, I present meta-regression, that tries to capture treatment effect heterogeneity by including covariates.
Finally, I present constantly updated meta-analysis, a way to aggregate results of individual studies as they come.
### Basic setting
The basic setting for a meta-analysis is that you have access to a list of estimates for the effect of a given program and for their precision.
These estimates come from the literature, searching published and unpublished sources alike.
This data is usually collected after an extensive search of bibliographic databases.
Then, one has to select among all the studies selected by the search the ones that are actualy relevant.
This is the most excruciating part of a meta-analysis, since a lot of the studies selected by hte search algorithm are actually irrelevant.
Finally, one has to extract from each relevant paper an estimate of the effect of the treatment and of its precision.
In general, one tries to choose standardized estimates such as the effect size (see Section \@ref(sec:effectsize) for a definition) and its standard error.
After all this process, we should end up with a dataset like: $\left\{(\hat{\theta}_k,\hat{\sigma}_k)\right\}_{k=1}^N$, with $\hat{\theta}_k$ the estimated effect size, $\hat{\sigma}_k$ its estimated standard error, and $N$ the number of included studies.
```{example}
Let's see how such a dataset would look like?
Let's build one from our simulations.
```
```{r confintervalESCLT,dependson=c('monte.carlo'),eval=TRUE,echo=TRUE,results='hide',warning=FALSE,error=FALSE,message=FALSE,fig.cap=paste('Example data set: effect sizes and confidence intervals with $\\delta=$',delta.2,sep=' '),fig.align='center',out.width=cst,fig.pos='htbp',fig.height=8,fig.width=12}
N.sample <- c(100,1000,10000,100000)
N.plot.ES.CLT <- c(10,7,2,1)
data.meta <- data.frame(ES=numeric(),
se=numeric())
se.ww.CLT.ES <- function(N,v1,v0,p){
return(sqrt((v1/p+v0/(1-p))/N)/v0)
}
for (k in 1:length(N.sample)){
set.seed(1234)
simuls.ww[[k]]$se.ES <- se.ww.CLT.ES(N.sample[[k]],simuls.ww[[k]][,'V1'],simuls.ww[[k]][,'V0'],simuls.ww[[k]][,'p'])
test.ES <- simuls.ww[[k]][sample(N.plot.ES.CLT[[k]]),c('ES','se.ES')]
test.ES$N <- rep(N.sample[[k]],N.plot.ES.CLT[[k]])
data.meta <- rbind(data.meta,test.ES)
}
data.meta$id <- 1:nrow(data.meta)
#data.meta$N <- factor(data.meta$N,levels(N.sample))
ggplot(data.meta, aes(x=as.factor(id), y=ES)) +
geom_bar(position=position_dodge(), stat="identity", colour='black') +
geom_errorbar(aes(ymin=ES-qnorm((delta.2+1)/2)*se.ES, ymax=ES+qnorm((delta.2+1)/2)*se.ES), width=.2,position=position_dodge(.9),color='blue') +
geom_hline(aes(yintercept=ES(param)), colour="#990000", linetype="dashed")+
xlab("Studies")+
ylab("Effect size")+
theme_bw()
```
Figure \@ref(fig:confintervalESCLT) shows the resulting sample.
I've selected `r N.plot.ES.CLT[[1]]` studies with $N=$ `r N.sample[[1]]`, `r N.plot.ES.CLT[[2]]` studies with $N=$ `r N.sample[[2]]`, `r N.plot.ES.CLT[[3]]` studies with $N=$ `r N.sample[[3]]`, and `r N.plot.ES.CLT[[4]]` study with $N=$ `r N.sample[[4]]`.
The studies are represented in that order, mimicking the increasing sample size of studies that accumulate evidence on a treatment, probably with studies with a small sample size at first, and only large studies at the end for the most promising treatments.
### Why vote-counting does not work
Vote-counting is an alternative to weighted average or meta-regression.
The term, coined by Light and Smith (1971), refers to the practice of counting the number of studies that fall under one of three categories:
* Significant and positive,
* Insignificant,
* Significant and negative.
A vote-counting approach concludes that there is evidence in favor of the treatment when the majority of effects fall in the first category, that there is no evidence that the treatment has an impact whenthe majority of studies fall in the second category, and that there is evidence that the treatment is defavorable when the majority of studies fall in the third category.
In general, majority is evaluated at 33\%.
The main problem with the vote counting approach is that it does not give more weight to more precise studies.
As a consequence, there is a very realistic possibility that the probability of finding the truth decrease as we add more studies to the meta-analysis.
Let's see how this could happen with a simulation taken from HEdges and Olkin's book.
Let $p$ be the probaility that a given result is significant and positive.
$p$ depends on the sample size $n$ of the study, and on the true treatment effect, $\theta$:
\begin{align*}
p & = \int_{C_{\alpha}}^{\infty}f(t;\theta,n),
\end{align*}
where $f$ is the density of the test statistic $T$ used to evaluate whether the effect is significant or not, and $C_{\alpha}$ is the critical value of the test $T$.
If $n$ and $\theta$ are constant over studies (for simplicity), the process of accumulating significant results can be modelled as a binomial with parameter $p$.
The probability that over $K$ studies, we have a proportion of significant results larger than a pre-specified threshold (let's say $C_0$) is equal to:
\begin{align*}
\Pr(\frac{X}{K}>C_0) & = \sum_{k=\text{int}(C_{0}k)+1}^{K}\left(\begin{array}{c}K\\k\end{array}\right)p^k(1-p)^{K-k},
\end{align*}
where $\text{int}(a)$ is the greatest integer larger or equal to $a$ and $0\leq C_0\leq 1$.
In order to use this formula, we simply have to choose a test.
Let's choose the two-sided t-test of a zero treatment effect in an RCT with equal tozes for treated and control groups.
In that case, $p$ is simply the power of the test.
In Chapter \@ref(Power), we have derived a formula for the power of this test when $N$ is large:
\begin{align*}
\kappa & = \Phi\left(\frac{\beta_A}{\sqrt{\var{\hat{E}}}}-\Phi^{-1}\left(1-\frac{\alpha}{2}\right)\right),
\end{align*}
with $\var{\hat{E}}=\frac{C(\hat{E})}{N}$ and $C(\hat{E})$ the variance of the estimator across sampling replications.
Let's make the simplifying assumption that the treatment effect is constant, so that the variance of the estimator is basically the variance of the outcomes.
Let's also assume that we are working with effect sizes, so that our outcomes are normalized to have mean zero and variance one.
Under these assumptions, $C(\hat{E})=1$ and we can implement the power formula:
```{r VoteCounting,eval=TRUE,echo=TRUE,results=FALSE,warning=FALSE,error=FALSE,message=FALSE,fig.cap='Detection probability of the vote counting rule',fig.subcap=c("$\\beta_A=0.1$","$\\beta_A=0.2$"),fig.align='center', out.width="50%", fig.pos='htbp', fig.height=8, fig.width=12}
PowerTwoside <- function(betaA,alpha,N,CE=1){
return(pnorm(-betaA/sqrt(CE/N)-qnorm(1-alpha/2))+pnorm(betaA/sqrt(CE/N)-qnorm(1-alpha/2)))
}
PowerTwosideStudent <- function(betaA,alpha,N,CE=1){
return(pt(-betaA/sqrt(CE/N)-qnorm(1-alpha/2),df=N-1)+pt(betaA/sqrt(CE/N)-qnorm(1-alpha/2),df=N-1))
}
VoteCounting <- function(betaA,C0,K,...){
return(pbinom(q=C0*K,size=K,prob=PowerTwosideStudent(betaA=betaA,...),lower.tail = FALSE))
}
PowerTwosideStudent(betaA=0.1,alpha=0.05,N=300)
VoteCounting(C0=.33,K=3000,betaA=0.1,alpha=0.05,N=300)
Sample.size <- c(20,50,100,200,300)
BetaA <- seq(0.1,1.5,by=0.1)
K.list <- c(10,20,30,50,100,1000)
power.vote <- data.frame("Power"= 0,'BetaA'= 0,'N'= 0,'K'= 0)
#power.vote <- sapply(BetaA,VoteCounting,C0=.33,K=K.list[[1]],alpha=0.05,N=Sample.size[[1]])
#power.vote <- cbind(power.vote,BetaA,Sample.size[[1]],K.list[[1]])
for (j in (1:length(K.list))){
for (k in (1:length(Sample.size))){
power.vote.int <- sapply(BetaA,VoteCounting,C0=.33,K=K.list[[j]],alpha=0.05,N=Sample.size[[k]])
power.vote.int <- cbind(power.vote.int,BetaA,Sample.size[[k]],K.list[[j]])
colnames(power.vote.int) <- c('Power','BetaA','N','K')
power.vote <- rbind(power.vote,power.vote.int)
}
}
power.vote <- power.vote[-1,]
power.vote$K.int <- power.vote$K
power.vote$K <- as.factor(power.vote$K)
#ggplot(data=filter(power.vote,K==10),aes(x=N,y=Power,group=as.factor(BetaA),shape=as.factor(BetaA),color=as.factor(BetaA)))+
# geom_line()+
# geom_point()
ggplot(data=filter(power.vote,BetaA==0.1),aes(x=N,y=Power,group=K,shape=K,color=K))+
geom_line()+
geom_point()+
xlab("N (BetaA=0.1)")+
ylab("Detection probability of the vote counting rule")+
theme_bw() +
scale_fill_discrete(name="K")
ggplot(data=filter(power.vote,BetaA==0.2),aes(x=N,y=Power,group=K,shape=K,color=K))+
geom_line()+
geom_point()+
xlab("N (BetaA=0.2)")+
ylab("Detection probability of the vote counting rule")+
theme_bw()
```
Figure \@ref(fig:VoteCounting) shows that the vote counting rule has a very inconvenient property: when the power of the test is lower than 33\%, the probability that the vote counting rule detects a true effect decreases with the number of studies included in the meta-analysis, and converges to zero when the number of studies gets large.
For example, when $N=100$ and $\beta_A=0.1$, the probability of detecting the effect using the vote counting method is equal to `r round(select(filter(power.vote,BetaA==0.1,N==100,K==10),Power)[[1]],3)` with $K=10$ studies and decreases to `r round(select(filter(power.vote,BetaA==0.1,N==100,K==20),Power)[[1]],3)` when $K=20$, and `r round(select(filter(power.vote,BetaA==0.1,N==100,K==100),Power)[[1]],3)` when $K=100$.
The pattern is reverse for more powerful studies, such as when $N=300$ and $\beta_A=0.1$ or when $N=100$ and $\beta_A=0.2$.
The intuition for this result is that the vote counting method does not average out the sampling noise in each individual study.
### Meta-analysis when treatment effects are homogeneous: the fixed effects approach {#MetaWA}
The key idea of meta-analysis with fixed effects is to combine the effect size estimates stemming from different studies, weighing them by their relative precision.
```{definition,metaweights,name='Weighted Meta-Analytic Estimator'}
The weighted meta-analytic estimator is
$$
\bar{\theta} = \sum_{k=1}^Nw_k\hat{\theta}_k \text{ with } w_k=\frac{\frac{1}{\hat{\sigma}^2_k}}{\sum_{k=1}^N\frac{1}{\hat{\sigma}^2_k}}.
$$
```
Under some assumptions, the estimator $\bar{\theta}$ converges to the true effect of the treatment.
Let's delineate these assumptions.
```{definition,metahomo,name='Homogeneous Treatment Effect'}
Each $\hat{\theta}_k$ converges to the same treatment effect $\theta$.
```
Assumption \@ref(def:metahomo) imposes that all the studies have been drawn from the same population, where the treatment effect is a constant.
```{definition,metaind,name='Independence of Estimates'}
The $\hat{\theta}_k$ are independent from each other.
```
Assumption \@ref(def:metaind) imposes that all the studies estimates are independent from each other.
That means that they do not share sampling units and that they are not affected by common shocks.
Under these assumptions, we can show two important results.
```{theorem,metafixedcons,name='Consistency of the Weighted Meta-Analytic Estimator'}
Under Assumptions \@ref(def:metahomo) and \@ref(def:metaind), when the sample size of each study goes to infinity, $\bar{\theta}\approx\theta$.
```
```{proof}
The Law of Large Number applied to each sample gives the fact that the estimator is a weighted sum of $\theta$ with weights summing to one.
Hence the result.
```
Theorem \@ref(thm:metafixedcons) says that the error we are making around the true effect of the treatment goes to zero as the sample size in each study decrease.
This is great: aggregating the studies is thus going to get us to the truth.
```{remark}
One interesting question is whether Theorem \@ref(thm:metafixedcons) also holds when the size of the individual studies remains fixed and the number of studies goes to infinity, which seems a more natural way to do asymptotics in a meta-analysis.
I'm pretty sure that is the case.
Indeed, the studies constitute an enormous sample in which we take the average outcomes of the treated on the one hand and of the untreated on the other.
These averages differ from the usual ones in the Law of Large Numbers only by the fact that the weights are not equal to one.
But they (i) are independent from the outcomes and (ii) sum to one.
As a consequence, I'm pretty sure the Law of Large Numbers also apply in this dimension.
```
**<span style="font-variant:small-caps;">Check if this is a consequence of Kolmogorov's Law of Large Numbers.</span>**
```{theorem,metafixeddis,name='Asymptotic Distribution of the Weighted Meta-Analytic Estimator'}
Under Assumptions \@ref(def:metahomo) and \@ref(def:metaind), when the sample size of each study goes to infinity, $\bar{\theta}\stackrel{d}{\rightarrow}\mathcal{N}(\theta,\sigma^2)$, with
$$
\sigma^2 = \frac{1}{\sum_{k=1}^N\frac{1}{\sigma^2_k}}.
$$
```
```{proof}
**<span style="font-variant:small-caps;">To do using the Lindenberg-Levy version of the Central Limit Theorem.</span>**
```
Theorem \@ref(thm:metafixeddis) shows that the distribution of the weighted meta-analytic estimator converges to a normal, which is very convenient in order to compute sampling noise.
In order to obtain an estimator $\hat{\sigma}^2$ of the variance of the meta-analytic estimator, we can simply replace the individual variance terms by their estimates: $\hat{\sigma}_k^2$.
```{remark}
I've taken Theorem \@ref(thm:metafixeddis) from Hedges and Olkin, but I think it is much more interesting and correct when the asymptotics goes in the number of studies.
```
```{remark}
According to Hedges and Olkin, the weighted meta-analytic estimator is the most efficient estimator available.
```
```{r WMAE,eval=TRUE,echo=TRUE,results='hide',warning=FALSE,error=FALSE,message=FALSE}
wmae <- function(theta,sigma2){
return(c(weighted.mean(theta,(1/sigma2)/(sum(1/sigma2))),1/sum(1/sigma2)))
}
```
```{example}
Let's use our meta-analytic estimator to estimate the effect size of our treatment.
```
The estimated treatment effect size with our sample is `r round(wmae(data.meta$ES,data.meta$se.ES^2)[[1]],2)` $\pm$ `r round(qnorm((delta.2+1)/2)*sqrt(wmae(data.meta$ES,data.meta$se.ES^2)[[2]]),2)`.
A very simple way to implement such an estimator in R is to use the `rma` command of the `metafor` package.
```{r metafor.example,eval=TRUE,echo=TRUE,results='markup',warning=FALSE,error=FALSE,message=FALSE}
data.meta$var.ES <- data.meta$se.ES^2
meta.example.FE <- rma(yi = data.meta$ES,vi=data.meta$var.ES,method="FE")
summary(meta.example.FE)
```
As seen above, the `metafor` package yields a meta-analytic estimate of `r round(coef(meta.example.FE),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*summary(meta.example.FE)$se,2)`, as we have found using the weighted meta-analytic estimator.
It is customary to present the results of a meta-analysis using a forest plot.
A forest plows all the individual estimates along with the aggregated estimate.
Figure \@ref(fig:FEforestplot) presents the forest plot for our example using the very convenient `forest` function in the `metafor` package:
```{r FEforestplot,echo=TRUE,warning=FALSE,error=FALSE,message=FALSE,results=FALSE,fig.cap='Example data set: forest plot', fig.align='center', out.width=cst, fig.pos='htbp', fig.height=8, fig.width=12}
forest(meta.example.FE,slab = paste('Study',data.meta$id,sep=' '),xlab='Estimated Meta-analytic Parameter')
```
### Meta-analysis when treatment effects are heterogeneous: the random effects approach
One key assumption that we have just made so far is that of homogeneous treatment effect.
We have worked under the assumption that each study was drawn from the same population, where the treatment effect is a constant.
Why would the treatment effects differ in each study?
1. We do not study exactly the same treatment, but a family of similar treatments.
Each individual study covers a particular iteration of the treatment, each with its idiosyncratic parameterization.
The particular value of the transfer in a Cash Transfer program, or of the conditions to receive it, or the length of payment, whether it is in one time or over some period, might make a difference, for example.
The same is true for Job Training Programs, Payments for Environmental Services, microcredit, graduation programs, nudges, etc.
Actually, most programs that economists study differ from one implementation to the next.
In psychology and medecine, most treatments are accompanied by a rigorous protocol that makes them much more homogeneous.
2. The population on which the treatment is applied varies.
For example, similar Job Training Programs or microcredit initiatives might have very different outcomes depending on the business cycle.
Education interventions might have very different effects depending on the background of the students on which they are tested.
A drug might interact with patients' phenotype and genotype to generate different effects, and the populations from which the experimental samples are drawn do not have to be similar.
As an extreme example, think of a vaccine tested in a population where the prevalence of a disease is null.
The treatment effect is zero.
Now, test the vaccine in a population where the disease is endemic: the treatment effect might be huge.
When each study draws a treatment effect from a distinct population, meta-analysis has to take into account that treatment effects are heterogeneous.
The main consequence of treatment effect heterogeneity is that the weighting approach we have used so far underestimates the uncertainty around the true effect, since it does not acknowledge that there is additional variation within each study.
There are two main ways to account for heterogeneity in meta-analysis:
1. **Random effects** allowing for additional random noise in each study.
2. **Meta-regression** trying to capture the heterogeneity in treatment effects with observed covariates.
In this section, we study the random effects estimator, and the next section will cover the meta-regression estimator.
Before implementing the random effects estimator, we need to decide whether there is heterogeneity in treatment effects or not.
**<span style="font-variant:small-caps;">Generate noise right now and show the plot.</span>**
#### Estimating the heterogeneity of treatment effects
A necessary first step is to estimate the variance in treatment effects that is due to treatment effect heterogeneity, beyond sampling noise.
The observed effect size estimate for a given study $k$ is modelled as follows:
\begin{align*}
\hat{\theta}_k & = \alpha + \epsilon_k + \nu_k,
\end{align*}
where $\epsilon_k$ is due to sampling noise and $\nu_k$ is due to the heterogeneity in effect sizes across sites, while $\alpha$ is the average of the effect size accross all populations.
We denote the variance of $\nu_k$ as $\tau^2$.
$\nu_k$ is the random effect that gives the random effects approach its name.
There are several ways to estimate this variation.
I'm gooing to start with the most intuitive one, Hedges' estimator, and I'll then move on to the other ones available.
I'll conclude with the formal statistical tests used to decide whether treatment effects are heterogeneous or not.
##### Hedges' estimator of treatment effect heterogeneity
Since Hedges, $\tau^2$ is estimated as the residual variance in effect sizes that is not explained by sampling noise.
In order to compute this estimator, first estimate the overall variance in $\hat{\theta}_k$, then estimate the component of the variance due to sampling noise and finally take the difference between the two.
Hedges' estimator of the overall variance in effect sizes is:
\begin{align*}
\hat{\tau}^2 & = \hat{\sigma}^2_{tot}-\hat{\sigma}^2_{\epsilon},
\end{align*}
with
\begin{align*}
\hat{\sigma^2_{tot}} & = \frac{1}{N}\sum_{k=1}^N(\hat{\theta}_k-\bar{\theta}_u)^2\\
\bar{\theta}_u & = \frac{1}{N}\sum_{k=1}^N\hat{\theta}_k \\
\hat{\sigma^2_{\epsilon}} & = \frac{1}{N}\sum_{k=1}^N\hat{\sigma}_k^2.
\end{align*}
```{remark}
Hedges actually uses the unbiased estimator adapted to small samples and thus replaces $N$ by $N-1$ in the first equation.
```
```{example}
Let's compute Hedges' esimator for $\tau^2$ in our numerical example.
```
Let's first define a few functions to compute each part:
```{r hedgestau,echo=TRUE,warning=FALSE,error=FALSE,message=FALSE,results=FALSE}
tau.2 <- function(theta,vartheta){
return(var(theta)-mean(vartheta))
}
tau.2.theta <- tau.2(data.meta$ES,data.meta$se.ES^2)
```
Our estimate of $\tau^2$ in our example is thus `r round(tau.2.theta,2)`.
This estimate is small, suggesting that there is no additional variance in the treatment effects on top of sammling variation, as we know is the case and has already been suggested by the results of the $Q$ statistic.
Let's now create a new sample of effect sizes where we add noise to each estimate stemming not from sampling, but from heterogeneity in treatment effects across sites and studies.
```{r randomshockmeta,echo=TRUE,warning=FALSE,error=FALSE,message=FALSE,results=FALSE}
tau <- c(0.5,1)
set.seed(1234)
data.meta$theta.1 <- data.meta$ES + rnorm(nrow(data.meta),mean=0,sd=tau[[1]])
data.meta$theta.2 <- data.meta$ES + rnorm(nrow(data.meta),mean=0,sd=tau[[2]])
```
I've simulated two new vectors of estimates for $\theta$, both obtained adding a mean-zero normally distributed noise to the initial estimates of $\theta$, one with a standard deviation of `r tau[[1]]` and the other of `r tau[[2]]`.
Let's visualize our two new datasets:
```{r metanoiseplot,eval=TRUE,echo=TRUE,results='hide',warning=FALSE,error=FALSE,message=FALSE,fig.cap='Datasets with treatment effect heterogeneity',fig.subcap=c('initial',paste('$\\tau^2=$',tau[[1]],sep=' '),paste('$\\tau^2=$',tau[[2]],sep=' ')), fig.align='center', out.width="33%", fig.pos='htbp', fig.height=8, fig.width=12}
ggplot(data.meta, aes(x=as.factor(id), y=ES)) +
geom_bar(position=position_dodge(), stat="identity", colour='black') +
geom_errorbar(aes(ymin=ES-qnorm((delta.2+1)/2)*se.ES, ymax=ES+qnorm((delta.2+1)/2)*se.ES), width=.2,position=position_dodge(.9),color='blue') +
geom_hline(aes(yintercept=ES(param)), colour="#990000", linetype="dashed")+
xlab(expression(paste('Studies',tau^2,'=',0,sep=' ')))+
ylab("Effect size")+
theme_bw()+
ylim(-2,2)
ggplot(data.meta, aes(x=as.factor(id), y=theta.1)) +
geom_bar(position=position_dodge(), stat="identity", colour='black') +
geom_errorbar(aes(ymin=theta.1-qnorm((delta.2+1)/2)*se.ES, ymax=theta.1+qnorm((delta.2+1)/2)*se.ES), width=.2,position=position_dodge(.9),color='blue') +
geom_hline(aes(yintercept=ES(param)), colour="#990000", linetype="dashed")+
xlab(expression(paste('Studies',tau^2,'=',tau[[1]],sep=' ')))+
ylab("Effect size")+
theme_bw()+
ylim(-2,2)
ggplot(data.meta, aes(x=as.factor(id), y=theta.2)) +
geom_bar(position=position_dodge(), stat="identity", colour='black') +
geom_errorbar(aes(ymin=theta.2-qnorm((delta.2+1)/2)*se.ES, ymax=theta.2+qnorm((delta.2+1)/2)*se.ES), width=.2,position=position_dodge(.9),color='blue') +
geom_hline(aes(yintercept=ES(param)), colour="#990000", linetype="dashed")+
xlab(expression(paste('Studies',tau^2,'=',tau[[2]],sep=' ')))+
ylab("Effect size")+
theme_bw()+
ylim(-2,2)
```
Let's see now how Hedge's estimator performs:
```{r hedgestaubis,echo=TRUE,warning=FALSE,error=FALSE,message=FALSE,results=FALSE}
tau.2.theta.1 <- tau.2(data.meta$theta.1,data.meta$se.ES^2)
tau.2.theta.2 <- tau.2(data.meta$theta.2,data.meta$se.ES^2)
```
Hedges' estimates of $\tau^2$ in our examples are thus `r round(tau.2.theta.1,2)` and `r round(tau.2.theta.2,2)` respectively, while the true values are, respectively `r tau[[1]]^2` and `r tau[[2]]^2`.
##### Other estimators of treatment effects heterogeneity
$\tau^2$ is a pretty difficult measure of treatment effect heterogeneity to interpret.
That's why other indicators have been built that are easier to interpret.
We are going to review several of them in this section.
The first alternative or complement to $\tau^2$ is Higgin's $I^2$:
\begin{align*}
I^2 & = \frac{Q-(N-1)}{Q}*100
\end{align*}
The interpretation of $I^2$ is pretty straightforward: it is the distance between the actual value of the $Q$ statistic and its value under the null of treatment effect homogeneity (it is equal to the number of studies $N$, with a correction for degress of freedom).
It can also be interpreted as the fraction of the overall variance (remember that $Q$ is the sum of variance ratios) that is not explained by within study sampling noise.
Another complement to $\tau^2$ is $H^2$:
\begin{align*}
H^2 & = \frac{Q}{N-1}
\end{align*}
If $H^2$ is above one, then there is unexplained heterogeneity, again by the fact that $Q$ has mean $N-1$ under the null of treatment effect homogeneity.
Finally, we can also define the Intra Class Correlation ($ICC$), which precisely measures the share of total variance attributable to treatment effect heterogeneity:
\begin{align*}
ICC & = \frac{\tau^2}{\tau^2+S^2}
\end{align*}
Where $S^2$ is the amount of variance due to sampling noise.
An estimator for $S^2$ is:
\begin{align*}
S^2 & = \frac{(N-1)\sum_{k=1}^N\frac{1}{\sigma^2_k}}{(\sum_{k=1}^N\frac{1}{\sigma^2_k})^2-\sum_{k=1}^N(\frac{1}{\sigma^2_k})^2}.
\end{align*}
**<span style="font-variant:small-caps;">I do not understand the formula for $S^2$. Why does it estimate what we want? I'd take the average variance.</span>**
$ICC$ and $I^2$ are related by the following very simple relation: $I^2=ICC*100$.
```{example}
Let's see how these three estimators look like in our example.
The cool thing is that `rma` computes these estimators by default, so that a simple call to `summary()` is going to show them.
The default random effects estimator is `REML`, which is deemed to be the best of them all according to simulations [(Viechtbauer, 2002)](https://journals.sagepub.com/doi/abs/10.3102/10769986030003261).
```
```{r I2H2ICC,eval=TRUE,echo=TRUE,results='markup',warning=FALSE,error=FALSE,message=FALSE}
meta.example.RE.ES <- rma(yi = data.meta$ES,vi=data.meta$var.ES)
meta.example.RE.theta.1 <- rma(yi = data.meta$theta.1,vi=data.meta$var.ES)
meta.example.RE.theta.2 <- rma(yi = data.meta$theta.2,vi=data.meta$var.ES)
tau2.hat <- c(meta.example.RE.ES$tau2,meta.example.RE.theta.1$tau2,meta.example.RE.theta.2$tau2)
I2 <- c(meta.example.RE.theta.1$I2,meta.example.RE.theta.2$I2,meta.example.RE.ES$I2)
H2 <- c(meta.example.RE.theta.1$H2,meta.example.RE.theta.2$H2,meta.example.RE.ES$H2)
# illustration of results returned by summary
summary(meta.example.RE.theta.2)
```
The estimate of $I^2$ in our example is of `r round(I2[[3]],2)` when $\tau^2$ is equal to 0, of `r round(I2[[1]],2)` when $\tau^2$ is equal to `r tau[[1]]^2` and of `r round(I2[[2]],2)` when $\tau^2$ is equal to `r tau[[2]]^2`.
The estimate of $H^2$ in our example is of `r round(H2[[3]],2)` when $\tau^2$ is equal to 0, of `r round(H2[[1]],2)` when $\tau^2$ is equal to `r tau[[1]]^2` and of `r round(H2[[2]],2)` when $\tau^2$ is equal to `r tau[[2]]^2`.
##### Testing for the homogeneity of treatment effects
What can we do in order to test whether there is heterogeneity in treatment effects?
One way is to build an index comparing the usual variation in treatment effects stemming from sampling noise to the one stemming from variation between studies.
If we find that the variation between studies dwarves the variation due to sampling noise in each study, then there is some heterogeneity for sure.
One statistics that does that is the $Q$ statistic where the variation in treatment effects between studies is estimated using the difference between the individual effect size and the average one squared:
\begin{align*}
Q & = \sum_{k=1}^N\frac{(\hat{\theta}_k-\bar{\theta})^2}{\hat{\sigma}^2_k}.
\end{align*}
What is great with the $Q$ statistic is that, under the Null hypothesis that all the treatment effects are equal to the same constant, it is distributed asymptotically as a $\chi^2$ distribution with $N-1$ degrees of freedom, and thus it can directly be used to test for the hypothesis of homogeneous treatment effects.
```{example}
In our example, we have already computed the $Q$ statistic when we have used the `rma` function in the `metafor` package.
In order to access it, we just need to extract it using `meta.example.FE$QE` for the $Q$ statistic and `meta.example.FE$QEp` for its p-value.
```
The $Q$ statistic in our example has value `r round(meta.example.FE$QE,2)`, with associated p-value `r round(meta.example.FE$QEp,2)`.
We end up not rejecting homogeneity, which is correct.
```{remark}
The problem with using test statistics for testing for treatment effect homogeneity is that, when precision increases, we might end up rejecting homogeneity despite the fact that it is there.
```
**<span style="font-variant:small-caps;">Test with $N=10^5$.</span>**
```{remark}
The $\chi^2$ distribution with $k$ degrees of freedom is asymptotically distributed as a normal with mean $k$ and variance $2k$.
So, when $k$ is large, a good rule of thumb for assessing the homogeneity of the treatment effect estimates is to compare the $Q$ statistic to the number of studies.
If it is much larger, homogeneity is probably not guaranteed.
```
#### Random effects models {#sec:RE}
Hedges proposes a new estimator for the average effect of the treatment, an estimator that accounts for the additional noise due to heterogeneous treatment effects accross sites.
```{definition,Hmetaweights,name='Hedges Weighted Meta-Analytic Estimator'}
Hedges weighted meta-analytic estimator for in the presence of random effects is
$$
\bar{\theta}_H = \sum_{k=1}^Nv_k\hat{\theta}_k \text{ with } v_k=\frac{\frac{1}{\hat{\sigma}^2_k+\hat{\tau}^2}}{\sum_{k=1}^N\frac{1}{\hat{\sigma}^2_k+\hat{\tau}^2}}.
$$
```
```{r HWMAE,eval=TRUE,echo=TRUE,results='hide',warning=FALSE,error=FALSE,message=FALSE}
Hwmae <- function(theta,sigma2,tau2){
return(c(weighted.mean(theta,(1/sigma2)/(sum(1/(sigma2+tau2))),1/sum(1/sigma2+tau2))))
}
ES.H.theta.1 <- Hwmae(data.meta$theta.1,data.meta$se.ES^2,tau.2.theta.1)
ES.H.theta.2 <- Hwmae(data.meta$theta.2,data.meta$se.ES^2,tau.2.theta.2)
```
```{example}
Let's see how Hedges estimator performs in our example.
```
Hedges' estimates of the average effect size is equal to `r round(ES.H.theta.1,2)` and `r round(ES.H.theta.2,2)` respectively, while the true value is `r round(ES(param),2)`.
The main problem with Hedges' estimator when treatment effects are heterogeneous is that very large effects for the more precise estimators dramatically affect the estimate.
```{remark}
Hedges' estimate of $\tau^2$ is slightly negative, which is problem, since a variance is always positive.
Other estimators of $\tau^2$ have been proposed in the literature to account for this fact and to respond to various shortcomings of Hedges' approach.
We will present them succinctly since they are part of the `metafor` package.
These other estimators have bames such as .
They are very well described in this [amazing set of slides](http://www.edii.uclm.es/~useR-2013/Tutorials/kovalchik/kovalchik_meta_tutorial.pdf).
Besides Hedges' (denoted 'HE' in R), the other estimators are named:
```
- DerSimonian-Laird ('DL')
- Hunter-Schmidt ('HS')
- Sidik-Jonkman ('SJ')
- Maximum-likelihood ('ML')
- Restricted maximum-likelihood ('REML')
- Empirical Bayes ('EB')
I'll detail how they work later.
**<span style="font-variant:small-caps;">Detail other estimators of tau.</span>**
```{example}
For the moment, let's see how they perform in our numerical example.
```
```{r RandomOthersTau,eval=TRUE,echo=TRUE,results='asis',warning=FALSE,error=FALSE,message=FALSE,fig.cap='Various estimators of $\\tau^2$',fig.align='center', out.width=cst, fig.pos='htbp', fig.height=8, fig.width=12}
estimators <- c("DL", "REML", "HE", "HS", "SJ", "ML", "EB")
meta.example.RE.theta.1.tau2 <- sapply(estimators,function(method){return(rma(yi = data.meta$theta.1,vi=data.meta$var.ES,method=method)$tau2)})
meta.example.RE.theta.2.tau2 <- sapply(estimators,function(method){return(rma(yi = data.meta$theta.2,vi=data.meta$var.ES,method=method)$tau2)})
#meta.example.RE <- sapply(estimators,function(method){return(rma(yi = data.meta$theta.1,vi=data.meta$var.ES,method=method))})
#meta.example.RE.tau2.test <- unlist(lapply(meta.example.RE,'[[','tau2'))
result.RE <- data.frame(Method=rep(estimators,2),tau2hat=c(meta.example.RE.theta.1.tau2,meta.example.RE.theta.2.tau2),tau2=c(rep(tau[[1]]^2,length(estimators)),rep(tau[[2]]^2,length(estimators))))
ggplot(data=result.RE, aes(x=Method, y=tau2hat, fill=as.factor(tau2))) +
geom_bar(stat="identity", position=position_dodge())+
ylim(0,1)
```
We are ready to estimate the overall treatment effect using random effects.
```{r RandomOthersES,eval=TRUE,echo=TRUE,results='asis',warning=FALSE,error=FALSE,message=FALSE,fig.cap='Various estimators of the treatment effect with random effects',fig.align='center', out.width=cst, fig.pos='htbp', fig.height=8, fig.width=12}
estimators <- c("DL", "REML", "HE", "HS", "SJ", "ML", "EB")
meta.example.RE.theta.1.ES <- sapply(estimators,function(method){return(rma(yi = data.meta$theta.1,vi=data.meta$var.ES,method=method)$beta)})
meta.example.RE.theta.2.ES <- sapply(estimators,function(method){return(rma(yi = data.meta$theta.2,vi=data.meta$var.ES,method=method)$beta)})
#meta.example.RE.tau2.test <- unlist(lapply(meta.example.RE,'[[','tau2'))
result.RE$ES.RE <- c(meta.example.RE.theta.1.ES,meta.example.RE.theta.2.ES)
ggplot(data=result.RE, aes(x=Method, y=ES.RE, fill=as.factor(tau2))) +
geom_bar(stat="identity", position=position_dodge())
```
**<span style="font-variant:small-caps;">Add error bars here.</span>**
##### Presenting the results of a random effects meta-analysis
In order to illustrate the results of a random effects meta-analysis, you can first show the forest plot.
Let's see how it works in our example:
```{r RERMAmetafor,eval=TRUE,echo=TRUE,results='hide',warning=FALSE,error=FALSE,message=FALSE,fig.cap='Forest plots with random effects',fig.subcap=c(paste('$\\tau^2=$',0,sep=''),paste('$\\tau^2=$',tau[[1]]^2,sep=''),paste('$\\tau^2=$',tau[[2]]^2,sep='')), fig.align='center', out.width="33%", fig.pos='htbp', fig.height=8, fig.width=12}
forest(meta.example.RE.ES,slab = paste('Study',data.meta$id,sep=' '),xlab=expression(paste('Estimated Meta-analytic Parameter,',tau^2,0,sep=' ')))
forest(meta.example.RE.theta.1,slab = paste('Study',data.meta$id,sep=' '),xlab=expression(paste('Estimated Meta-analytic Parameter,',tau^2,'=','0.25',sep=' ')))
forest(meta.example.RE.theta.2,slab = paste('Study',data.meta$id,sep=' '),xlab=expression(paste('Estimated Meta-analytic Parameter,',tau^2,'=','1',sep=' ')))
```
Another very nice and useful graphical presentation device is a radial (or Galbraith) plot.
It relates the invserse of the standard errors to the effect sizes normalized by their standard errors.
Each data point is also related a radius by the line passing through the origin.
The Radial plot enables to visualize the noise in the dataset, and is especially useful when comparing a fixed and a random effects estimator for the same study.
```{r Radial,eval=TRUE,echo=TRUE,results='hide',warning=FALSE,error=FALSE,message=FALSE,fig.cap=paste('Radial plots with fixed and random effects','$\\tau^2=$',tau[[1]]^2,sep=' '),fig.subcap=c('Fixed effects','Random effects'), fig.align='center', out.width="50%", fig.pos='htbp', fig.height=8, fig.width=12}
meta.example.FE.theta.1 <- rma(yi = data.meta$theta.1,vi=data.meta$var.ES,method="FE")
radial(meta.example.FE.theta.1)
radial(meta.example.RE.theta.1)
```
Figure \@ref(fig:Radial) shows how the mechanics of the fixed effects estimator differs from the mechanics of the random effects one.
In the presence of treatment effect heterogeneity, the fixed effect estimator faces two issues:
1. It gives too much weight to very precise estimators.
The random effects estimator undoes part of this importance by adding $\tau^2$ to the weights of each observation.
2. It overestimates overall precision by ignoring the sampling variance stemming from treatment effect heterogeneity across sites.
The random effects estimator corrects for that by estimating $\tau^2$ and adding it to the estimate of the total variance of the treatment effect.
```{example}
Let's see how big a difference using random versus fixed effects does to the estimation of treatment effects.
```
Let's plot the two forest plots for the example with $\tau=$ `r tau[[1]]^2`.
```{r FEvsRE,eval=TRUE,echo=TRUE,results='hide',warning=FALSE,error=FALSE,message=FALSE,fig.cap=paste('Fixed vs random effects with','$\\tau^2=$',tau[[1]]^2,sep=' '),fig.subcap=c('Fixed effects','Random effects'), fig.align='center', out.width="50%", fig.pos='htbp', fig.height=8, fig.width=12}
forest(meta.example.FE.theta.1,slab = paste('Study',data.meta$id,sep=' '),xlab='Estimated Meta-analytic Parameter')
forest(meta.example.RE.theta.1,slab = paste('Study',data.meta$id,sep=' '),xlab='Estimated Meta-analytic Parameter')
```
Figure \@ref(fig:FEvsRE) clearly shows that the inclusion of $\tau^2$ in the weights and precision estimates makes a huge difference to the meta-analytic estimate.
The fixed effects estimator yields an estimate of our treatment effect of `r round(coef(meta.example.FE.theta.1),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*summary(meta.example.FE.theta.1)$se,2)`.
The random effects estimator yields an estimate of our treatment effect of `r round(coef(meta.example.RE.theta.1),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*summary(meta.example.RE.theta.1)$se,2)`.
With $\tau^2=$ `r tau[[2]]^2`, the random effects estimator yields an estimate of our treatment effect of `r round(coef(meta.example.RE.theta.2),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*summary(meta.example.RE.theta.2)$se,2)`.
Remember that the true effect size of our treatment is `r round(ES(param),2)`.
With $\tau^2=$ `r tau[[2]]^2`, the random effects estimator barely contains the truth in its `r delta.2*100` $\%$ confidence interval.
### Meta-regression
A Meta-regression tries to explain the heterogeneity in treatment effects across studies using observed covariates.
The idea is to identify characteristics of the studies or of the sites that are correlated with how treatment effects vary.
#### The Meta-regression model
The main equation that we want to estimate is as follows [(Raudenbusch, 2009)](https://www.jstor.org/stable/10.7758/9781610441384):
\begin{align}
\hat{\theta}_k & = \mathbf{X}_k \mathbf{\beta} + \epsilon_k + \nu_k,
\end{align}
**<span style="font-variant:small-caps;">Center regressors at the mean?</span>**
where $\mathbf{X}_k$ is a line vector containing the value of the variables suspected to be correlated with treatment effect heterogeneity for study $k$ and $\mathbf{\beta}$ is a column vector of the corresponding coefficients, of the same dimension as $\mathbf{X}_k$.
$\mathbf{X}_k$ contains a $1$ as its first term, so that $\beta_0$, the first component of the vector $\mathbf{\beta}$ measures the effect of the treatment when all other regressors are set to zero.
It might thus be a good idea to set the regressors as deviations around their means if we want $\beta_0$ to capture the average effect of the treatment.
The error term $\epsilon_k$ captures the heterogeneity in estimated effect sizes that is due to sampling noise.
The error term $\nu_k$ captures the heterogeneity in effect sizes across sites that remains after conditioning on $\mathbf{X}_k$.
In addition, it is generally assumed that $\epsilon_k\sim\mathbf{N}(0,\hat{\sigma}^2_k)$ and $\nu_k\sim\mathbf{N}(0,\tau^2)$.
This model is in general called the **mixed effects linear model**.
It contains at the same time fixed effects captured by $\mathbf{X}_k \mathbf{\beta}$ and random effects captured by $\nu_k$.
Setting $\tau^2$ to zero generates a **fixed effects linear model**.
It is possible, as usual, to test for whether $\tau^2$ is null or not, which is a test of whether the added covariates fully capture the heterogeneity in treatment effects across studies.
#### Estimating the meta-regression model
There are at least four ways to estimate the meta-regression model:
1. Weighted Least squares (WLS): mostly used for fixed effects models, where $\tau^2$ is assumed to be zero.
2. Full Maximum Likelihood Estimator (FMLE)
3. Restricted Maximum Likelihood Estimator (RMLE)
4. Method Of Moments (MOM)
##### Weighted Least Squares
The Weighted Least Squares (WLS) estimator imposes that $\tau^2=0$.
It is thus appropriate when we have a fixed effects linear model.
It is also used as a starting point for estimating the other models.
The WLS estimator of $\mathbf{\beta}$ is written as follows:
\begin{align*}
\mathbf{\hat{\beta}}_{WLS} & = \left(\sum_{k=1}^N\frac{1}{\hat{\sigma}^2_k}\mathbf{X}_k'\mathbf{X}_k\right)^{-1}\sum_{k=1}^N\frac{1}{\hat{\sigma}^2_k}\mathbf{X}_k'\hat{\theta}_k.
\end{align*}
The WLS estimator is similar to the standard OLS estimator, except that it gives more weight to mmore precise estimates of the treatment effect.
This is a generalization of the weighted average that we have studied in Section \@ref(MetaWA).
##### Full Maximum Likelihood Estimator
The Full Maximum Likelihood Estimator (FMLE) is also a weighted estimator, but, as the random effects estimator presented in Section \@ref(sec:RE), it uses as weigths not only the precision estimates ($\frac{1}{\hat{\sigma}^2_k}$), but the inverse of the sum of the variance due to sampling noise and the variance due to variation in treatment effects across sites.
In order to make all of this clearer, let's define $\omega_k = \epsilon_k + \nu_k$, and let's denote $\zeta^2_{k}=\hat{\sigma}^2_k+\tau^2$ the variance of $\omega_k$.
The estimatingn equations for the FMLE estimator are:
\begin{align*}
\mathbf{\hat{\beta}}_{FMLE} & = \left(\sum_{k=1}^N\frac{1}{\hat{\zeta}^2_k}\mathbf{X}_k'\mathbf{X}_k\right)^{-1}\sum_{k=1}^N\frac{1}{\hat{\zeta}^2_k}\mathbf{X}_k'\hat{\theta}_k,\\
\hat{\tau}^2_{FMLE} & = \frac{\sum_{k=1}^N\frac{1}{\hat{\zeta}^4_k}\left((\hat{\theta}_k -\mathbf{X}_k\mathbf{\beta})^2-\hat{\sigma}^2_k\right)}{\sum_{k=1}^N\frac{1}{\hat{\zeta}^4_k}}
\end{align*}
where $\hat{\zeta}^2_k$ is an estimate of $\zeta^2_{k}$.
In general, the FEML model is estimated by using a first guess for $\mathbf{\beta}$, for example $\mathbf{\hat{\beta}}_{WLS}$.
Using this first estimate, we can compute a first estimate of $\hat{\tau}^2$ and update the set of weights, and iterate until convergence.
##### Restricted Maximum Likelihood Estimator
The Restricted Maximum Likelihood Estimator (RMLE) is a weigthed estimator that is very similar to the FMLE estimator, except that the estimation procedure focuses on estimating $\tau^2$ first.
As a consequence, the formula for the $\tau^2$ estimator is different:
\begin{align*}
\mathbf{\hat{\beta}}_{RMLE} & = \left(\sum_{k=1}^N\frac{1}{\hat{\zeta}^2_k}\mathbf{X}_k'\mathbf{X}_k\right)^{-1}\sum_{k=1}^N\frac{1}{\hat{\zeta}^2_k}\mathbf{X}_k'\hat{\theta}_k,\\
\hat{\tau}^2_{RMLE} & = \frac{\sum_{k=1}^N\frac{1}{\hat{\zeta}^4_k}\left((\hat{\theta}_k -\mathbf{X}_k\mathbf{\beta})^2-\hat{\sigma}^2_k\right)
+\text{tr}\left[\left(\sum_{k=1}^N\frac{1}{\hat{\zeta}^2_k}\mathbf{X}_k'\mathbf{X}_k\right)^{-1}\sum_{k=1}^N\frac{1}{\hat{\zeta}^2_k}\mathbf{X}_k'\mathbf{X}_k\right]}
{\sum_{k=1}^N\frac{1}{\hat{\zeta}^4_k}}.
\end{align*}
Again, this estimator an be computed in a recursive way, starting with an initial guesstimate for the parameters $\beta$, for example the simple $WLS$ estimator.
##### Method Of Moments (MOM)
The Methods Of Moments estimator (MOM) does not require to assume that the distirbution of $\nu_k$ is normal.
MOM only assumes that the distribution of $\nu_k$ is i.i.d. with mean zero and variance $\tau^2$.
The MOM estimator is a three-step estimator:
1. Estimate $\beta$ using a simple regression that does require knowing $\tau^2$.
2. Estimate $\tau^2$ from the residuals of this regression.
3. Run a Weighted Least Squares regression including the new estimate of $\tau^2$ in the weights.
When the first step uses a simple OLS estimator, we have:
\begin{align*}
\mathbf{\hat{\beta}}_{OLS} & = \left(\sum_{k=1}^N\mathbf{X}_k'\mathbf{X}_k\right)^{-1}\sum_{k=1}^N\mathbf{X}_k'\hat{\theta}_k \\
\hat{\tau}^2_{OLS} & = \frac{RSS-\sum_{k=1}^N\hat{\sigma}^2_k-\text{tr}(S)}{k-p-1},
\end{align*}
where $RSS$ is the Residual Sum of Squares of the OLS regression, $p$ is the number of covariates and:
\begin{align*}
S & = \left(\sum_{k=1}^N\mathbf{X}_k'\mathbf{X}_k\right)^{-1}\sum_{k=1}^N\mathbf{X}_k'\mathbf{X}_k.
\end{align*}
When the first step uses the WLS estimator, we have:
\begin{align*}
\hat{\tau}^2_{WLS} & = \frac{WRSS-(k-p-1)}{\text{tr}(M)},
\end{align*}
where $WRSS$ is the Residual Sum of Squares of the WLS regression and:
\begin{align*}
\text{tr}(M) & = \sum_{k=1}^N\frac{1}{\hat{\sigma}^2_k} -\text{tr}\left(\left(\sum_{k=1}^N\frac{1}{\hat{\sigma}^2_k}\mathbf{X}_k'\mathbf{X}_k\right)^{-1}\sum_{k=1}^N\frac{1}{\hat{\sigma}^4_k}\mathbf{X}_k'\mathbf{X}_k\right).
\end{align*}
#### Estimating sampling noise in the meta-regression model
##### Under homoskedasticity
Under homoskedasticity, we're assuming that the variance of the treatment effect at various sites does not depend on the site characteristics $\mathbf{X}_k$.
In that case, the variance of the estimated coefficients is estimated by:
\begin{align*}
\hat{\text{Var}}_{Homo}(\hat{\mathbf{\beta}}) & = \left(\sum_{k=1}^N\frac{1}{\hat{\sigma}^2_k+\hat{\tau}^2}\mathbf{X}_k'\mathbf{X}_k\right)^{-1}.
\end{align*}
##### Under heteroskedasticity
Under heteroskedasticity, we allow the variance $\tau^2$ to depend on $\mathbf{X}_k$.
One correct estimator under that assumption is the Huber-White sandwich estimator:
\begin{align*}
\hat{\text{Var}}_{HW}(\hat{\mathbf{\beta}}) & = \left(\sum_{k=1}^N\frac{1}{\hat{\sigma}^2_k+\hat{\tau}^2}\mathbf{X}_k'\mathbf{X}_k\right)^{-1}
\sum_{k=1}^N\left(\frac{1}{\hat{\sigma}^2_k+\hat{\tau}^2}\right)^2
\mathbf{X}_k'(\hat{\theta}_k-\mathbf{X}_k\hat{\mathbf{\beta}})^2\mathbf{X}_k
\left(\sum_{k=1}^N\frac{1}{\hat{\sigma}^2_k+\hat{\tau}^2}\mathbf{X}_k'\mathbf{X}_k\right)^{-1}.
\end{align*}
```{example}
Let's see how all of these estimators work in our example.
In order to run a regression, I first need a covariate.
I'm going to use the exact value of the noise that I've added to the regressions, so that I should be able to perfectly capture the heterogeneity in treatment effects.
Let's see how this works.
```
```{r MetaReg,eval=TRUE,echo=TRUE,results='markup',warning=FALSE,error=FALSE,message=FALSE}
# Let me generate the noise as a deviation from the true treatment effect
data.meta$nu.1 <- data.meta$theta.1 - data.meta$ES
data.meta$nu.2 <- data.meta$theta.2 - data.meta$ES
# Let me now run a meta regression
metaReg.example.RE.theta.1.ES <- lapply(estimators,function(method){return(rma(theta.1 ~ nu.1,data=data.meta,vi=data.meta$var.ES,method=method))})
metaReg.example.RE.theta.2.ES <- lapply(estimators,function(method){return(rma(theta.2 ~ nu.2,data=data.meta,vi=data.meta$var.ES,method=method))})
#Let's see what the estimation looks like when we ran an REML regression:
summary(metaReg.example.RE.theta.1.ES[[2]])
```
We can see that the estimated coefficient for the noise is large and almost equal to one, that the estimation of residual inter-site variance becomes zero and that the precision of our estimared treatment effect becomes much greater (since all variance due to site effects has been absorbed by the regressor).
Let's now look at the estimated coefficients.
For that, we are going to use the function `coef(summary())` that extracts a dataframe of the coefficients along with their standard errors.
```{r MetaRegCoef,eval=TRUE,echo=TRUE,results='markup',warning=FALSE,error=FALSE,message=FALSE,fig.cap='Various estimators of Effect Size in a Meta-Regression',fig.align='center', out.width=cst, fig.pos='htbp', fig.height=8, fig.width=12}
list.coef.tot.1 <- lapply(metaReg.example.RE.theta.1.ES,function(res){return(coef(summary(res)))})
list.coef.tot.2 <- lapply(metaReg.example.RE.theta.2.ES,function(res){return(coef(summary(res)))})
list.coef.1 <- unlist(lapply(list.coef.tot.1,'[[',c(1,1)))
list.se.1 <- unlist(lapply(list.coef.tot.1,'[[',c(2,1)))
list.coef.2 <- unlist(lapply(list.coef.tot.2,'[[',c(1,1)))
list.se.2 <- unlist(lapply(list.coef.tot.2,'[[',c(2,1)))
result.Meta <- data.frame(Method=rep(estimators,2),ES.Meta=c(list.coef.1,list.coef.2),se.ES=c(list.se.1,list.se.2),tau2=c(rep(tau[[1]]^2,length(estimators)),rep(tau[[2]]^2,length(estimators))))
ggplot(data=result.Meta, aes(x=Method, y=ES.Meta, group=as.factor(tau2), color=as.factor(tau2))) +
geom_point(stat="identity", position=position_dodge(0.7))+
geom_errorbar(aes(min=ES.Meta-qnorm((1+delta.2)/2)*se.ES,max=ES.Meta+qnorm((1+delta.2)/2)*se.ES),position=position_dodge(0.7),width=0.1)+
geom_hline(aes(yintercept=ES(param)), colour="#990000", linetype="dashed")+
expand_limits(y=0)
```
Figure \@ref(fig:MetaRegCoef) shows that all estimators perform very well and deliver a precise estimate of the true effect.
**<span style="font-variant:small-caps;">I think SJn is the MOM estimator, check that.</span>**
### Constantly updated meta-analysis
Constantly updated meta-analysis performs the meta-analysis in a progressive manner, as the results keep arriving.
This is a very important tool that enables us to aggregate constantly the information coming from different studies.
Moreover, restrospectively, it helps us to assess when we would have reached enough precision so that we could have foregone an additional study.
The way constantly updated meta-analysis works is simply by performing a new meta-analysis each time a new results pops up.
```{example}
Figure \@ref(fig:cumWMAE) shows how constantly updated meta-analysis works in our example.
```
```{r cumWMAE,eval=TRUE,echo=TRUE,results='hide',warning=FALSE,error=FALSE,message=FALSE,fig.cap='Constantly updated meta-analysis',fig.subcap=c('Initial data set','Constantly updated dataset'), fig.align='center', out.width="50%", fig.pos='htbp', fig.height=8, fig.width=12}
cum.wmae.1 <- function(k,theta,sigma2){
return(c(weighted.mean(theta[1:k],(1/sigma2[1:k])/(sum(1/sigma2[1:k]))),1/sum(1/sigma2[1:k])))
}
cum.wmae <- function(theta,sigma2){
return(sapply(1:length(theta),cum.wmae.1,theta=theta,sigma2=sigma2))
}
cum.test <- as.data.frame(t(cum.wmae(data.meta$ES,data.meta$se.ES^2)))
colnames(cum.test) <- c('cum.ES','cum.var')
cum.test$id <- 1:nrow(cum.test)
cum.test$cum.se.ES <- sqrt(cum.test$cum.var)
ggplot(data.meta, aes(x=forcats::fct_rev(as.factor(id)), y=ES)) +
geom_bar(position=position_dodge(), stat="identity", colour='black') +
geom_errorbar(aes(ymin=ES-qnorm((delta.2+1)/2)*se.ES, ymax=ES+qnorm((delta.2+1)/2)*se.ES), width=.2,position=position_dodge(.9),color='blue') +
geom_hline(aes(yintercept=ES(param)), colour="#990000", linetype="dashed")+
xlab("Studies")+
ylab("Initial effect size")+
theme_bw()+
coord_flip()
ggplot(cum.test, aes(x=forcats::fct_rev(as.factor(id)), y=cum.ES)) +
geom_bar(position=position_dodge(), stat="identity", colour='black') +
geom_errorbar(aes(ymin=cum.ES-qnorm((delta.2+1)/2)*cum.se.ES, ymax=cum.ES+qnorm((delta.2+1)/2)*cum.se.ES), width=.2,position=position_dodge(.9),color='blue') +
geom_hline(aes(yintercept=ES(param)), colour="#990000", linetype="dashed")+
xlab("Studies")+
ylab("Cumulative effect size")+
theme_bw()+
coord_flip()
```
Figure \@ref(fig:cumWMAE) shows that combining several imprecise estimates might help you reach the same precision as running a larger experiment.
For instance, cumulating the first 10 studies with a small sample size ($N=$ `r N.sample[[1]]`), the meta-analytic effect is estimated at `r round(select(filter(cum.test,id==10),cum.ES),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*select(filter(cum.test,id==10),cum.se.ES),2)`.
This is very close to the individual estimate obtained from the first estimate with a larger sample size (sample 11 on Figure \@ref(fig:cumWMAE), with $N=$ `r N.sample[[2]]`): `r round(select(filter(data.meta,id==11),ES),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*select(filter(data.meta,id==11),se.ES),2)`.
Both estimates actually have the exact same precision (because they actually have the same sample size).
The same is true when combining the first 17 studies.
The meta-analytic effect is estimated at `r round(select(filter(cum.test,id==17),cum.ES),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*select(filter(cum.test,id==17),cum.se.ES),2)`, while the effect estimated using one unique RCT with a larger sample size (sample 18 on Figure \@ref(fig:cumWMAE), with $N=$ `r N.sample[[3]]`) is `r round(select(filter(data.meta,id==18),ES),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*select(filter(data.meta,id==18),se.ES),2)`.
Finally, the same result occurs when combining the first 19 studies.
The meta-analytic effect is estimated at `r round(select(filter(cum.test,id==19),cum.ES),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*select(filter(cum.test,id==19),cum.se.ES),2)`, while the effect estimated using one unique RCT with a larger sample size (sample 20 on Figure \@ref(fig:cumWMAE), with $N=$ `r N.sample[[4]]`) is `r round(select(filter(data.meta,id==20),ES),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*select(filter(data.meta,id==20),se.ES),2)`.
As a conclusion, constantly updated meta-analysis would have each time delivered the same result than the one found with a much larger study, rendering this additional study almost irrelevant.
This is a very important result: beyond the apparent messiness of the first noisy estimates in Figures \@ref(fig:confintervalESCLT) and \@ref(fig:FEforestplot) lies an order that can be retrieved and made apparent using constantly updated meta-analysis.
Sometimes, the answer is right there in front of our eyes, we just lack the ability to see it.
Constantly updated meta-analysis serves as a binocular to magnify what is there.
Think about how costly it woud be to run a very large study, just to find out that the we did not really need it because we had known the result all along.
```{remark}
Something pretty cool is that I can reproduce Figure \@ref(fig:cumWMAE) using the `metafor` package with much less lines of code.
```
```{r cumWMAEmetafor,eval=TRUE,echo=TRUE,results='hide',warning=FALSE,error=FALSE,message=FALSE,fig.cap='Constantly updated meta-analysis with the `metafor` package',fig.subcap=c('Initial data set','Constantly updated dataset'), fig.align='center', out.width="50%", fig.pos='htbp', fig.height=8, fig.width=12}
forest(meta.example.FE,slab = paste('Study',data.meta$id,sep=' '),xlab='Estimated Meta-analytic Parameter')
cumul.meta.example.FE <- cumul(meta.example.FE, order=data.meta$id)
forest(cumul.meta.example.FE,slab = paste('Study',data.meta$id,sep=' '),xlab='Estimated Meta-analytic Cumulated Parameter')
```
You can also call each of the individual results of the cumulative meta-analysis using `cumul.meta.example.FE$estimate`.
For example, the cumulated effect size after the 10 first studies is equal to `r round(cumul.meta.example.FE$estimate[[10]],2)` $\pm$ `r round(qnorm((delta.2+1)/2)*cumul.meta.example.FE$se[[10]],2)`.
## Publication bias and site selection bias
Up to now, we have made the assumption that a meta-analysis can access the results of **ALL** of the studies conducted on a topic.
Problems appear when the publisehd record does not contain **ALL** of the studies conducted on a topic, but only a non-representative sample of them.
In the first section below, I detail the two main types of biases: publication bias and site selection bias.
In the second section, I present methods that help to detect and correct for publication bias.
In the third section, I present methods tha help to detect and correct for site selection bias.
In the last section, I take a step back and ask whether publication bias can be somehow optimal.
### Sources of publication bias and of site selection bias and Questionable Research Practices
This section explains the sources of publication bias and site selection bias.
I also expalin how they trigger the use of Questionable Research Practices that bias the published record even more.
#### Publication bias
There is publication bias when the eventual publication of the results of a research project depends on the results themselves.
In general, the probability that a result is published increases drastically when the results reach the usual levels of statistical significance.
On the contrary, the probability that a non significant result is published decreases drastically.
**<span style="font-variant:small-caps;">Give evidence of that behavior.</span>**
The reasons for this behavior are pretty well understood: editors and referees consider that only statistically significant results are of scientific interest, and that non significant results bring close to no information on a topic, especially if they are imprecise.
Knowing this, most researchers choose not to invest time in trying to send a paper with a non significant result for publication.
What are the consequences of publishing only statistically significant results?
Well, among imprecisely estimated effects, only the largest ones are going to reach publication, generating a pattern of overestimation of the true treatment effect.
They key trade-off is whether the resulting bias is very large or not.
```{example}
What does publication bias look like in our example?
Let's assume that only statistically significant effects are published.
Would it change our estimate?
In order to see whether that is the case, let's build Figure \@ref(fig:confintervalESCLT) with the addition of fixed effects estimator using all results and using only statistically significant results.
```
```{r PubBias,dependson=c('monte.carlo'),eval=TRUE,echo=TRUE,results='hide',warning=FALSE,error=FALSE,message=FALSE,fig.cap='Illustration of publication bias',fig.subcap=c('All studies', 'Only imprecise studies'), fig.align='center',out.width='33%',fig.pos='htbp',fig.height=8,fig.width=12}
meta.example.FE.pubbias <- rma(yi = data.meta$ES[abs(data.meta$ES/sqrt(data.meta$var.ES))>=qnorm((1+delta.2)/2)],vi=data.meta$var.ES[abs(data.meta$ES/sqrt(data.meta$var.ES))>qnorm((1+delta.2)/2)],method="FE")
meta.example.FE.small <- rma(yi = filter(data.meta,id<=10)$ES,vi=filter(data.meta,id<=10)$var.ES,method="FE")
meta.example.FE.small.pubbias <- rma(yi = filter(data.meta,id<=10)$ES[abs(data.meta$ES/sqrt(data.meta$var.ES))>=qnorm((1+delta.2)/2)],vi=filter(data.meta,id<=10)$var.ES[abs(data.meta$ES/sqrt(data.meta$var.ES))>qnorm((1+delta.2)/2)],method="FE")
meta.example.FE.interm <- rma(yi = filter(data.meta,id<=17)$ES,vi=filter(data.meta,id<=17)$var.ES,method="FE")
meta.example.FE.interm.pubbias <- rma(yi = filter(data.meta,id<=17)$ES[abs(data.meta$ES/sqrt(data.meta$var.ES))>=qnorm((1+delta.2)/2)],vi=filter(data.meta,id<=17)$var.ES[abs(data.meta$ES/sqrt(data.meta$var.ES))>qnorm((1+delta.2)/2)],method="FE")
ggplot(filter(data.meta,id<=10), aes(x=as.factor(id), y=ES)) +
geom_point(position=position_dodge(), stat="identity", colour='blue') +
geom_errorbar(aes(ymin=ES-qnorm((delta.2+1)/2)*se.ES, ymax=ES+qnorm((delta.2+1)/2)*se.ES), width=.2,position=position_dodge(.9),color='blue') +
geom_hline(aes(yintercept=ES(param)), colour="#990000", linetype="dashed")+
geom_hline(aes(yintercept=coef(meta.example.FE.small)), colour="#990000", linetype="dotted")+
geom_hline(aes(yintercept=coef(meta.example.FE.small.pubbias)), colour="green", linetype="dotted")+
xlab("Studies (only small sample size)")+
ylab("Effect size")+
theme_bw()
ggplot(filter(data.meta,id<=17), aes(x=as.factor(id), y=ES)) +
geom_point(position=position_dodge(), stat="identity", colour='blue') +
geom_errorbar(aes(ymin=ES-qnorm((delta.2+1)/2)*se.ES, ymax=ES+qnorm((delta.2+1)/2)*se.ES), width=.2,position=position_dodge(.9),color='blue') +
geom_hline(aes(yintercept=ES(param)), colour="#990000", linetype="dashed")+
geom_hline(aes(yintercept=coef(meta.example.FE.interm)), colour="#990000", linetype="dotted")+
geom_hline(aes(yintercept=coef(meta.example.FE.interm.pubbias)), colour="green", linetype="dotted")+
xlab("Studies (only small and intermediate sample size)")+
ylab("Effect size")+
theme_bw()
ggplot(data.meta, aes(x=as.factor(id), y=ES)) +
geom_point(position=position_dodge(), stat="identity", colour='blue') +
geom_errorbar(aes(ymin=ES-qnorm((delta.2+1)/2)*se.ES, ymax=ES+qnorm((delta.2+1)/2)*se.ES), width=.2,position=position_dodge(.9),color='blue') +
geom_hline(aes(yintercept=ES(param)), colour="#990000", linetype="dashed")+
geom_hline(aes(yintercept=coef(meta.example.FE)), colour="#990000", linetype="dotted")+
geom_hline(aes(yintercept=coef(meta.example.FE.pubbias)), colour="green", linetype="dotted")+
xlab("Studies (all)")+
ylab("Effect size")+
theme_bw()
```
Figure \@ref(fig:PubBias) shows that publication bias can be a sizable problem.
Remember that the true effect that we are trying to estimate is `r round(ES(param),2)`.
When only imprecise studies with small sample size are available, the effect estimated using only the statistically significant studies (actually, the only study that reports a statistically significant result) is equal to `r round(coef(meta.example.FE.small.pubbias),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*summary(meta.example.FE.small.pubbias)$se,2)`, while the effect estimated all the 10 studies with a small sample size is `r round(coef(meta.example.FE.small),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*summary(meta.example.FE.small)$se,2)`.
When studies with small and intermediate sample size are available, the effect estimated using only the statistically significant studies is equal to `r round(coef(meta.example.FE.interm.pubbias),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*summary(meta.example.FE.interm.pubbias)$se,2)`, while the effect estimated all the 17 studies with a small and intermediate sample size is `r round(coef(meta.example.FE.interm),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*summary(meta.example.FE.interm)$se,2)`.
It is only when studies with large and very large sample size are added to the estimation that publication bias is not a problem anymore.
The effect estimated using only the statistically significant studies is equal to `r round(coef(meta.example.FE.pubbias),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*summary(meta.example.FE.pubbias)$se,2)`, while the effect estimated all the studies is `r round(coef(meta.example.FE),2)` $\pm$ `r round(qnorm((delta.2+1)/2)*summary(meta.example.FE)$se,2)`.
As a conclusion of Figure \@ref(fig:PubBias), publication bias biases the true effect by: