Function to create funnel plots.

funnel(x, ...)

# S3 method for rma
funnel(x, yaxis="sei",
       xlim, ylim, xlab, ylab,
       steps=5, at, atransf, targs, digits, level=x$level,
       addtau2=FALSE, type="rstandard",
       back="lightgray", shade="white", hlines="white",
       refline, lty=3, pch=19, pch.fill=21, col, bg,
       label=FALSE, offset=0.4, legend=FALSE, ci.res=1000, ...)

# S3 method for default
funnel(x, vi, sei, ni, subset, yaxis="sei",
       xlim, ylim, xlab, ylab,
       steps=5, at, atransf, targs, digits, level=95,
       back="lightgray", shade="white", hlines="white",
       refline=0, lty=3, pch=19, col, bg,
       label=FALSE, offset=0.4, legend=FALSE, ci.res=1000, ...)

Arguments

x

an object of class "rma" or a vector with the observed effect sizes or outcomes.

vi

vector with the corresponding sampling variances (needed if x is a vector with the observed effect sizes or outcomes).

sei

vector with the corresponding standard errors (note: only one of the two, vi or sei, needs to be specified).

ni

vector with the corresponding sample sizes. Only relevant when passing a vector via x.

subset

optional (logical or numeric) vector to specify the subset of studies that should be included in the plot. Only relevant when passing a vector via x.

yaxis

either "sei", "vi", "seinv", "vinv", "ni", "ninv", "sqrtni", "sqrtninv", "lni", or "wi" to indicate what values should be placed on the y-axis. See ‘Details’.

xlim

x-axis limits. If unspecified, the function tries to set the x-axis limits to some sensible values.

ylim

y-axis limits. If unspecified, the function tries to set the y-axis limits to some sensible values.

xlab

title for the x-axis. If unspecified, the function tries to set an appropriate axis title.

ylab

title for the y-axis. If unspecified, the function tries to set an appropriate axis title.

steps

the number of tick marks for the y-axis (the default is 5).

at

position of the x-axis tick marks and corresponding labels. If unspecified, the function tries to set the tick mark positions/labels to some sensible values.

atransf

optional argument to specify a function that should be used to transform the x-axis labels (e.g., atransf=exp; see also transf). If unspecified, no transformation is used.

targs

optional arguments needed by the function specified via atransf.

digits

integer to specify the number of decimal places to which the tick mark labels of the x- and y-axis should be rounded. Can also be a vector of two integers, the first to specify the number of decimal places for the x-axis, the second for the y-axis labels (e.g., digits=c(2,3)). If unspecified, the function tries to set the argument to some sensible values.

level

numeric value between 0 and 100 to specify the level of the pseudo confidence interval region (for "rma" objects, the default is to take the value from the object). May also be a vector of values to obtain multiple regions. See ‘Examples’.

addtau2

logical to indicate whether the amount of heterogeneity should be accounted for when drawing the pseudo confidence interval region (the default is FALSE). Ignored when the model includes moderators and residuals are plotted. See ‘Details’.

type

either "rstandard" (default) or "rstudent" to specify whether the usual or deleted residuals should be used in creating the funnel plot when the model involves moderators. See ‘Details’.

back

color to use for the background of the plotting region (default is "lightgray").

shade

color to use for shading the pseudo confidence interval region (default is "white"). When level is a vector of values, different shading colors can be specified for each region.

hlines

color of the horizontal reference lines (default is "white").

refline

numeric value to specify the location of the vertical ‘reference’ line and where the pseudo confidence interval should be centered. If unspecified, the reference line is drawn at the fixed- or random-effects model estimate when the model does not include moderators and at zero when moderators are included (and therefore residuals are plotted) or when directly plotting observed outcomes.

lty

line type for the pseudo confidence interval region and the reference line. The default is to draw dotted lines (see par for other options). Can also be a vector to specify the two line types separately.

pch

plotting symbol to use for the observed outcomes. By default, a filled circle is used. Can also be a vector of values. See points for other options.

pch.fill

plotting symbol to use for the outcomes filled in by the trim and fill method. By default, a circle is used. Only relevant when plotting an object created by the trimfill function.

col

optional character string to specify the name of a color to use for the points ("black" is used by default if not specified). Can also be a vector of color names.

bg

optional character string to specify the name of a background color for open plot symbols ("white" is used by default if not specified). Can also be a vector of color names.

label

argument to control the labeling of the points (the default is FALSE). See ‘Details’.

offset

argument to control the distance between the points and the corresponding labels.

legend

logical to indicate whether a legend should be added to the plot (the default is FALSE). Can also be a keyword to indicate the position of the legend (see legend).

