| Title: | Visualizing Meta-Analyses with Orchard Plots and Prediction Intervals |
|---|---|
| Description: | Generates prediction intervals and orchard plots for meta-analytic and meta-regression models fitted with the 'metafor' package. Orchard plots augment classic forest plots by displaying individual effect sizes together with group means and their confidence and prediction intervals, providing an enhanced visualization of meta-analytic data for ecology, evolution, and beyond. Methods are described in Nakagawa et al. (2023) <doi:10.1111/2041-210X.14152>. |
| Authors: | Daniel Noble [aut, cre], Shinichi Nakagawa [aut] |
| Maintainer: | Daniel Noble <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 2.2.1 |
| Built: | 2026-07-23 15:54:18 UTC |
| Source: | https://github.com/cran/orchaRd |
Computes the excess kurtosis of a numeric vector using small sample correction.
.calc.kurtosis(x).calc.kurtosis(x)
x |
A numeric vector. |
A numeric value representing the kurtosis estimate or variance.
Computes the skewness of a numeric vector using small sample correction.
.calc.skewness(x).calc.skewness(x)
x |
A numeric vector. |
A numeric value representing the skewness estimate or variance.
Colour blind palette
.colour_blind_palette.colour_blind_palette
An object of class character of length 20.
Computes the natural logarithm of the ratio of between and within group variances as a measure of the magnitude of difference.
.lnM(x1, x2, sd1, sd2, n1, n2).lnM(x1, x2, sd1, sd2, n1, n2)
x1 |
Mean of group 1. |
x2 |
Mean of group 2. |
sd1 |
Standard deviation of group 1. |
sd2 |
Standard deviation of group 2. |
n1 |
Sample size of group 1. |
n2 |
Sample size of group 2. |
The natural logarithm of the ratio of between and within group variances.
Computes the between group mean-squares difference.
.MSb(x1, x2, n1, n2, paired = FALSE).MSb(x1, x2, n1, n2, paired = FALSE)
x1 |
Mean of group 1. |
x2 |
Mean of group 2. |
n1 |
Sample size of group 1. |
n2 |
Sample size of group 2. |
paired |
Logical, whether the samples are paired. Default is FALSE. |
The between group mean-squares difference.
Computes the within group mean-squares difference.
.MSw(sd1, sd2, n1, n2, paired = FALSE).MSw(sd1, sd2, n1, n2, paired = FALSE)
sd1 |
Standard deviation of group 1. |
sd2 |
Standard deviation of group 2. |
n1 |
Sample size of group 1. |
n2 |
Sample size of group 2. |
paired |
Logical, whether the samples are paired. Default is FALSE. |
The within group mean-squares difference.
Converts a Pearson correlation coefficient to Fisher's Zr using the inverse hyperbolic tangent.
.r.to.zr(r).r.to.zr(r)
r |
A numeric vector of Pearson correlation coefficients. |
The Zr-transformed correlation value(s).
Computes a SAFE bootstrap estimate of the effect size and its variance for dependent samples.
.safe_lnM_dep( x1bar, x2bar, sd1, sd2, n, r, min_kept = 2000, chunk_init = 4000, chunk_max = 2e+06, max_draws = Inf, patience_noaccept = 5, seed = 565 ).safe_lnM_dep( x1bar, x2bar, sd1, sd2, n, r, min_kept = 2000, chunk_init = 4000, chunk_max = 2e+06, max_draws = Inf, patience_noaccept = 5, seed = 565 )
x1bar |
Mean of group 1. |
x2bar |
Mean of group 2. |
sd1 |
Standard deviation of group 1. |
sd2 |
Standard deviation of group 2. |
n |
Sample size (assumed equal for both groups). |
r |
Correlation between the two groups. |
min_kept |
Minimum number of accepted bootstrap samples to keep. Default is 2000. |
chunk_init |
Initial chunk size for bootstrap sampling. Default is 4000. |
chunk_max |
Maximum chunk size for bootstrap sampling. Default is 2e6. |
max_draws |
Maximum total number of bootstrap draws. Default is Inf. |
patience_noaccept |
Number of consecutive chunks with no accepted samples before stopping. Default is 5. |
seed |
Random seed for reproducibility. Default is 565. |
A list containing the point estimate, variance, number of kept samples, total draws, number of attempts, and status.
Computes a SAFE bootstrap estimate of the effect size and its variance for independent samples.
.safe_lnM_indep( x1bar, x2bar, sd1, sd2, n1, n2, min_kept = 2000, chunk_init = 4000, chunk_max = 2e+06, max_draws = Inf, patience_noaccept = 5, seed = 565 ).safe_lnM_indep( x1bar, x2bar, sd1, sd2, n1, n2, min_kept = 2000, chunk_init = 4000, chunk_max = 2e+06, max_draws = Inf, patience_noaccept = 5, seed = 565 )
x1bar |
Mean of group 1. |
x2bar |
Mean of group 2. |
sd1 |
Standard deviation of group 1. |
sd2 |
Standard deviation of group 2. |
n1 |
Sample size of group 1. |
n2 |
Sample size of group 2. |
min_kept |
Minimum number of accepted bootstrap samples to keep. Default is 2000. |
chunk_init |
Initial chunk size for bootstrap sampling. Default is 4000. |
chunk_max |
Maximum chunk size for bootstrap sampling. Default is 2e6. |
max_draws |
Maximum total number of bootstrap draws. Default is Inf. |
patience_noaccept |
Number of consecutive chunks with no accepted samples before stopping. Default is 5. |
seed |
Random seed for reproducibility. Default is 565. |
A list containing the point estimate, variance, number of kept samples, total draws, number of attempts, and status.
Computes jackknife estimate and standard error for skewness and kurtosis.
.sv_jack( x, bias.correct = TRUE, return.replicates = FALSE, type = c("skew", "kurt") ).sv_jack( x, bias.correct = TRUE, return.replicates = FALSE, type = c("skew", "kurt") )
x |
A numeric vector. |
bias.correct |
Logical, whether to apply bias correction. Default is TRUE. |
return.replicates |
Logical, whether to return jackknife replicates. Default is FALSE. |
type |
Character, either "skew" or "kurt" to specify the type of statistic. |
A list with estimate ('est'), bias-corrected estimate ('est_bc'), variance, and standard error.
Computes the sampling variance of the natural logarithm of the ratio of between and within group variances.
.v_lnM(x1, x2, sd1, sd2, n1, n2, r = NULL).v_lnM(x1, x2, sd1, sd2, n1, n2, r = NULL)
x1 |
Mean of group 1. |
x2 |
Mean of group 2. |
sd1 |
Standard deviation of group 1. |
sd2 |
Standard deviation of group 2. |
n1 |
Sample size of group 1. |
n2 |
Sample size of group 2. |
r |
Optional correlation between groups for dependent samples. Default is NULL for independent samples. |
The sampling variance of the natural logarithm of the ratio of between and within group variances.
Computes the approximate sampling variance of Fisher's Zr given a sample size.
.zr.variance(n).zr.variance(n)
n |
Sample size (must be greater than 3). |
The variance of the Zr-transformed correlation.
Using a metafor model object of class rma or rma.mv, a results table of class orchard, or a raw data.frame, the bubble_plot function creates a bubble plot from slope estimates or raw effect sizes. When a raw data.frame is provided, only the data points are plotted (no model fit lines). In cases when a model includes interaction terms, this function creates panels of bubble plots.
bubble_plot( object, mod, group = NULL, xlab = "Moderator", ylab = "Effect size", N = NULL, alpha = 0.5, cb = TRUE, k = TRUE, g = FALSE, transfm = c("none", "tanh", "invlogit", "percent", "percentr"), n_transfm = NULL, est.lwd = 1, ci.lwd = 0.5, pi.lwd = 0.5, est.col = "black", ci.col = "black", pi.col = "black", point.size = c(1, 3.5), legend.pos = c("top.left", "top.right", "bottom.right", "bottom.left", "top.out", "bottom.out", "none"), k.pos = c("top.right", "top.left", "bottom.right", "bottom.left", "none"), condition.nrow = 2, condition.order = NULL, weights = "prop", by = NULL, at = NULL, yi = NULL, vi = NULL, stdy = NULL )bubble_plot( object, mod, group = NULL, xlab = "Moderator", ylab = "Effect size", N = NULL, alpha = 0.5, cb = TRUE, k = TRUE, g = FALSE, transfm = c("none", "tanh", "invlogit", "percent", "percentr"), n_transfm = NULL, est.lwd = 1, ci.lwd = 0.5, pi.lwd = 0.5, est.col = "black", ci.col = "black", pi.col = "black", point.size = c(1, 3.5), legend.pos = c("top.left", "top.right", "bottom.right", "bottom.left", "top.out", "bottom.out", "none"), k.pos = c("top.right", "top.left", "bottom.right", "bottom.left", "none"), condition.nrow = 2, condition.order = NULL, weights = "prop", by = NULL, at = NULL, yi = NULL, vi = NULL, stdy = NULL )
object |
Model object of class |
mod |
The name of a continuous moderator, to be plotted on the x-axis of the bubble plot. |
group |
The grouping variable that one wishes to plot beside total effect sizes, k. This could be study, species, or any grouping variable one wishes to present sample sizes for. Not needed if an |
xlab |
Moderator label. |
ylab |
Effect size measure label. |
N |
The vector of sample size which an effect size is based on. Defaults to precision (the inverse of sampling standard error). |
alpha |
The level of transparency for pieces of fruit (effect size). |
cb |
If |
k |
If |
g |
If |
transfm |
If set to |
n_transfm |
The vector of sample sizes for each effect size estimate. This is used when |
est.lwd |
Size of the point estimate. |
ci.lwd |
Size of the confidence interval. |
pi.lwd |
Size of the prediction interval. |
est.col |
Colour of the point estimate. |
ci.col |
Colour of the confidence interval. |
pi.col |
Colour of the prediction interval. |
point.size |
Numeric vector of length 2, specifying the minimum and maximum point sizes for effect size bubbles. Defaults to |
legend.pos |
Where to place the legend, or not to include a legend ("none"). |
k.pos |
The position of effect size number, k. |
condition.nrow |
Number of rows to plot condition variable. |
condition.order |
Order of the levels of the condition variable in the plot. Defaults to NULL. |
weights |
How to marginalize categorical variables; used when one wants marginalised means. The default is |
by |
Character vector indicating the name that predictions should be conditioned on for the levels of the moderator. |
at |
List of levels one wishes to predict at for the corresponding variables in |
yi |
Character string. The name of the effect size column in the data.frame. Only used when |
vi |
Character string. The name of the sampling variance column in the data.frame. Only used when |
stdy |
Character string. The name of the study identifier column in the data.frame, used for computing k and g labels. Only used when |
Bubble plot
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
data(lim) lim[, "year"] <- as.numeric(lim$year) lim$vi <- 1 / (lim$N - 3) model <- metafor::rma.mv( yi = yi, V = vi, mods = ~ Environment * year, random = list(~ 1 | Article, ~ 1 | Datapoint), data = na.omit(lim) ) test <- orchaRd::mod_results( model, mod = "year", group = "Article", data = lim, weights = "prop", by = "Environment") orchaRd::bubble_plot( test, mod = "year", group = "Article", legend.pos = "top.left") # Or just using model directly orchaRd::bubble_plot( model, mod = "year", legend.pos = "top.left", group = "Article", weights = "prop", by = "Environment")data(lim) lim[, "year"] <- as.numeric(lim$year) lim$vi <- 1 / (lim$N - 3) model <- metafor::rma.mv( yi = yi, V = vi, mods = ~ Environment * year, random = list(~ 1 | Article, ~ 1 | Datapoint), data = na.omit(lim) ) test <- orchaRd::mod_results( model, mod = "year", group = "Article", data = lim, weights = "prop", by = "Environment") orchaRd::bubble_plot( test, mod = "year", group = "Article", legend.pos = "top.left") # Or just using model directly orchaRd::bubble_plot( model, mod = "year", legend.pos = "top.left", group = "Article", weights = "prop", by = "Environment")
Using a metafor model object of class rma or rma.mv or a results table of class orchard, this function produces a caterpillar plot from mean effect size estimates for all levels of a given categorical moderator, their corresponding confidence intervals, and prediction intervals.
caterpillars( object, mod = "1", group, xlab, overall = TRUE, transfm = c("none", "tanh", "invlogit", "percent", "percentr", "inv_ft"), n_transfm = NULL, colerrorbar = "#00CD00", colpoint = "#FFD700", colpoly = "red", k = TRUE, g = TRUE, at = NULL, by = NULL, weights = "prop" )caterpillars( object, mod = "1", group, xlab, overall = TRUE, transfm = c("none", "tanh", "invlogit", "percent", "percentr", "inv_ft"), n_transfm = NULL, colerrorbar = "#00CD00", colpoint = "#FFD700", colpoly = "red", k = TRUE, g = TRUE, at = NULL, by = NULL, weights = "prop" )
object |
Model object of class |
mod |
The name of a moderator variable. Otherwise, "1" for an intercept-only model. |
group |
The grouping variable that one wishes to plot beside total effect sizes, k. This could be study, species, or whatever other grouping variable one wishes to present sample sizes for. |
xlab |
The effect size measure label. |
overall |
Logical, indicating whether to re-label "Intrcpt" (the default label from |
transfm |
If set to |
n_transfm |
The vector of sample sizes for each effect size estimate. This is used when |
colerrorbar |
Colour of the error bar in the caterpillars plot. Defaults to hex code - "#00CD00". |
colpoint |
Point estimate colour in the caterpillars plot. Defaults to hex code - "#FFD700". |
colpoly |
Polygon colour in the caterpillars plot. Defaults to "red". |
k |
If |
g |
If |
at |
Used when one wants marginalised means. List of levels one wishes to predict at for the corresponding variables in |
by |
Used when one wants marginalised means. Character vector indicating the name that predictions should be conditioned on for the levels of the moderator. |
weights |
Used when one wants marginalised means. How to marginalize categorical variables. The default is |
Caterpillars plot
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
data(eklof) eklof<-metafor::escalc(measure="ROM", n1i=N_control, sd1i=SD_control, m1i=mean_control, n2i=N_treatment, sd2i=SD_treatment, m2i=mean_treatment, data=eklof) # Add the unit level predictor eklof$Datapoint<-as.factor(seq(1, dim(eklof)[1], 1)) # fit a MLMR - accouting for some non-independence eklof_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~ Grazer.type-1, random=list(~1|ExptID, ~1|Datapoint), data=eklof) results <- mod_results(eklof_MR, mod = "Grazer.type", group = "First.author") caterpillars(results, mod = "Grazer.type", group = "First.author", xlab = "log(Response ratio) (lnRR)", g = FALSE) # Example 2 data(lim) lim$vi<- 1/(lim$N - 3) lim_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~Phylum-1, random=list(~1|Article, ~1|Datapoint), data=lim) results_lim <- mod_results(lim_MR, mod = "Phylum", group = "Article") caterpillars(results_lim, mod = "Phylum", group = "Article", xlab = "Correlation coefficient", transfm = "tanh")data(eklof) eklof<-metafor::escalc(measure="ROM", n1i=N_control, sd1i=SD_control, m1i=mean_control, n2i=N_treatment, sd2i=SD_treatment, m2i=mean_treatment, data=eklof) # Add the unit level predictor eklof$Datapoint<-as.factor(seq(1, dim(eklof)[1], 1)) # fit a MLMR - accouting for some non-independence eklof_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~ Grazer.type-1, random=list(~1|ExptID, ~1|Datapoint), data=eklof) results <- mod_results(eklof_MR, mod = "Grazer.type", group = "First.author") caterpillars(results, mod = "Grazer.type", group = "First.author", xlab = "log(Response ratio) (lnRR)", g = FALSE) # Example 2 data(lim) lim$vi<- 1/(lim$N - 3) lim_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~Phylum-1, random=list(~1|Article, ~1|Datapoint), data=lim) results_lim <- mod_results(lim_MR, mod = "Phylum", group = "Article") caterpillars(results_lim, mod = "Phylum", group = "Article", xlab = "Correlation coefficient", transfm = "tanh")
Computes the difference in correlation coefficients between two groups along with associated sampling variance for meta-analysis. The correlation and associated sample size or the data frame of the two variables can be provided
cor_diff(cor1 = NULL, cor2 = NULL, n1 = NULL, n2 = NULL, x1 = NULL, x2 = NULL)cor_diff(cor1 = NULL, cor2 = NULL, n1 = NULL, n2 = NULL, x1 = NULL, x2 = NULL)
cor1 |
Numeric, the correlation coefficient for group 1. |
cor2 |
Numeric, the correlation coefficient for group 2. |
n1 |
Integer, the sample size for group 1. |
n2 |
Integer, the sample size for group 2. |
x1 |
A numeric vector for group 1. |
x2 |
A numeric vector for group 2. |
A data frame with the difference in correlations and the sampling variances of the difference.
set.seed(982) # Example with known correlations cor_diff(0.5, 0.3, 100, 100) cor_diff(0.2, 0.4, 40, 40)set.seed(982) # Example with known correlations cor_diff(0.5, 0.3, 100, 100) cor_diff(0.2, 0.4, 40, 40)
CVH1 for mulilevel meta-analytic models, based on Yang et al. (2023). Under multilevel models, we can have multiple CVH1. TODO - we need to cite original CVH1 paper
cvh1_ml(model, boot = NULL)cvh1_ml(model, boot = NULL)
model |
Model object of class |
boot |
Number of simulations to run to produce 95 percent confidence intervals for I2. Default is |
A data frame containing all the model results including mean effect size estimate, confidence, and prediction intervals
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
TODO
library(metafor) # NOTE: boot is set LOW here for speed; use boot >= 1000 in practice. data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) cvh1_ml(english_MA) cvh1_ml(english_MA, boot = 10)library(metafor) # NOTE: boot is set LOW here for speed; use boot >= 1000 in practice. data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) cvh1_ml(english_MA) cvh1_ml(english_MA, boot = 10)
CVH2 for mulilevel meta-analytic models, based on Yang et al. (2023). Under multilevel models, we can have multiple CVH2. TODO - we need to cite original CVH2 paper
cvh2_ml(model, boot = NULL)cvh2_ml(model, boot = NULL)
model |
Model object of class |
boot |
Number of simulations to run to produce 95 percent confidence intervals for I2. Default is |
A data frame containing all the model results including mean effect size estimate, confidence, and prediction intervals
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
TODO
library(metafor) # NOTE: boot is set LOW here for speed; use boot >= 1000 in practice. data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) cvh2_ml(english_MA) cvh2_ml(english_MA, boot = 10)library(metafor) # NOTE: boot is set LOW here for speed; use boot >= 1000 in practice. data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) cvh2_ml(english_MA) cvh2_ml(english_MA, boot = 10)
Eklof et al. (2012) evaluated the effects of predation on benthic invertebrate communities. Using the log response ratio they quantified differences in abundance and/or biomass of gastropods and Amphipods in groups with and without predation in an experimental setting. Below we describe the variables used in our examples and analyses.
A data frame :
Experiment / effect size ID
First author of publication
Year of publication
Journal published within
Research group that data arose from
Type of grazer
Mean abundance/biomass of invertebrates in treatment group
Standard deviation in abundance/biomass of invertebrates in treatment group
Sample size of invertebrate sample in treatment group
Mean abundance/biomass of invertebrates in control group
Standard deviation in abundance/biomass of invertebrates in control group
Sample size of invertebrate sample in control group
...
Eklof J.S., Alsterberg C., Havenhand J.N., Sundback K., Wood H.L., Gamfeldt L. 2012. Experimental climate change weakens the insurance effect of biodiversity. Ecology Letters, 15:864-872. https://doi.org/10.1111/j.1461-0248.2012.01810.x
English and Uller (2016) performed a meta-analysis on the effects of early life dietary restriction (a reduction in a major component of the diet without malnutrition; e.g. caloric restriction) on average age at death, using the standardised mean difference (often called *d*). In a subsequent publication, Senior et al. (2017) analysed this dataset for effects of dietary-restriction on among-individual variation in the age at death using the log coefficient of variation ratio. A major prediction in both English & Uller (2016) and Senior et al. (2017) was that the type of manipulation, whether the study manipulated quality of food versus the quantity of food, would be important.
A data frame :
Study ID
Effect size ID
First author of study
Year of study publication
Research journal where study was published
Common name of species
Phylum of species
Life stage when manipulation was undertaken
Type of food manipulation
Whether species exhibits catchup growth
Sex of organisms in sample
Diet adults were provided and whether it was restricted (treatment) or the control
Sample size of the control group
Sample size of the treatment group
Mean of the control group
Mean of the treatment/experimental group
Standard deviation of the control group
Standard deviation of the treatment/experimental group
...
English S, Uller T. 2016. Does early-life diet affect longevity? A meta-analysis across experimental studies. Biology Letters, 12: http://doi:10.1098/rsbl.2016.0291
Uppercase moderator names
firstup(x, upper = TRUE)firstup(x, upper = TRUE)
x |
a character string |
upper |
logical indicating if the first letter of the character string should be capitalized. Defaults to TRUE. |
Returns a character string with all combinations of the moderator level names with upper case first letters
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
Fish data example.
A data frame
Temperature difference between treatments
Effect size ID
Experimental design type
Group ID
Log Response ratio effect size
Sampling variance for lnRR
Mean for control
Mean for treatment
Sample size for control
Sample size for treatment
Paper ID
SD for control
SD for treatment
Species ID
Type of trait effect size was calculated from
Duration of time developmental treatmemt was applied
Lim J.N., Senior A.M., Nakagawa S. 2014. Heterogeneity in individual quality and reproductive trade-offs within species. Evolution. 68(8):2306-18. doi: 10.1111/evo.12446
This function adds a corrected meta-analytic mean, sensu Nakagawa et al. 2022, confidence interval and text annotation to an intercept only orchard plot.
geom_pub_stats_naka( data, col = "blue", plotadj = -0.05, textadj = 0.05, branch.size = 1.2, trunk.size = 3 )geom_pub_stats_naka( data, col = "blue", plotadj = -0.05, textadj = 0.05, branch.size = 1.2, trunk.size = 3 )
data |
The data frame containing the corrected meta-analytic mean and confidence intervals. |
col |
The colour of the mean and confidence intervals. |
plotadj |
The adjustment to the x-axis position of the mean and confidence intervals. |
textadj |
The adjustment to the y-axis position of the mean and confidence intervals for the text displaying the type of correction. |
branch.size |
Size of the confidence intervals. |
trunk.size |
Size of the mean, or central point. |
A list of ggplot2 objects to be added to the orchard plot.
Daniel Noble - [email protected]
This function adds a corrected meta-analytic mean, sensu Yang et al. 2023, confidence interval and text annotation to an intercept only orchard plot.
geom_pub_stats_yang( data, col = "red", plotadj = -0.05, textadj = 0.05, branch.size = 1.2, trunk.size = 3 )geom_pub_stats_yang( data, col = "red", plotadj = -0.05, textadj = 0.05, branch.size = 1.2, trunk.size = 3 )
data |
The data frame containing the corrected meta-analytic mean and confidence intervals. |
col |
The colour of the mean and confidence intervals. |
plotadj |
The adjustment to the x-axis position of the mean and confidence intervals. |
textadj |
The adjustment to the y-axis position of the mean and confidence intervals for the text displaying the type of correction. |
branch.size |
Size of the confidence intervals. |
trunk.size |
Size of the mean, or central point. |
A list of ggplot2 objects to be added to the orchard plot.
Daniel Noble - [email protected]
Collects and builds the data used to fit the rma.mv or rma model in metafor.
get_data_raw( model, mod, group, N = NULL, at = NULL, subset = TRUE, upper = TRUE )get_data_raw( model, mod, group, N = NULL, at = NULL, subset = TRUE, upper = TRUE )
model |
|
mod |
the moderator variable. |
group |
The grouping variable that one wishes to plot beside total effect sizes, k. This could be study, species, or whatever other grouping variable one wishes to present sample sizes. |
N |
The name of the column in the data specifying the sample size, N. Defaults to |
at |
List of moderators. If |
subset |
Whether or not to subset levels within the |
upper |
Logical indicating if the first letter of the moderator levels should be capitalized. Defaults to |
Returns a data frame
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
data(fish) warm_dat <- fish model <- metafor::rma.mv( yi = lnrr, V = lnrr_vi, random = list(~1 | group_ID, ~1 | es_ID), mods = ~ experimental_design + trait.type + deg_dif + treat_end_days, method = "REML", test = "t", data = warm_dat, control = list(optimizer = "optim", optmethod = "Nelder-Mead")) test <- get_data_raw( model, mod = "trait.type", group = "group_ID", at = list(trait.type = c("physiology", "morphology"))) test2 <- get_data_raw(model, mod = "1", group = "group_ID")data(fish) warm_dat <- fish model <- metafor::rma.mv( yi = lnrr, V = lnrr_vi, random = list(~1 | group_ID, ~1 | es_ID), mods = ~ experimental_design + trait.type + deg_dif + treat_end_days, method = "REML", test = "t", data = warm_dat, control = list(optimizer = "optim", optmethod = "Nelder-Mead")) test <- get_data_raw( model, mod = "trait.type", group = "group_ID", at = list(trait.type = c("physiology", "morphology"))) test2 <- get_data_raw(model, mod = "1", group = "group_ID")
Collects and builds the data used to fit the rma.mv or rma model in metafor when a continuous variable is fit within a model object.
get_data_raw_cont(model, mod, group, N = NULL, by)get_data_raw_cont(model, mod, group, N = NULL, by)
model |
|
mod |
the moderator variable. |
group |
The grouping variable that one wishes to plot beside total effect sizes, k. This could be study, species or whatever other grouping variable one wishes to present sample sizes. |
N |
The name of the column in the data specifying the sample size, N. Defaults to |
by |
Character name(s) of the 'condition' variables to use for grouping into separate tables. |
Returns a data frame
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
This function extracts the corrected meta-analytic mean and confidence intervals from a model object.
get_ints_dat(model, type = c("bc", "br"))get_ints_dat(model, type = c("bc", "br"))
model |
The rma model object containing the corrected meta-analytic mean and confidence intervals. |
type |
The type of correction to extract the corrected meta-analytic mean and confidence intervals from. "br" (i.e., Bias Robust) for Yang et al. 2023, "bc" (i.e., Bias-Corrected) for Nakagawa et al. 2023. |
A list containing the corrected meta-analytic mean and confidence intervals, and a label for the plot.
Daniel Noble - [email protected]
Wraps a fitted glmmTMB model in a light-weight object with class
c("rma.mv", "rma") so it can be passed to orchaRd functions
that operate on metafor model objects. The main use-case is
multilevel meta-analysis fitted with glmmTMB, including models that
use structured covariance terms such as equalto() and
propto().
glmmTMB_to_rma( model, yi, vi, data = NULL, V = NULL, measure = NULL, test = "z", ddf = NULL, study_col = NULL )glmmTMB_to_rma( model, yi, vi, data = NULL, V = NULL, measure = NULL, test = "z", ddf = NULL, study_col = NULL )
model |
A fitted |
yi |
Name of the effect-size column in |
vi |
Name of the sampling-variance column in |
data |
Optional data frame. Defaults to |
V |
Optional known sampling-error variance-covariance matrix. Supply the
same matrix used in |
measure |
Character string labelling the effect-size metric. Stored as an
attribute on |
test |
Either |
ddf |
Optional denominator degrees of freedom used when
|
study_col |
Optional study-level grouping variable used for automatic
|
The returned object is intended for analytical summaries and plotting
functions that only consume the fitted model components. Workflows that
require refitting a metafor model, such as leave_one_out() or
bootstrap paths inside some heterogeneity helpers, are not supported for
converted objects.
A list of class c("rma.mv", "rma") containing the slots that
orchaRd and metafor summary helpers expect.
I2 (I-squared) for mulilevel meta-analytic models, based on Nakagawa & Santos (2012). Under multilevel models, we can have multiple I2 (see also Senior et al. 2016). Alternatively, the method proposed by Wolfgang Viechtbauer can also be used.
i2_ml(model, method = c("ratio", "matrix"), boot = NULL)i2_ml(model, method = c("ratio", "matrix"), boot = NULL)
model |
Model object of class |
method |
Method used to calculate I2. Two options exist: a ratio-based calculation proposed by Nakagawa & Santos ( |
boot |
Number of simulations to run to produce 95 percent confidence intervals for I2. Default is |
A data frame containing all the model results including mean effect size estimate, confidence, and prediction intervals
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
Senior, A. M., Grueber, C. E., Kamiya, T., Lagisz, M., OâDwyer, K., Santos, E. S. A. & Nakagawa S. 2016. Heterogeneity in ecological and evolutionary meta-analyses: its magnitudes and implications. Ecology 97(12): 3293-3299. Nakagawa, S, and Santos, E.S.A. 2012. Methodological issues and advances in biological meta-analysis.Evolutionary Ecology 26(5): 1253-1274.
library(metafor) # NOTE: boot is set LOW here for speed; use boot >= 1000 in practice. data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) i2_ml(english_MA) i2_ml(english_MA, method = "matrix") i2_ml(english_MA, boot = 10)library(metafor) # NOTE: boot is set LOW here for speed; use boot >= 1000 in practice. data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) i2_ml(english_MA) i2_ml(english_MA, method = "matrix") i2_ml(english_MA, boot = 10)
Performs a leave-one-out analysis on a meta-analytic model from the **metafor** package by iteratively removing each level of a grouping variable and refitting the model.
leave_one_out( model, group, vcalc_args = NULL, robust_args = NULL, phylo_args = NULL )leave_one_out( model, group, vcalc_args = NULL, robust_args = NULL, phylo_args = NULL )
model |
A meta-analytic model fitted using **metafor** package functions such as rma.mv(). |
group |
A character string specifying the column name in model$data that contains the grouping variable for which levels will be iteratively removed. |
vcalc_args |
Optional list of arguments for variance-covariance calculation using metafor's vcalc function. Must include:
|
robust_args |
Optional list of arguments for robust variance estimation using metafor's robust function. Must include:
|
phylo_args |
Optional list of arguments for phylogenetic matrix calculation using ape's vcv function. Must include:
|
An object of class "orchard" containing:
mod_table: A data frame with model estimates from each leave-one-out iteration,
with an additional column indicating which group was omitted.
data: A data frame with effect sizes from each iteration, with an additional
column indicating which group was omitted.
orig_mod_results: The results from the original model without any omissions,
as returned by mod_results().
Facundo Decunta - [email protected]
# Subset to a few studies so the leave-one-out refits run quickly fish_sub <- fish[fish$paper_ID %in% unique(fish$paper_ID)[1:5], ] res <- metafor::rma.mv(lnrr, lnrr_vi, random = ~ 1 | paper_ID, data = fish_sub) loo_results <- leave_one_out(res, group = "paper_ID") # With robust variance estimation loo_robust <- leave_one_out(res, group = "paper_ID", robust_args = list(cluster = "paper_ID"))# Subset to a few studies so the leave-one-out refits run quickly fish_sub <- fish[fish$paper_ID %in% unique(fish$paper_ID)[1:5], ] res <- metafor::rma.mv(lnrr, lnrr_vi, random = ~ 1 | paper_ID, data = fish_sub) loo_results <- leave_one_out(res, group = "paper_ID") # With robust variance estimation loo_robust <- leave_one_out(res, group = "paper_ID", robust_args = list(cluster = "paper_ID"))
Lim et al. (2014) meta-analysed the strength of correlation between maternal and offspring size within-species, across a very wide range of taxa. They found that typically there is a moderate positive correlation between maternal size and offspring size within species (i.e. larger mothers have larger offspring). Below we describe the variables use in our examples and analyses.
A data frame :
Amniote group
Study or research paper that data were collected from
Authors of article
Class of organism
Common name of species
Observation level ID that identified each unique datapoint
Environment organism is found, wild or captive
Family of species
Genus of species
Mother length, or mass
Sample size used to estaimted correlation
Order of species
Phylum of the species
Reproductive mode of species
Species name use for phylogenetic reconstruction
year of study
Effect size correlation coefficient between maternal and offspring size within-species
...
Lim J.N., Senior A.M., Nakagawa S. 2014. Heterogeneity in individual quality and reproductive trade-offs within species. Evolution. 68(8):2306-18. doi: 10.1111/evo.12446
M1 for mulilevel meta-analytic models, based on Yang et al. (2023). Under multilevel models, we can have multiple M1 - TODO - we need to cite original M1 paper
m1_ml(model, boot = NULL)m1_ml(model, boot = NULL)
model |
Model object of class |
boot |
Number of simulations to run to produce 95 percent confidence intervals for M1. Default is |
A data frame containing all the model results including mean effect size estimate, confidence, and prediction intervals
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
TODO
library(metafor) # NOTE: boot is set LOW here for speed; use boot >= 1000 in practice. data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) m1_ml(english_MA) m1_ml(english_MA, boot = 10)library(metafor) # NOTE: boot is set LOW here for speed; use boot >= 1000 in practice. data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) m1_ml(english_MA) m1_ml(english_MA, boot = 10)
M2 for mulilevel meta-analytic models, based on Yang et al. (2023). Under multilevel models, we can have multiple M2 - TODO - we need to cite original M2 paper
m2_ml(model, boot = NULL)m2_ml(model, boot = NULL)
model |
Model object of class |
boot |
Number of simulations to run to produce 95 percent confidence intervals for M2. Default is |
A data frame containing all the model results including mean effect size estimate, confidence, and prediction intervals
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
TODO
library(metafor) # NOTE: boot is set LOW here for speed; use boot >= 1000 in practice. data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) m2_ml(english_MA) m2_ml(english_MA, boot = 10)library(metafor) # NOTE: boot is set LOW here for speed; use boot >= 1000 in practice. data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) m2_ml(english_MA) m2_ml(english_MA, boot = 10)
Computes the magnitude effect size and its variance using the SAFE bootstrap method for either independent or dependent samples.
magnitude_effects( x1bar, x2bar, sd1, sd2, n1, n2, min_kept = 2000, chunk_init = 4000, chunk_max = 2e+06, max_draws = Inf, patience_noaccept = 5, paired = FALSE, r = NULL, seed = 565 )magnitude_effects( x1bar, x2bar, sd1, sd2, n1, n2, min_kept = 2000, chunk_init = 4000, chunk_max = 2e+06, max_draws = Inf, patience_noaccept = 5, paired = FALSE, r = NULL, seed = 565 )
x1bar |
Mean of group 1. |
x2bar |
Mean of group 2. |
sd1 |
Standard deviation of group 1. |
sd2 |
Standard deviation of group 2. |
n1 |
Sample size of group 1. |
n2 |
Sample size of group 2. |
min_kept |
Minimum number of accepted bootstrap samples to keep. Default is 2000. |
chunk_init |
Initial chunk size for bootstrap sampling. Default is 4000. |
chunk_max |
Maximum chunk size for bootstrap sampling. Default is 2e6. |
max_draws |
Maximum total number of bootstrap draws. Default is Inf. |
patience_noaccept |
Number of consecutive chunks with no accepted samples before stopping. Default is 5. |
paired |
Logical, whether the samples are paired. Default is FALSE. |
r |
Optional correlation between groups for dependent samples. Required if 'paired' is TRUE. |
seed |
Random seed for reproducibility. Default is 565. |
A list containing the point estimate, variance, number of kept samples, total draws, number of attempts, and status.
# min_kept/chunk_init are set LOW here for speed; use the # defaults for real analyses. # Independent samples magnitude_effects(x1bar = 10, x2bar = 7, sd1 = 2, sd2 = 3, n1 = 30, n2 = 30, min_kept = 200, chunk_init = 400) # Dependent (paired) samples, given the correlation between groups magnitude_effects(x1bar = 10, x2bar = 7, sd1 = 2, sd2 = 3, n1 = 30, n2 = 30, paired = TRUE, r = 0.5, min_kept = 200, chunk_init = 400)# min_kept/chunk_init are set LOW here for speed; use the # defaults for real analyses. # Independent samples magnitude_effects(x1bar = 10, x2bar = 7, sd1 = 2, sd2 = 3, n1 = 30, n2 = 30, min_kept = 200, chunk_init = 400) # Dependent (paired) samples, given the correlation between groups magnitude_effects(x1bar = 10, x2bar = 7, sd1 = 2, sd2 = 3, n1 = 30, n2 = 30, paired = TRUE, r = 0.5, min_kept = 200, chunk_init = 400)
Calculated I2 (I-squared) for mulilevel meta-analytic models, based on a matrix method proposed by Wolfgang Viechtbauer.
matrix_i2(model)matrix_i2(model)
model |
Model object of class |
A named numeric vector of I2 (I-squared) values expressed as percentages. The first element, I2_Total, is the total heterogeneity; each remaining element (named I2_<level> after a random-effect level of the model) is the heterogeneity attributable to that level.
library(metafor) data(english) english <- escalc( measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv( yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) matrix_i2(english_MA)library(metafor) data(english) english <- escalc( measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) english_MA <- rma.mv( yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), data = english) matrix_i2(english_MA)
Calculated CVH1 for mulilevel meta-analytic models
ml_cvh1(model)ml_cvh1(model)
model |
Model object of class |
A named numeric vector of CVH1 values (the coefficient of variation of the heterogeneity, on the standard-deviation scale). The first element, CVH1_Total, is the overall value across all random effects; each remaining element (named CVH1_<level> after a random-effect level of the model) is the value for that level.
Calculated CVH2 for mulilevel meta-analytic models
ml_cvh2(model)ml_cvh2(model)
model |
Model object of class |
A named numeric vector of CVH2 values (the coefficient of variation of the heterogeneity, on the variance scale). The first element, CVH2_Total, is the overall value across all random effects; each remaining element (named CVH2_<level> after a random-effect level of the model) is the value for that level.
Calculated M1 for mulilevel meta-analytic models
ml_m1(model)ml_m1(model)
model |
Model object of class |
A named numeric vector of M1 heterogeneity values (a proportion-type index on the standard-deviation scale, bounded between 0 and 1). The first element, M1_Total, is the overall value across all random effects; each remaining element (named M1_<level> after a random-effect level of the model) is the value for that level.
Calculated CV for mulilevel meta-analytic models
ml_m2(model)ml_m2(model)
model |
Model object of class |
A named numeric vector of M2 heterogeneity values (a proportion-type index on the variance scale, bounded between 0 and 1). The first element, M2_Total, is the overall value across all random effects; each remaining element (named M2_<level> after a random-effect level of the model) is the value for that level.
Using a metafor model object of class rma or rma.mv, this function creates a table of model results containing the mean effect size estimates for all levels of a given categorical moderator, and their corresponding confidence and prediction intervals. The function is capable of calculating marginal means from meta-regression models, including those with multiple moderator variables of mixed types (i.e. continuous and categorical variables).
mod_results( model, mod = "1", group, N = NULL, weights = "prop", by = NULL, at = NULL, subset = FALSE, upper = TRUE, ... )mod_results( model, mod = "1", group, N = NULL, weights = "prop", by = NULL, at = NULL, subset = FALSE, upper = TRUE, ... )
model |
|
mod |
Moderator variable of interest that one wants marginal means for. Defaults to the intercept, i.e. |
group |
The grouping variable that one wishes to plot beside total effect sizes, k. This could be study, species, or any grouping variable one wishes to present sample sizes for. |
N |
The name of the column in the data specifying the sample size so that each effect size estimate is scaled to the sample size, N. Defaults to |
weights |
How to marginalize categorical variables. The default is |
by |
Character vector indicating the name that predictions should be conditioned on for the levels of the moderator. |
at |
List of levels one wishes to predict at for the corresponding variables in |
subset |
Used when one wishes to only plot a subset of levels within the main moderator of interest defined by |
upper |
Logical, defaults to |
... |
Additional arguments passed to |
Prediction intervals with random-slope models (struct = "GEN" or "HCS"):
When your rma.mv model includes a random-slope term (e.g.,
random = ~ moderator | study with struct = "GEN" or
"HCS"), prediction intervals require the full variance-covariance
matrix of the random effects â not just the sum of the variance components.
In a random-slope model the random intercept and slope are typically
correlated, and a correct prediction interval at a given moderator value
x must incorporate:
where and are the random intercept and slope
variances, and is their correlation. Simply summing
tau2, gamma2, and sigma2 ignores the slope variance
contribution and the covariance, producing intervals that may be too narrow
or too wide depending on the moderator value.
metafor::predict.rma() does not currently return prediction intervals
for models with GEN or HCS structures for this reason. orchaRd will
issue a warning when it detects such a structure. Users should verify
prediction intervals manually using the approach described by Pustejovsky
(2024, R-sig-meta-analysis mailing list):
https://stat.ethz.ch/pipermail/r-sig-meta-analysis/2024-March/005152.html.
A practical workaround is to re-centre the moderator at the value of interest (so the random slope term evaluates at zero) and then compare the resulting prediction interval with a manual calculation using the full variance-covariance matrix from the model.
A data frame containing all the model results including mean effect size estimate, confidence and prediction intervals
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
# Simple eklof data data(eklof) eklof<-metafor::escalc(measure="ROM", n1i=N_control, sd1i=SD_control, m1i=mean_control, n2i=N_treatment, sd2i=SD_treatment, m2i=mean_treatment, data = eklof) # Add the unit level predictor eklof$Datapoint<-as.factor(seq(1, dim(eklof)[1], 1)) # fit a MLMR - accouting for some non-independence eklof_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~ Grazer.type, random=list(~1|ExptID, ~1|Datapoint), data = eklof) results <- mod_results(eklof_MR, mod = "Grazer.type", group = "ExptID") # Fish example demonstrating marginalised means data(fish) model <- metafor::rma.mv(yi = lnrr, V = lnrr_vi, random = list(~1 | group_ID, ~1 | es_ID), mods = ~ trait.type + deg_dif, method = "REML", test = "t", data = fish) overall <- mod_results(model, group = "group_ID") across_trait <- mod_results(model, group = "group_ID", mod = "trait.type") # Marginalised means, conditioning on levels of a continuous moderator across_trait_by_deg <- mod_results(model, group = "group_ID", mod = "trait.type", at = list(deg_dif = c(5, 10, 15)), by = "deg_dif")# Simple eklof data data(eklof) eklof<-metafor::escalc(measure="ROM", n1i=N_control, sd1i=SD_control, m1i=mean_control, n2i=N_treatment, sd2i=SD_treatment, m2i=mean_treatment, data = eklof) # Add the unit level predictor eklof$Datapoint<-as.factor(seq(1, dim(eklof)[1], 1)) # fit a MLMR - accouting for some non-independence eklof_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~ Grazer.type, random=list(~1|ExptID, ~1|Datapoint), data = eklof) results <- mod_results(eklof_MR, mod = "Grazer.type", group = "ExptID") # Fish example demonstrating marginalised means data(fish) model <- metafor::rma.mv(yi = lnrr, V = lnrr_vi, random = list(~1 | group_ID, ~1 | es_ID), mods = ~ trait.type + deg_dif, method = "REML", test = "t", data = fish) overall <- mod_results(model, group = "group_ID") across_trait <- mod_results(model, group = "group_ID", mod = "trait.type") # Marginalised means, conditioning on levels of a continuous moderator across_trait_by_deg <- mod_results(model, group = "group_ID", mod = "trait.type", at = list(deg_dif = c(5, 10, 15)), by = "deg_dif")
Computes the effect estimate of the difference in skewness and kurtosis between two groups along with associated sampling variance for meta-analysis.
moment_effects(x1, x2, type = c("skew", "kurt"))moment_effects(x1, x2, type = c("skew", "kurt"))
x1 |
A numeric vector. |
x2 |
A numeric vector. |
type |
Character, either "skew" or "kurt" to specify the type of moment effect. |
A data frame with the difference in moment effects and their variances.
set.seed(982) # Just some random comparisons moment_effects(rnorm(100), rnorm(100), type = "skew") moment_effects(rnorm(40), rnorm(40), type = "skew") moment_effects(rnorm(40), rnorm(40), type = "kurt") moment_effects(rnorm(100), rnorm(100), type = "kurt") # Comparisons with known moment differences m1 <- c(mean = 0, variance = 1, skewness = 0, kurtosis = 2) m2 <- c(mean = 0, variance = 1, skewness = 0, kurtosis = 4) x1 <- PearsonDS::rpearson(1000, moments = m1) x2 <- PearsonDS::rpearson(1000, moments = m2) moment_effects(x1, x2, type = "skew") # ~0 moment_effects(x1, x2, type = "kurt") # ~-2 m1 <- c(mean = 0, variance = 1, skewness = 0, kurtosis = 3) m2 <- c(mean = 0, variance = 1, skewness = 1, kurtosis = 3) x1 <- PearsonDS::rpearson(1000, moments = m1) x2 <- PearsonDS::rpearson(1000, moments = m2) moment_effects(x1, x2, type = "skew") # ~-1 moment_effects(x1, x2, type = "kurt") # ~0set.seed(982) # Just some random comparisons moment_effects(rnorm(100), rnorm(100), type = "skew") moment_effects(rnorm(40), rnorm(40), type = "skew") moment_effects(rnorm(40), rnorm(40), type = "kurt") moment_effects(rnorm(100), rnorm(100), type = "kurt") # Comparisons with known moment differences m1 <- c(mean = 0, variance = 1, skewness = 0, kurtosis = 2) m2 <- c(mean = 0, variance = 1, skewness = 0, kurtosis = 4) x1 <- PearsonDS::rpearson(1000, moments = m1) x2 <- PearsonDS::rpearson(1000, moments = m2) moment_effects(x1, x2, type = "skew") # ~0 moment_effects(x1, x2, type = "kurt") # ~-2 m1 <- c(mean = 0, variance = 1, skewness = 0, kurtosis = 3) m2 <- c(mean = 0, variance = 1, skewness = 1, kurtosis = 3) x1 <- PearsonDS::rpearson(1000, moments = m1) x2 <- PearsonDS::rpearson(1000, moments = m2) moment_effects(x1, x2, type = "skew") # ~-1 moment_effects(x1, x2, type = "kurt") # ~0
Computes how many studies are in each level of categorical moderators of a rma.mv model object.
num_studies(data, mod, group)num_studies(data, mod, group)
data |
Raw data from object of class "orchard" |
mod |
Character string describing the moderator of interest. |
group |
A character string specifying the column name of the study ID grouping variable. |
Returns a table with the number of studies in each level of all parameters within a rma.mv or rma object.
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
data(fish) warm_dat <- fish model <- metafor::rma.mv( yi = lnrr, V = lnrr_vi, random = list(~1 | es_ID, ~1 | group_ID), mods = ~ experimental_design - 1, method = "REML", test = "t", data = warm_dat, control = list(optimizer = "optim", optmethod = "Nelder-Mead")) res <- mod_results(model, mod = "experimental_design", group = "group_ID") num_studies(res$data, moderator, stdy)data(fish) warm_dat <- fish model <- metafor::rma.mv( yi = lnrr, V = lnrr_vi, random = list(~1 | es_ID, ~1 | group_ID), mods = ~ experimental_design - 1, method = "REML", test = "t", data = warm_dat, control = list(optimizer = "optim", optmethod = "Nelder-Mead")) res <- mod_results(model, mod = "experimental_design", group = "group_ID") num_studies(res$data, moderator, stdy)
Plots the output of a leave-one-out analysis for a meta-analytic model. The plot displays the effect sizes, overall effect estimate (with confidence and prediction intervals), and optionally, the effect sizes left out ("ghost points") in each iteration. In addition, the original model's 95% confidence limits are shown as reference lines.
orchard_leave1out( leave1out, ylab = NULL, ci_lines = TRUE, ci_lines_color = "red", ghost_points = TRUE, angle = 0, g = FALSE, transfm = c("none", "tanh", "invlogit", "percent", "percentr"), ... )orchard_leave1out( leave1out, ylab = NULL, ci_lines = TRUE, ci_lines_color = "red", ghost_points = TRUE, angle = 0, g = FALSE, transfm = c("none", "tanh", "invlogit", "percent", "percentr"), ... )
leave1out |
Output from |
ylab |
Optional label for the y-axis, which lists the elements left out. |
ci_lines |
Logical indicating whether to add horizontal reference lines (default is |
ci_lines_color |
Character string specifying the color for the confidence interval lines (default is |
ghost_points |
Logical indicating whether to add "ghost points" for the effect sizes that were left out.
These are plotted as empty points (default is |
angle |
Numeric value specifying the angle of the x-axis labels in degrees (default is 0). |
g |
Logical indicating whether to return the plot as a grob object (default is |
transfm |
Character string specifying the transformation to apply to the data. Options are: "none" (default, no transformation), "tanh" (hyperbolic tangent), "invlogit" (inverse logit), "percent" (percentage), or "percentr" (percentage range). |
... |
Additional arguments passed to |
This function is useful to see how sensitive is the overall effect size estimated by a meta-analytic model to exclusion of each element from a group.
The y-axis shows the elements from the group. For each one, the plot shows the result from the model that left-out that element. For each model, the plot shows the effect sizes, overall effect estimate with confidence and prediction intervals, and "ghost points". This "ghost points" are the effect sizes left out and they are shown as empty points. They can be ommited setting 'ghost_points' to FALSE.
The plot also shows 95 as red dotted lines. The arguments 'ci_lines' and 'ci_lines_color' allow to remove this lines or select their color.
The function internally sets a color palette for the plot. If more than 20 elements are in the group, a viridis
palette is used. Otherwise, a color-blind friendly palette is applied by default.
A ggplot2 object displaying the leave-one-out analysis with reference lines for the original model's confidence limits.
Facundo Decunta - [email protected]
# Subset to a few studies so the leave-one-out refits run quickly fish_sub <- fish[fish$paper_ID %in% unique(fish$paper_ID)[1:5], ] res <- metafor::rma.mv(lnrr, lnrr_vi, random = ~ 1 | paper_ID, data = fish_sub) loo_res <- orchaRd::leave_one_out(res, group = "paper_ID") orchard_leave1out(leave1out = loo_res, xlab = "lnRR")# Subset to a few studies so the leave-one-out refits run quickly fish_sub <- fish[fish$paper_ID %in% unique(fish$paper_ID)[1:5], ] res <- metafor::rma.mv(lnrr, lnrr_vi, random = ~ 1 | paper_ID, data = fish_sub) loo_res <- orchaRd::leave_one_out(res, group = "paper_ID") orchard_leave1out(leave1out = loo_res, xlab = "lnRR")
Using a metafor model object of class rma or rma.mv, or a results table of class orchard, it creates an orchard plot from mean effect size estimates for all levels of a given categorical moderator, and their corresponding confidence and prediction intervals.
orchard_plot( object, mod = "1", group, xlab, N = NULL, alpha = 0.5, angle = 90, cb = TRUE, k = TRUE, g = TRUE, est = FALSE, mod.order = NULL, trunk.size = 0.5, branch.size = 1.2, twig.size = 0.5, point.size = c(1, 3.5), transfm = c("none", "tanh", "invlogit", "percent", "percentr", "inv_ft"), n_transfm = NULL, condition.lab = NULL, legend.pos = c("bottom.right", "bottom.left", "top.right", "top.left", "top.out", "bottom.out", "none"), k.pos = c("right", "left", "none"), k.size = 3.5, est.size = 3, refline.pos = 0, colour = FALSE, fill = TRUE, weights = "prop", by = NULL, at = NULL, upper = TRUE, flip = TRUE )orchard_plot( object, mod = "1", group, xlab, N = NULL, alpha = 0.5, angle = 90, cb = TRUE, k = TRUE, g = TRUE, est = FALSE, mod.order = NULL, trunk.size = 0.5, branch.size = 1.2, twig.size = 0.5, point.size = c(1, 3.5), transfm = c("none", "tanh", "invlogit", "percent", "percentr", "inv_ft"), n_transfm = NULL, condition.lab = NULL, legend.pos = c("bottom.right", "bottom.left", "top.right", "top.left", "top.out", "bottom.out", "none"), k.pos = c("right", "left", "none"), k.size = 3.5, est.size = 3, refline.pos = 0, colour = FALSE, fill = TRUE, weights = "prop", by = NULL, at = NULL, upper = TRUE, flip = TRUE )
object |
model object of class |
mod |
the name of a moderator. Defaults to |
group |
The grouping variable that one wishes to plot beside total effect sizes, k. This could be study, species, or any grouping variable one wishes to present sample sizes for. Not needed if an |
xlab |
The effect size measure label. |
N |
The name of the column in the data specifying the sample size so that each effect size estimate is scaled to the sample size, N. Defaults to |
alpha |
The level of transparency for effect sizes represented in the orchard plot. |
angle |
The angle of y labels. The default is 90 degrees. |
cb |
If |
k |
If |
g |
If |
est |
If |
mod.order |
Order in which to plot the groups of the moderator when it is a categorical one. Should be a vector of equal length to number of groups in the categorical moderator, in the desired order (bottom to top, or left to right for flipped orchard plot) |
trunk.size |
Size of the mean, or central point. |
branch.size |
Size of the confidence intervals. |
twig.size |
Size of the prediction intervals. |
point.size |
Numeric vector of length 2, specifying the minimum and maximum point sizes for effect size bubbles. Defaults to |
transfm |
If set to |
n_transfm |
The vector of sample sizes for each effect size estimate. This is used when |
condition.lab |
Label for the condition being marginalized over. |
legend.pos |
Where to place the legend. To remove the legend, use |
k.pos |
Where to put k (number of effect sizes) on the plot. Users can specify the exact position or they can use specify |
k.size |
Numeric, the font size for k (and g) labels on the plot. Defaults to |
est.size |
Numeric, the font size for estimate and CI labels when |
refline.pos |
Where to put the reference line. defaults to 0. |
colour |
Colour of effect size shapes. By default, effect sizes are colored according to the |
fill |
If |
weights |
Used when one wants marginalised means. How to marginalize categorical variables. The default is |
by |
Character vector indicating the name that predictions should be conditioned on for the levels of the moderator. |
at |
List of levels one wishes to predict at for the corresponding varaibles in 'by'. Used when one wants marginalised means. This argument can also be used to suppress levels of the moderator when argument |
upper |
Logical, defaults to |
flip |
Logical, defaults to |
Orchard plot
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
data(eklof) eklof<-metafor::escalc(measure="ROM", n1i=N_control, sd1i=SD_control, m1i=mean_control, n2i=N_treatment, sd2i=SD_treatment, m2i=mean_treatment, data=eklof) # Add the unit level predictor eklof$Datapoint<-as.factor(seq(1, dim(eklof)[1], 1)) # fit a MLMR - accounting for some non-independence eklof_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~ Grazer.type-1, random=list(~1|ExptID, ~1|Datapoint), data=eklof) results <- mod_results(eklof_MR, mod = "Grazer.type", group = "ExptID") orchard_plot(results, mod = "Grazer.type", group = "ExptID", xlab = "log(Response ratio) (lnRR)") # or orchard_plot(eklof_MR, mod = "Grazer.type", group = "ExptID", xlab = "log(Response ratio) (lnRR)") # Example 2 data(lim) lim$vi<- 1/(lim$N - 3) lim_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~Phylum-1, random=list(~1|Article, ~1|Datapoint), data=lim) orchard_plot(lim_MR, mod = "Phylum", group = "Article", xlab = "Correlation coefficient", transfm = "tanh", N = "N")data(eklof) eklof<-metafor::escalc(measure="ROM", n1i=N_control, sd1i=SD_control, m1i=mean_control, n2i=N_treatment, sd2i=SD_treatment, m2i=mean_treatment, data=eklof) # Add the unit level predictor eklof$Datapoint<-as.factor(seq(1, dim(eklof)[1], 1)) # fit a MLMR - accounting for some non-independence eklof_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~ Grazer.type-1, random=list(~1|ExptID, ~1|Datapoint), data=eklof) results <- mod_results(eklof_MR, mod = "Grazer.type", group = "ExptID") orchard_plot(results, mod = "Grazer.type", group = "ExptID", xlab = "log(Response ratio) (lnRR)") # or orchard_plot(eklof_MR, mod = "Grazer.type", group = "ExptID", xlab = "log(Response ratio) (lnRR)") # Example 2 data(lim) lim$vi<- 1/(lim$N - 3) lim_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~Phylum-1, random=list(~1|Article, ~1|Datapoint), data=lim) orchard_plot(lim_MR, mod = "Phylum", group = "Article", xlab = "Correlation coefficient", transfm = "tanh", N = "N")
Phylogenetic matrix used in Pottier et al. (2021) meta-analysis on sex-differences in acclimation
A phylogenetic correlation matrix :
Pottier et al. 2022. Functional Ecology
Pottier et al. (2021) meta-analysis on sex-differences in acclimation
A data frame :
...
Pottier et al. 2022. Functional Ecology
Function to get prediction intervals (credibility intervals) from esmeans objects (metafor).
pred_interval_esmeans(model, mm, mod, ...)pred_interval_esmeans(model, mm, mod, ...)
model |
|
mm |
result from |
mod |
Moderator of interest. |
... |
other arguments passed to function. |
A data frame built from summary() of the emmeans object: one row per level of the moderator giving the estimated marginal mean and its confidence limits, plus two added columns, lower.PI and upper.PI, containing the lower and upper bounds of the prediction (credibility) interval.
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
Print method for class 'orchard'
## S3 method for class 'orchard' print(x, ...)## S3 method for class 'orchard' print(x, ...)
x |
an R object of class orchard |
... |
Other arguments passed to print |
Returns a data frame
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
This function adds the bias corrected mean and confidence intervals to an existing orchard plot that displays the overall meta-analytic mean effect size.
pub_bias_plot( plot, fe_model, v_model = NULL, col = c("red", "blue"), plotadj = -0.05, textadj = 0.05, branch.size = 1.2, trunk.size = 3 )pub_bias_plot( plot, fe_model, v_model = NULL, col = c("red", "blue"), plotadj = -0.05, textadj = 0.05, branch.size = 1.2, trunk.size = 3 )
plot |
The orchard plot object to add the bias corrected mean and confidence intervals to. This plot needs to be a plot that displays the raw and a single meta-analytic mean (overall mean), confidence interval and prediction interval. |
fe_model |
The meta-analytic model (rma object) produced from a two-step correction (sensu Yang et al. 2023) (Step 1: Fixed effect model) with a robust corretion to correct the meta-analytic mean for publication bias (selection bias) and the dependency in the data. |
v_model |
An optional argument. The meta-analytic model (rma object) to deal with publication bias using the meta-regression approach proposed by Nakagawa et al. 2023. This model can have fixed and/or random effects, with one random effect being sampling error (se or v). The intercept from this model can be considered the corrected meta-analytic mean when sample size is infinite or sampling error is zero. |
col |
The colour of the mean and confidence intervals. |
plotadj |
The adjustment to the x-axis position of the mean and confidence intervals. |
textadj |
The adjustment to the y-axis position of the mean and confidence intervals for the text displaying the type of correction. |
branch.size |
Size of the confidence intervals. |
trunk.size |
Size of the mean, or central point. |
An orchard plot with the corrected meta-analytic mean and confidence intervals added.
Daniel Noble - [email protected]
library(metafor) # Data data(english) # We need to calculate the effect sizes, in this case d english <- escalc( measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) # Our MLMA model english_MA1 <- rma.mv( yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), test = "t", data = english) # Step 1: Fit the fixed effect model english_MA2 <- rma.mv( yi = SMD, V = vSMD, data = english, test = "t") english_MA3 <- rma( yi = SMD, vi = vSMD, data = english, test = "t", method = "FE") # Step 2: Correct for dependency english_MA2_1 <- robust( english_MA2, cluster = english$StudyNo) # Step 3: Testing modified eggers english_MA4 <- rma.mv( yi = SMD, V = vSMD, mod = ~vSMD, random = list(~1 | StudyNo, ~1 | EffectID), test = "t", data = english) # Now plot the results plot <- orchard_plot( english_MA1, group = "StudyNo", xlab = "Standardized Mean Difference") plot2 <- pub_bias_plot(plot, english_MA2_1) plot3 <- pub_bias_plot( plot, english_MA2_1, english_MA4)library(metafor) # Data data(english) # We need to calculate the effect sizes, in this case d english <- escalc( measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names = c("SMD", "vSMD"), data = english) # Our MLMA model english_MA1 <- rma.mv( yi = SMD, V = vSMD, random = list(~1 | StudyNo, ~1 | EffectID), test = "t", data = english) # Step 1: Fit the fixed effect model english_MA2 <- rma.mv( yi = SMD, V = vSMD, data = english, test = "t") english_MA3 <- rma( yi = SMD, vi = vSMD, data = english, test = "t", method = "FE") # Step 2: Correct for dependency english_MA2_1 <- robust( english_MA2, cluster = english$StudyNo) # Step 3: Testing modified eggers english_MA4 <- rma.mv( yi = SMD, V = vSMD, mod = ~vSMD, random = list(~1 | StudyNo, ~1 | EffectID), test = "t", data = english) # Now plot the results plot <- orchard_plot( english_MA1, group = "StudyNo", xlab = "Standardized Mean Difference") plot2 <- pub_bias_plot(plot, english_MA2_1) plot3 <- pub_bias_plot( plot, english_MA2_1, english_MA4)
Calculated R2 (R-squared) for mixed (mulitlevel) models, based on Nakagawa & Schielzeth (2013).
R2_calc(model)R2_calc(model)
model |
Model object of class |
A named numeric vector of length two: R2_marginal, the proportion of variance explained by the fixed effects (moderators) alone, and R2_conditional, the proportion explained by both the fixed and random effects. Values range from 0 to 1.
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
data(lim) lim$vi<-(1/sqrt(lim$N - 3))^2 lim_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~Phylum-1, random=list(~1|Article, ~1|Datapoint), data=lim) R2 <- R2_calc(lim_MR)data(lim) lim$vi<-(1/sqrt(lim$N - 3))^2 lim_MR<-metafor::rma.mv(yi=yi, V=vi, mods=~Phylum-1, random=list(~1|Article, ~1|Datapoint), data=lim) R2 <- R2_calc(lim_MR)
R2 (R-squared) for mixed (mulitlevel) models, based on Nakagawa & Schielzeth (2013).
r2_ml(model, data, boot = NULL)r2_ml(model, data, boot = NULL)
model |
Model object of class |
data |
Data frame used to fit the |
boot |
The number of parametric bootstrap iterations, if desired. Defaults to |
A data frame containing all model results, including: mean effect size estimate, confidence and prediction intervals, with estimates converted back to r.
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
Nakagawa, S, and Schielzeth, H. 2013. A general and simple method for obtaining R2 from generalized linear mixedâeffects models. *Methods in Ecology and Evolution* 4(2): 133-142.
data(lim) lim$vi <- (1/sqrt(lim$N - 3))^2 lim_MR <- metafor::rma.mv( yi = yi, V = vi, mods = ~ Phylum - 1, random = list(~1 | Article, ~1 | Datapoint), data = lim) R2 <- r2_ml(lim_MR, data = lim)data(lim) lim$vi <- (1/sqrt(lim$N - 3))^2 lim_MR <- metafor::rma.mv( yi = yi, V = vi, mods = ~ Phylum - 1, random = list(~1 | Article, ~1 | Datapoint), data = lim) R2 <- r2_ml(lim_MR, data = lim)
I2 (I-squared) for mulilevel meta-analytic models based on Nakagawa & Santos (2012). Under multilevel models, we can have a multiple I2 (see also Senior et al. 2016).
ratio_i2(model)ratio_i2(model)
model |
Model object of class |
A named numeric vector of I2 (I-squared) values expressed as percentages. The first element, I2_Total, is the total heterogeneity; each remaining element (named I2_<level> after a random-effect level of the model) is the heterogeneity attributable to that level.
library(metafor) data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names=c("SMD","vSMD"),data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list( ~ 1 | StudyNo, ~ 1 | EffectID), data = english) ratio_i2(english_MA)library(metafor) data(english) english <- escalc(measure = "SMD", n1i = NStartControl, sd1i = SD_C, m1i = MeanC, n2i = NStartExpt, sd2i = SD_E, m2i = MeanE, var.names=c("SMD","vSMD"),data = english) english_MA <- rma.mv(yi = SMD, V = vSMD, random = list( ~ 1 | StudyNo, ~ 1 | EffectID), data = english) ratio_i2(english_MA)
Merge two model results tables (orchard objects).
submerge(object1, object2, ..., mix = FALSE)submerge(object1, object2, ..., mix = FALSE)
object1 |
object of class |
object2 |
object of class |
... |
Other arguments passed to submerge. |
mix |
If |
Returns a data frame.
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
Sampling error matrix used in Pottier et al. (2021) meta-analysis on sex-differences in acclimation
A sampling variance matrix :
Pottier et al. 2022. Functional Ecology
Calculate weighted variance
weighted_var(x, weights)weighted_var(x, weights)
x |
A vector of tau2s to be averaged |
weights |
Weights, or sample sizes, used to average the variance |
Returns a vector with a single weighted variance
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]
Converts Zr back to r (Pearson's correlation coefficient)
Zr_to_r(df)Zr_to_r(df)
df |
data frame of results of class 'orchard' |
A data frame containing all the model results including mean effect size estimate, confidence and prediction intervals with estimates converted back to r
Shinichi Nakagawa - [email protected]
Daniel Noble - [email protected]