ci.res

integer to specify the number of y-axis values at which to calculate the bounds of the pseudo confidence interval. The default is 1000, which usually provides a sufficient resolution for the plotting.

...

other arguments.

Details

For fixed- and random-effects models (i.e., models not involving moderators), the plot shows the observed effect sizes or outcomes on the x-axis against the corresponding standard errors (i.e., the square root of the sampling variances) on the y-axis. A vertical line indicates the estimate based on the model. A pseudo confidence interval region is drawn around this value with bounds equal to \(\pm 1.96 \mbox{SE}\), where \(\mbox{SE}\) is the standard error value from the y-axis (assuming level=95). If addtau2=TRUE (only for models of class "rma.uni"), then the bounds of the pseudo confidence interval region are equal to \(\pm 1.96 \sqrt{\mbox{SE}^2 + \hat{\tau}^2}\), where \(\hat{\tau}^2\) is the amount of heterogeneity as estimated by the model.

For models involving moderators, the plot shows the residuals on the x-axis against their corresponding standard errors. Either the usual or deleted residuals can be used for that purpose (set via the type argument). See residuals.rma for more details on the different types of residuals.

With the atransf argument, the labels on the x-axis can be transformed with some suitable function. For example, when plotting log odds ratios, one could use transf=exp to obtain a funnel plot with the values on the x-axis corresponding to the odds ratios. See also transf for some other useful transformation functions in the context of a meta-analysis.

Instead of placing the standard errors on the y-axis, several other options are available by setting the yaxis argument to:

  • yaxis="vi" for the sampling variances,

  • yaxis="seinv" for the inverse of the standard errors,

  • yaxis="vinv" for the inverse of the sampling variances,

  • yaxis="ni" for the sample sizes,

  • yaxis="ninv" for the inverse of the sample sizes,

  • yaxis="sqrtni" for the square root of the sample sizes,

  • yaxis="sqrtninv" for the inverse square root of the sample sizes,

  • yaxis="lni" for the log of the sample sizes,

  • yaxis="wi" for the weights.

However, only when yaxis="sei" (the default) will the pseudo confidence region have the expected (upside-down) funnel shape with straight lines. Also, when placing (a function of) the sample sizes on the y-axis or the weights, then the pseudo confidence region cannot be drawn. See Sterne and Egger (2001) for more details on the choice of the y-axis.

If the object passed to the function comes from the trimfill function, the outcomes that are filled in by the trim and fill method are also added to the funnel plot. The symbol to use for plotting the filled in values can be specified via the pch.fill argument.

One can also directly pass a vector with the observed effect sizes or outcomes (via x) and the corresponding sampling variances (via vi), standard errors (via sei), and/or sample sizes (via ni) to the function. By default, the vertical reference line is then drawn at zero.

The arguments back, shade, and hlines can be set to NULL to suppress the shading and the horizontal reference line.

With the label argument, one can control whether points in the plot will be labeled. If label="all" (or label=TRUE), all points in the plot will be labeled. If label="out", points falling outside of the pseudo confidence region will be labeled. Finally, one can also set this argument to a numeric value (between 1 and \(k\)) to specify how many of the most extreme points should be labeled (e.g., with label=1 only the most extreme point would be labeled, while with label=3, the most extreme, and the second and third most extreme points would be labeled). With the offset argument, one can adjust the distance between the labels and the corresponding points.

Note

Placing (a function of) the sample sizes on the y-axis (i.e., using yaxis="ni", yaxis="ninv", yaxis="sqrtni", yaxis="sqrtninv", or yaxis="lni") is only possible when information about the sample sizes is actually stored within the object passed to the funnel function. That should automatically be the case when the observed effect sizes or outcomes were computed with the escalc function or when the observed effect sizes or outcomes were computed within the model fitting function. On the other hand, this will not be the case when rma.uni was used together with the yi and vi arguments and the yi and vi values were not computed with escalc. In that case, it is still possible to pass information about the sample sizes to the rma.uni function (e.g., use rma.uni(yi, vi, ni=ni, data=dat), where data frame dat includes a variable called ni with the sample sizes).

When using unweighted estimation, using yaxis="wi" will place all points on a horizontal line. When directly passing a vector with the observed effect sizes or outcomes to the function, yaxis="wi" is equivalent to yaxis="vinv", except that the weights are expressed in percent.

When specifying vectors for pch, col, and/or bg, the variables specified are assumed to be of the same length as the data passed to the funnel function or the model fitting function (when using funnel on a model object). Any subsetting and removal of studies with missing values is automatically applied to the variables specified via these arguments.

Value

A data frame with components:

x

the x-axis coordinates of the points that were plotted.

y

the y-axis coordinates of the points that were plotted.

slab

the study labels.

Note that the data frame is returned invisibly.

Author

Wolfgang Viechtbauer wvb@metafor-project.org https://www.metafor-project.org

References

Light, R. J., & Pillemer, D. B. (1984). Summing up: The science of reviewing research. Cambridge, MA: Harvard University Press.

Peters, J. L., Sutton, A. J., Jones, D. R., Abrams, K. R., & Rushton, L. (2008). Contour-enhanced meta-analysis funnel plots help distinguish publication bias from other causes of asymmetry. Journal of Clinical Epidemiology, 61(10), 991--996. https://doi.org/10.1016/j.jclinepi.2007.11.010

Sterne, J. A. C., & Egger, M. (2001). Funnel plots for detecting bias in meta-analysis: Guidelines on choice of axis. Journal of Clinical Epidemiology, 54(10), 1046--1055. https://doi.org/10.1016/s0895-4356(01)00377-8

Viechtbauer, W. (2010). Conducting meta-analyses in R with the metafor package. Journal of Statistical Software, 36(3), 1--48. https://doi.org/10.18637/jss.v036.i03

See also

Examples

### copy BCG vaccine data into 'dat' dat <- dat.bcg ### calculate log risk ratios and corresponding sampling variances dat <- escalc(measure="RR", ai=tpos, bi=tneg, ci=cpos, di=cneg, data=dat) ### fit random-effects model res <- rma(yi, vi, data=dat, slab=paste(dat$author, dat$year, sep=", ")) ### draw a standard funnel plot funnel(res)
### show risk ratio values on x-axis (log scale) funnel(res, atransf=exp)
### label points outside of the pseudo confidence interval region funnel(res, atransf=exp, label="out")
### passing log risk ratios and sampling variances directly to the function ### note: same plot, except that reference line is centered at zero funnel(dat$yi, dat$vi)
### can accomplish the same thing by setting refline=0 funnel(res, refline=0)
### adjust the position of the x-axis labels, number of digits, and y-axis limits funnel(res, atransf=exp, at=log(c(.125, .25, .5, 1, 2)), digits=3L, ylim=c(0,.8))
### contour-enhanced funnel plot centered at 0 (see Peters et al., 2008) funnel(res, level=c(90, 95, 99), shade=c("white", "gray55", "gray75"), refline=0, legend=TRUE)
### same, but show risk ratio values on the x-axis and some further adjustments funnel(res, level=c(90, 95, 99), shade=c("white", "gray55", "gray75"), digits=3L, ylim=c(0,.8), refline=0, legend=TRUE, atransf=exp, at=log(c(.125, .25, .5, 1, 2, 4, 8)))
### illustrate the use of vectors for 'pch' and 'col' res <- rma(yi, vi, data=dat, subset=2:10) funnel(res, pch=ifelse(dat$yi > -1, 19, 21), col=ifelse(sqrt(dat$vi) > .3, "red", "blue"))
### can add a second funnel via (undocumented) argument refline2 funnel(res, atransf=exp, at=log(c(.125, .25, .5, 1, 2, 4)), digits=3L, ylim=c(0,.8), refline2=0)
### mixed-effects model with absolute latitude in the model res <- rma(yi, vi, mods = ~ ablat, data=dat) ### funnel plot of the residuals funnel(res)
### simulate a large meta-analytic dataset (correlations with rho = 0.2) ### with no heterogeneity or publication bias; then try out different ### versions of the funnel plot gencor <- function(rhoi, ni) { x1 <- rnorm(ni, mean=0, sd=1) x2 <- rnorm(ni, mean=0, sd=1) x3 <- rhoi*x1 + sqrt(1-rhoi^2)*x2 cor(x1, x3) } set.seed(1234) k <- 200 ### number of studies to simulate ni <- round(rchisq(k, df=2) * 20 + 20) ### simulate sample sizes (skewed distribution) ri <- mapply(gencor, rep(0.2,k), ni) ### simulate correlations res <- rma(measure="ZCOR", ri=ri, ni=ni, method="FE") ### use r-to-z transformed correlations funnel(res, yaxis="sei")
funnel(res, yaxis="vi")
funnel(res, yaxis="seinv")
funnel(res, yaxis="vinv")
funnel(res, yaxis="ni")
funnel(res, yaxis="ninv")
funnel(res, yaxis="sqrtni")
funnel(res, yaxis="sqrtninv")
funnel(res, yaxis="lni")
funnel(res, yaxis="wi")