To run the following script, some packages may need to be installed
from Github
.
# install.packages("devtools")
# install.packages("tidyverse")
# install.packages("metafor")
# install.packages("patchwork")
# install.packages("R.rsp")
#
# devtools::install_github("itchyshin/orchard_plot", subdir = "orchaRd", force = TRUE, build_vignettes = TRUE)
library(metafor)
library(broom)
library(readxl)
library(tidyverse)
library(rmarkdown)
library(kableExtra)
library(orchaRd)
library(patchwork)
library(sjPlot)
library(gridExtra)
library(jtools)
library(ggtext)
library(purrr)
#' @title Covariance and correlation matrix function basing on shared level ID
#' @description Function for generating simple covariance and correlation matrices
#' @param data Dataframe object containing effect sizes, their variance, unique IDs and clustering variable
#' @param V Name of the variable (as a string – e.g, "V1") containing effect size variances variances
#' @param cluster Name of the variable (as a string – e.g, "V1") indicating which effects belong to the same cluster. Same value of 'cluster' are assumed to be nonindependent (correlated).
#' @param obs Name of the variable (as a string – e.g, "V1") containing individual IDs for each value in the V (Vector of variances). If this parameter is missing, label will be labelled with consecutive integers starting from 1.
#' @param rho Known or assumed correlation value among effect sizes sharing same 'cluster' value. Default value is 0.5.
#' @param type Optional logical parameter indicating whether a full variance-covariance matrix (default or "vcv") is needed or a correlation matrix ("cor") for the non-independent blocks of variance values.
#' @export
make_VCV_matrix <- function(data, V, cluster, obs, type=c("vcv", "cor"), rho=0.5){
type <- match.arg(type)
if (missing(data)) {
stop("Must specify dataframe via 'data' argument.")
}
if (missing(V)) {
stop("Must specify name of the variance variable via 'V' argument.")
}
if (missing(cluster)) {
stop("Must specify name of the clustering variable via 'cluster' argument.")
}
if (missing(obs)) {
obs <- 1:length(V)
}
if (missing(type)) {
type <- "vcv"
}
new_matrix <- matrix(0,nrow = dim(data)[1],ncol = dim(data)[1]) #make empty matrix of the same size as data length
rownames(new_matrix) <- data[ ,obs]
colnames(new_matrix) <- data[ ,obs]
# find start and end coordinates for the subsets
shared_coord <- which(data[ ,cluster] %in% data[duplicated(data[ ,cluster]), cluster]==TRUE)
# matrix of combinations of coordinates for each experiment with shared control
combinations <- do.call("rbind", tapply(shared_coord, data[shared_coord,cluster], function(x) t(utils::combn(x,2))))
if(type == "vcv"){
# calculate covariance values between values at the positions in shared_list and place them on the matrix
for (i in 1:dim(combinations)[1]){
p1 <- combinations[i,1]
p2 <- combinations[i,2]
p1_p2_cov <- rho * sqrt(data[p1,V]) * sqrt(data[p2,V])
new_matrix[p1,p2] <- p1_p2_cov
new_matrix[p2,p1] <- p1_p2_cov
}
diag(new_matrix) <- data[ ,V] #add the diagonal
}
if(type == "cor"){
# calculate covariance values between values at the positions in shared_list and place them on the matrix
for (i in 1:dim(combinations)[1]){
p1 <- combinations[i,1]
p2 <- combinations[i,2]
p1_p2_cov <- rho
new_matrix[p1,p2] <- p1_p2_cov
new_matrix[p2,p1] <- p1_p2_cov
}
diag(new_matrix) <- 1 #add the diagonal of 1
}
return(new_matrix)
}
#' @title model_table: univariate rma.mv models
#' @description Function to get estimates, CIs (confidence intervals) from rma objects (metafor) and output into neat table - this one designed for three models at a time
#' @param m1: first rma.mv object
#' @param m2: second rma.mv object
#' @param m3: third rma.mv object
#' @param names: list of names for the "Effect size" column, must be length three and correspond to m1,m2,m3 effect sizes
model_table<-function(m1, m2, m3, names){
#r2 <- r2_ml(model1, model2, model3)
# creating a table
tibble(`Effect size` = names,
`Estimate` = c(m1$b, m2$b, m3$b),
`Lower CI [0.025]` = c(m1$ci.lb, m2$ci.lb, m3$ci.lb),
`Upper CI [0.975]` = c(m1$ci.ub, m2$ci.ub, m3$ci.ub),
`P value` = c(m1$pval, m2$pval, m3$pval)) %>% kable("html", digits = 3) %>%
kable_styling(position = "left")
}
model_table<-function(m1, m2, m3, names){
#r2 <- r2_ml(model1, model2, model3)
# creating a table
tibble(`Effect size` = names,
`Estimate` = c(m1$b, m2$b, m3$b),
`Lower CI [0.025]` = c(m1$ci.lb, m2$ci.lb, m3$ci.lb),
`Upper CI [0.975]` = c(m1$ci.ub, m2$ci.ub, m3$ci.ub),
`P value` = c(m1$pval, m2$pval, m3$pval)) %>% kable("html", digits = 3) %>%
kable_styling(position = "left")
}
get_pred1 <- function(model, mod = " ") {
name <- name <- firstup(as.character(stringr::str_replace(row.names(model$beta),
mod, "")))
len <- length(name)
if (len != 1) {
newdata <- matrix(NA, ncol = len, nrow = len)
for (i in 1:len) {
pos <- which(model$X[, i] == 1)[[1]]
newdata[, i] <- model$X[pos, ]
}
pred <- metafor::predict.rma(model, newmods = newdata)
} else {
pred <- metafor::predict.rma(model)
}
estimate <- pred$pred
lowerCL <- pred$ci.lb
upperCL <- pred$ci.ub
lowerPR <- pred$cr.lb
upperPR <- pred$cr.ub
table <- tibble(name = factor(name, levels = name, labels = name), estimate = estimate,
lowerCL = lowerCL, upperCL = upperCL, pval = model$pval, lowerPR = lowerPR,
upperPR = upperPR)
}
get_pred2 <- function(model, mod = " ") {
name <- as.factor(str_replace(row.names(model$beta), paste0("relevel", "\\(",
mod, ", ref = name", "\\)"), ""))
len <- length(name)
if (len != 1) {
newdata <- diag(len)
pred <- predict.rma(model, intercept = FALSE, newmods = newdata[, -1])
} else {
pred <- predict.rma(model)
}
estimate <- pred$pred
lowerCL <- pred$ci.lb
upperCL <- pred$ci.ub
lowerPR <- pred$cr.lb
upperPR <- pred$cr.ub
table <- tibble(name = factor(name, levels = name, labels = name), estimate = estimate,
lowerCL = lowerCL, upperCL = upperCL, pval = model$pval, lowerPR = lowerPR,
upperPR = upperPR)
}
mod_tab<-function(m){
# getting marginal R2
r2 <- r2_ml(m)
# creating a table
tibble(`Fixed effect` = row.names(m$beta), Estimate = c(m$b),
`Lower CI [0.025]` = c(m$ci.lb), `Upper CI [0.975]` = c(m$ci.ub),
`P value` = c(m$pval), R2 = c(r2[1], rep(NA, (length(m$beta)-1)))) %>% kable("html", digits = 3) %>% kable_styling("striped", position = "left")
}
uni_mod_plot<-function(m, df, log_ratio, response, variance){
p <- predict.rma(m)
df %>% mutate(ymin = p$ci.lb,
ymax = p$ci.ub, ymin2 = p$cr.lb,
ymax2 = p$cr.ub, pred = p$pred) %>%
ggplot(aes(x = response, y = log_ratio, size = sqrt(1/variance))) + geom_point(shape = 21, alpha= 0.2,
fill = "grey90") +
geom_hline(yintercept = 0, size = .5, colour = "gray70")+
geom_smooth(aes(y = ymin2), method = "lm", se = FALSE, lty = "solid", lwd = 0.75,
colour = "#0072B2") + geom_smooth(aes(y = ymax2), method = "lm", se = FALSE,
lty = "solid", lwd = 0.75, colour = "#0072B2") + geom_smooth(aes(y = ymin),
method = "lm", se = FALSE, lty = "solid", lwd = 0.75, colour = "#D55E00") +
geom_smooth(aes(y = ymax), method = "lm", se = FALSE, lty = "solid", lwd = 0.75,
colour = "#D55E00") + geom_smooth(aes(y = pred), method = "lm", se = FALSE,
lty = "solid", lwd = 1, colour = "black") +
labs(x = "\n ln(restoration site age)", y = "ln(restored/unrestored) - mean biodiversity", size = "Precision (1/SE)") + guides(fill = "none",
colour = "none") + # themses
theme_classic() + theme(legend.position = c(0, 1), legend.justification = c(0, 1)) + theme(legend.direction = "horizontal") +
theme(legend.background = element_blank()) + theme(axis.text.y = element_text(size = 8,
colour = "black", hjust = 0.5, angle = 90))+
coord_cartesian(ylim = c(-2.5, 2.5))+
scale_y_continuous(limits = c(-2.5, 2.5),
breaks = c(-2, -1, 0, 1, 2),
labels = c("\n \n -2", "100% decrease \n \n -1", "\n \n 0.0", "100% increase \n \n 1", "\n \n2")) +
theme(legend.position = "none")
}
uni_mod_plot_ns<-function(m, df, log_ratio, response, variance){
p <- predict.rma(m)
df %>% mutate(ymin = p$ci.lb,
ymax = p$ci.ub, ymin2 = p$cr.lb,
ymax2 = p$cr.ub, pred = p$pred) %>%
ggplot(aes(x = response, y = log_ratio, size = sqrt(1/variance))) + geom_point(shape = 21, alpha= 0.2,
fill = "grey90") +
geom_hline(yintercept = 0, size = .5, colour = "gray70")+
geom_smooth(aes(y = ymin2), method = "lm", se = FALSE, lty = "dashed", lwd = 0.75,
colour = "#0072B2") + geom_smooth(aes(y = ymax2), method = "lm", se = FALSE,
lty = "dashed", lwd = 0.75, colour = "#0072B2") + geom_smooth(aes(y = ymin),
method = "lm", se = FALSE, lty = "dashed", lwd = 0.75, colour = "#D55E00") +
geom_smooth(aes(y = ymax), method = "lm", se = FALSE, lty = "dashed", lwd = 0.75,
colour = "#D55E00") + geom_smooth(aes(y = pred), method = "lm", se = FALSE,
lty = "dashed", lwd = 1, colour = "black") +
labs(x = "\n ln(restoration site age)", y = "ln(restored/unrestored) - mean biodiversity", size = "Precision (1/SE)") + guides(fill = "none",
colour = "none") + # themses
theme_classic() + theme(legend.position = c(0, 1), legend.justification = c(0, 1)) + theme(legend.direction = "horizontal") +
theme(legend.background = element_blank()) + theme(axis.text.y = element_text(size = 8,
colour = "black", hjust = 0.5, angle = 90))+
coord_cartesian(ylim = c(-2.5, 2.5))+
scale_y_continuous(limits = c(-2.5, 2.5),
breaks = c(-2, -1, 0, 1, 2),
labels = c("\n \n -2", "100% decrease \n \n -1", "\n \n 0.0", "100% increase \n \n 1", "\n \n2")) +
theme(legend.position = "none")
}
uni_egger_plot_cvr<-function(m, data){# getting marginal R2
r2 <- r2_ml(m)
# getting estimates: name does not work for slopes
est <- get_est(m, mod = "sqrt(vi)")
# creating a table
tibble(`Fixed effect` = row.names(m$beta), Estimate = c(est$estimate),
`Lower CI [0.025]` = c(est$lowerCL), `Upper CI [0.975]` = c(est$upperCL),
`P value` = c(m$pval), R2 = c(r2[1],
NA)) %>% kable("html", digits = 3) %>% kable_styling("striped", position = "left")
pred <- predict.rma(m)
# plotting
fit <- data %>% drop_na(vi_cvr)%>% mutate(ymin = pred$ci.lb, ymax = pred$ci.ub, ymin2 = pred$cr.lb, ymax2 = pred$cr.ub, pred = pred$pred) %>%
ggplot(aes(x = sqrt(vi_cvr), y = yi_cvr, size = sqrt(1/vi_cvr))) + geom_point(shape = 21, fill = "grey90", alpha = 0.3) +
geom_smooth(aes(y = ymin2), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#0072B2") +
geom_smooth(aes(y = ymax2), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#0072B2") +
geom_smooth(aes(y = ymin), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#D55E00") +
geom_smooth(aes(y = ymax), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#D55E00") +
geom_smooth(aes(y = pred), method = "loess", se = FALSE, lty = "dashed", lwd = 0.5, colour = "black") +
labs(x = "sqrt(sampling variance)", y = "lnRR (effect size)", size = "Precision (1/SE)") +
guides(fill = "none", colour = "none") +
theme_bw() + theme(legend.position = c(0, 1), legend.justification = c(0, 1)) + theme(legend.direction = "horizontal") +
theme(legend.background = element_blank()) + theme(axis.text.y = element_text(size = 10, colour = "black", hjust = 0.5, angle = 90))
fit
}
uni_egger_plot_vr<-function(m, data){# getting marginal R2
r2 <- r2_ml(m)
# getting estimates: name does not work for slopes
est <- get_est(m, mod = "sqrt(vi)")
# creating a table
tibble(`Fixed effect` = row.names(m$beta), Estimate = c(est$estimate),
`Lower CI [0.025]` = c(est$lowerCL), `Upper CI [0.975]` = c(est$upperCL),
`P value` = c(m$pval), R2 = c(r2[1],
NA)) %>% kable("html", digits = 3) %>% kable_styling("striped", position = "left")
pred <- predict.rma(m)
# plotting
fit <- data %>% drop_na(vi_vr)%>% mutate(ymin = pred$ci.lb, ymax = pred$ci.ub, ymin2 = pred$cr.lb, ymax2 = pred$cr.ub, pred = pred$pred) %>%
ggplot(aes(x = sqrt(vi_vr), y = yi_vr, size = sqrt(1/vi_vr))) + geom_point(shape = 21, fill = "grey90", alpha = 0.3) +
geom_smooth(aes(y = ymin2), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#0072B2") +
geom_smooth(aes(y = ymax2), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#0072B2") +
geom_smooth(aes(y = ymin), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#D55E00") +
geom_smooth(aes(y = ymax), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#D55E00") +
geom_smooth(aes(y = pred), method = "loess", se = FALSE, lty = "dashed", lwd = 0.5, colour = "black") +
labs(x = "sqrt(sampling variance)", y = "lnRR (effect size)", size = "Precision (1/SE)") +
guides(fill = "none", colour = "none") +
theme_bw() + theme(legend.position = c(0, 1), legend.justification = c(0, 1)) + theme(legend.direction = "horizontal") +
theme(legend.background = element_blank()) + theme(axis.text.y = element_text(size = 10, colour = "black", hjust = 0.5, angle = 90))
fit
}
uni_egger_plot_mean<-function(m, data){# getting marginal R2
r2 <- r2_ml(m)
# getting estimates: name does not work for slopes
est <- get_est(m, mod = "sqrt(vi)")
# creating a table
tibble(`Fixed effect` = row.names(m$beta), Estimate = c(est$estimate),
`Lower CI [0.025]` = c(est$lowerCL), `Upper CI [0.975]` = c(est$upperCL),
`P value` = c(m$pval), R2 = c(r2[1],
NA)) %>% kable("html", digits = 3) %>% kable_styling("striped", position = "left")
pred <- predict.rma(m)
# plotting
fit <- data %>% drop_na(vi_mean)%>% mutate(ymin = pred$ci.lb, ymax = pred$ci.ub, ymin2 = pred$cr.lb, ymax2 = pred$cr.ub, pred = pred$pred) %>%
ggplot(aes(x = sqrt(vi_mean), y = yi_mean, size = sqrt(1/vi_mean))) + geom_point(shape = 21, fill = "grey90", alpha = 0.3) +
geom_smooth(aes(y = ymin2), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#0072B2") +
geom_smooth(aes(y = ymax2), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#0072B2") +
geom_smooth(aes(y = ymin), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#D55E00") +
geom_smooth(aes(y = ymax), method = "loess", se = FALSE, lty = "dotted", lwd = 0.25, colour = "#D55E00") +
geom_smooth(aes(y = pred), method = "loess", se = FALSE, lty = "dashed", lwd = 0.5, colour = "black") +
labs(x = "sqrt(sampling variance)", y = "lnRR (effect size)", size = "Precision (1/SE)") +
guides(fill = "none", colour = "none") +
theme_bw() + theme(legend.position = c(0, 1), legend.justification = c(0, 1)) + theme(legend.direction = "horizontal") +
theme(legend.background = element_blank()) + theme(axis.text.y = element_text(size = 10, colour = "black", hjust = 0.5, angle = 90))
fit
}
I2 <- function(model, method = c("Wolfgang", "Shinichi")) {
## evaluate choices
method <- match.arg(method)
# Wolfgang's method
if (method == "Wolfgang") {
W <- solve(model$V)
X <- model.matrix(model)
P <- W - W %*% X %*% solve(t(X) %*% W %*% X) %*% t(X) %*% W
I2_total <- sum(model$sigma2)/(sum(model$sigma2) + (model$k - model$p)/sum(diag(P)))
I2_each <- model$sigma2/(sum(model$sigma2) + (model$k - model$p)/sum(diag(P)))
names(I2_each) = paste0("I2_", model$s.names)
# putting all together
I2s <- c(I2_total = I2_total, I2_each)
# or my way
} else {
# sigma2_v = typical sampling error variance
sigma2_v <- sum(1/model$vi) * (model$k - 1)/(sum(1/model$vi)^2 - sum((1/model$vi)^2))
I2_total <- sum(model$sigma2)/(sum(model$sigma2) + sigma2_v) #s^2_t = total variance
I2_each <- model$sigma2/(sum(model$sigma2) + sigma2_v)
names(I2_each) = paste0("I2_", model$s.names)
# putting all together
I2s <- c(I2_total = I2_total, I2_each)
}
return(I2s)
}
The meta-analytic dataset is available at https://osf.io/4aucp/.
The core details of the literature search are included in the main body of the manuscript so are not included here. However, there are some additional details that are important to note.
Titles of results were screened for any non-terrestrial studies by removal of titles containing the following words: aquatic, stream, river, marine, ocean, lake, fish, wetland, saltmarsh, pond, coral, reef, plankton. Other useful blanket screening terms include, “prioritiz*”, “implications for”, which helped to identify empirical studies not of restoration sites but of experiments with potential implications for ecological restoration. This removed 555 records for a total of 1721 studies remaining. Titles were then individually screened in detail to only include studies that clearly assessed restoration outcomes using some form of biodiversity. Where study titles were ambiguous they were not removed. Only obviously irrelevant studies were removed at this stage. This removed a further 1137 studies.
All screening was conducted by lead author JA.
We did not record a measure of the individual quality of studies included in the meta-analysis (e.g. blinded data collection, reporting quality, and experimental vs observational).
See below for a PRISMA diagram showing the workflow for the literature search.
Figure S1. PRISMA diagram detailing literature screening process (formatted according to Page et al. 2020)
We checked the mean-variance relationship in our data. If there is such a relationship, it is better to use the logarithm of response ratio, lnRR rather than standardized mean difference (often known as Cohen’s d or Hedges’ g) because the latter assumes the homogeneity of variance.
full_data<-read.csv("Data/variation_data.csv", stringsAsFactors=FALSE)
# A)
dat_t<-full_data %>% drop_na(t_mean) # some have NA values here so log transform produces NAs, creating clean dataset for each plot
dat_c<-full_data %>% drop_na(c_mean) %>% filter(c_sd != 0) # t = treatment (restored), c = control (unrestored), r = reference (some SD = 0 in control dataset)
dat_r<-full_data %>% drop_na(r_mean)
cor_1 <- round(with(dat_t,cor(log(t_mean), log(t_sd))), 3)
plot_res <- ggplot(dat_t, aes(log(t_mean), log(t_sd))) + geom_point() +
geom_smooth(method = "lm") +
labs(x = "ln(mean[experiment])",
y = "ln(SD[experiment])",
title = "Restoration sites mean vs variance (sd)") +
xlim(-5, 7.5) + ylim(-9, 9) + annotate('text',x = 7.5, y = -8, label = paste("r = ", cor_1))
# B)
cor_2 <- round(with(dat_c,cor(log(c_mean), log(c_sd))), 3)
plot_con <- ggplot(dat_c, aes(log(c_mean), log(c_sd))) + geom_point() +
geom_smooth(method = "lm") +
labs(x = "ln(mean[control])",
y = "ln(SD[control])",
title = "Unrestored sites mean vs variance (sd)")+
xlim(-5, 7.5) + ylim(-9, 9) + annotate('text',x = 7.5, y = -8, label = paste("r = ", cor_2))
# c)
cor_3 <- round(with(dat_r,cor.test(log(r_mean), log(r_sd)))$estimate[[1]], 3)
plot_ref <- ggplot(dat_r, aes(log(r_mean), log(r_sd))) + geom_point() +
geom_smooth(method = "lm") +
labs(x = "ln(mean[experiment])",
y = "ln(SD[experiment])",
title = "Reference sites mean vs variance (sd)")+
xlim(-5, 7.5) + ylim(-9, 9) + annotate('text',x = 7.5, y = -8, label = paste("r = ", cor_3))
mean_SD <- (plot_res / plot_con / plot_ref) +
plot_annotation(tag_levels = "A", tag_suffix = ")")
mean_SD
Figure S2: Correlations between mean and variance in the restored sites, unrestored sites, and reference sites.
We found extremely strong correlations between mean and variance (standard deviation) on the log scale above, so instead, we report differences in variability within-studies as the difference in lnCVR (the log of the coefficient of variation ratio. We use the log response ratio to compare mean differences for a range of reasons outlined in the methods of the main body of the paper, and as is illustrated further below, it is also less sensitive to scale bias.
Effect sizes are calculated using escalc
function in
metafor
. Here we calculate effect sizes for two separate
meta-analyses, comparing restored sites to control (unrestored) sites,
and comparing restored sites to reference (goal) sites. We also use the
make_VCV_matrix
function to calculate the
variance-covariance matrix to use in the model in place of the error
term vi
. The code essentially performs the same procedure
for caluclating effect sizes twice. We also calculate lnVR (the log
variability ratio that uses SD), despite the correlations shown above,
to present alongside the main results (though these are not presented in
the body of the paper).
###########################
## UNRESTORED / RESTORED ##
###########################
# un_re = unrestored / restored
un_re<-read.csv("Data/variation_data.csv", stringsAsFactors = F)
un_re$c_quad_n = as.numeric(un_re$c_quad_n)
un_re$c_mean = as.numeric(un_re$c_mean)
un_re$c_sd = as.numeric(un_re$c_sd)
#remove studies with only a restored sites comparison
un_re<-un_re[!is.na(un_re$c_mean),]
#un_re %>% group_by(id, c_mean, c_sd) %>% distinct(shared_ctrl) %>% filter(n()>1) # checking shared controls is accurate
#calculate the lnCVR and lnRR and lnVR effect size and un_reiance with escalc
CVR<-escalc(measure = "CVR", n1i = un_re$t_quad_n, n2i = un_re$c_quad_n, m1i = un_re$t_mean, m2i = un_re$c_mean, sd1i = un_re$t_sd, sd2i = un_re$c_sd)
lnRR<-escalc(measure = "ROM", n1i = un_re$t_quad_n, n2i = un_re$c_quad_n, m1i = un_re$t_mean, m2i = un_re$c_mean, sd1i = un_re$t_sd, sd2i = un_re$c_sd)
lnVR<-escalc(measure = "VR", n1i = un_re$t_quad_n, n2i = un_re$c_quad_n, m1i = un_re$t_mean, m2i = un_re$c_mean, sd1i = un_re$t_sd, sd2i = un_re$c_sd)
#combined effect sizes with relevant un_rea frames
un_re <-bind_cols(un_re, lnRR, lnVR, CVR)
# name the un_rea something meaningful and remove all the columns unneeded
un_re<-un_re %>% rename(yi_mean = yi...36, vi_mean = vi...37, yi_vr = yi...38, vi_vr = vi...39, yi_cvr = yi...40, vi_cvr = vi...41)
#remove studies that have vi=NA - usually where control SD = 0
un_re<-un_re[!is.na(un_re$vi_vr),]
un_re$plu<-as.factor(un_re$plu)
un_re$plu<-relevel(un_re$plu, "semi-natural")
#need another random factor for 'unit'
unit <- factor(1:length(un_re$yi_mean))
un_re$unit <- unit
vcv_cvr<-make_VCV_matrix(un_re, V ="vi_cvr", "shared_ctrl", "unit", rho=0.5)
vcv_mean<-make_VCV_matrix(un_re, V ="vi_mean", "shared_ctrl", "unit", rho=0.5)
vcv_vr<-make_VCV_matrix(un_re, V ="vi_vr", "shared_ctrl", "unit", rho=0.5)
##########################
## RESTORED / REFERENCE ##
##########################
# re_ref = restored / reference
re_ref<-read.csv("Data/variation_data.csv", stringsAsFactors = F)
#remove studies with only a degraded site comparison
re_ref<-re_ref[!is.na(re_ref$r_mean),]
#remove studies that have vi=NA - usually where control SD = 0
re_ref<-re_ref %>% filter(r_sd != 0)
re_ref<-re_ref %>% filter(!is.na(r_sd))
# there is a few sites where the reference control is shared, but the degraded one is not, need to add a "ref_shared_ctrl" to correct this
re_ref<-re_ref %>% group_by(id, r_mean, r_sd) %>% mutate(ref_shared_ctrl = cur_group_id())
#re_ref %>% group_by(id, r_mean, r_sd) %>% distinct(ref_shared_ctrl) %>% filter(n()>1) # to check any errors in the shared_control tagging
re_ref$r_quad_n = as.numeric(re_ref$r_quad_n)
re_ref$r_mean = as.numeric(re_ref$r_mean)
re_ref$r_sd = as.numeric(re_ref$r_sd)
re_ref<-re_ref %>% filter(r_quad_n > 1) # a few sample sizes of 1 or 0?
#calculate the lnCVR and lnRR effect size and re_refiance with escalc
CVR<-escalc(measure = "CVR", n1i = re_ref$t_quad_n, n2i = re_ref$r_quad_n, m1i = re_ref$t_mean, m2i = re_ref$r_mean, sd1i = re_ref$t_sd, sd2i = re_ref$r_sd)
lnRR<-escalc(measure = "ROM", n1i = re_ref$t_quad_n, n2i = re_ref$r_quad_n, m1i = re_ref$t_mean, m2i = re_ref$r_mean, sd1i = re_ref$t_sd, sd2i = re_ref$r_sd)
lnVR<-escalc(measure = "VR", n1i = re_ref$t_quad_n, n2i = re_ref$r_quad_n, m1i = re_ref$t_mean, m2i = re_ref$r_mean, sd1i = re_ref$t_sd, sd2i = re_ref$r_sd)
#combined effect sizes with relevant data frames
re_ref <-bind_cols(re_ref, lnRR, lnVR, CVR)
# name the data something meaningful and remove all the columns unneeded
re_ref<-re_ref %>% rename(yi_mean = yi...37, vi_mean = vi...38, yi_vr = yi...39, vi_vr = vi...40, yi_cvr = yi...41, vi_cvr = vi...42)
re_ref$plu<-as.factor(re_ref$plu)
re_ref$plu<-relevel(re_ref$plu, "semi-natural")
#need another random factor for 'unit'
unit <- factor(1:length(re_ref$yi_mean))
re_ref$unit <- unit
re_ref<-as.data.frame(re_ref) # the group_by to do the shared control check above turns this bad boy into a tibble, needs to be a dataframe for the below function
vcv_cvr_rr<-make_VCV_matrix(data = re_ref, V ="vi_cvr", cluster = "ref_shared_ctrl", obs = "unit", rho=0.5)
vcv_mean_rr<-make_VCV_matrix(re_ref, V ="vi_mean", "ref_shared_ctrl", "unit", rho=0.5)
vcv_vr_rr<-make_VCV_matrix(re_ref, V ="vi_vr", "ref_shared_ctrl", "unit", rho=0.5)
We conducted meta-analyses (i.e. ran the intercept models) using the
rma.mv
function in metafor
. For every model
(lnCVR, lnRR, and lnVR), we conduct the same model a second time
including the sampling scale (measured as quadrat size) to see if the
results are robust to variation in sampling scale. Note that this
reduces the sample size of the model overall in all cases as not all
biodiversity sampling methods have a comparable scale (e.g. butterfly
net sweeps, linear transects).
# "mean" in model name refers to lnRR, vr = lnVR, cvr = lnCVR
# ur = unrestored/restored comparison, rr = restored/reference comparison, q = quadrat size included
un_re$ln_qsize<-log(un_re$t_qsize_m2)
re_ref$ln_qsize<-log(re_ref$t_qsize_m2)
cvr_ur <- rma.mv(yi_cvr, vcv_cvr, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
cvr_q_ur <- rma.mv(yi_cvr, vcv_cvr, mods= ~ln_qsize - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
vr_ur <- rma.mv(yi_vr, vcv_vr, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
vr_q_ur <- rma.mv(yi_vr, vcv_vr, mods= ~ln_qsize - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
mean_ur <- rma.mv(yi_mean, vcv_mean, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
mean_q_ur <- rma.mv(yi_mean, vcv_mean, mods= ~ln_qsize - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
cvr_rr <- rma.mv(yi_cvr, vcv_cvr_rr, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
cvr_q_rr <- rma.mv(yi_cvr, vcv_cvr_rr, mods= ~ln_qsize - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
vr_rr <- rma.mv(yi_vr, vcv_vr_rr, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
vr_q_rr <- rma.mv(yi_vr, vcv_vr_rr, mods= ~ln_qsize - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
mean_rr <- rma.mv(yi_mean, vcv_mean_rr, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
mean_q_rr <- rma.mv(yi_mean, vcv_mean_rr, mods= ~ln_qsize - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
Table S1: Overall effects (meta-analytic means), 95% confidence intervals (CIs) and 95% prediction intervals (95%). lnCVR = log CV ratio (coefficient of variation), lnRR = log response ratio (mean), lnVR = log variation ratio (SD).
# getting a table of CI and PI
pred_cvr_ur <- get_pred1(cvr_ur, mod = "Int")
pred_vr_ur <- get_pred1(vr_ur, mod = "Int")
pred_mean_ur <- get_pred1(mean_ur, mod = "Int")
pred_cvr_rr <- get_pred1(cvr_rr, mod = "Int")
pred_vr_rr <- get_pred1(vr_rr, mod = "Int")
pred_mean_rr <- get_pred1(mean_rr, mod = "Int")
# Drawing a table for meta-analyses
tibble(`Effect size` = c("lnCVR - unrestored", "lnVR - unrestored", "lnRR - unrestored", "lnCVR - reference", "lnVR - reference", "lnRR - referemce"),
`Overall mean` = c(pred_cvr_ur$estimate, pred_vr_ur$estimate, pred_mean_ur$estimate, pred_cvr_rr$estimate, pred_vr_rr$estimate, pred_mean_rr$estimate),
`Lower CI [0.025]` = c(pred_cvr_ur$lowerCL, pred_vr_ur$lowerCL, pred_mean_ur$lowerCL, pred_cvr_rr$lowerCL, pred_vr_rr$lowerCL, pred_mean_rr$lowerCL),
`Upper CI [0.975]` = c(pred_cvr_ur$upperCL, pred_vr_ur$upperCL, pred_mean_ur$upperCL, pred_cvr_rr$upperCL, pred_vr_rr$upperCL, pred_mean_rr$upperCL),
`P value` = c(pred_cvr_ur$pval, pred_vr_ur$pval, pred_mean_ur$pval,pred_cvr_rr$pval, pred_vr_rr$pval, pred_mean_rr$pval),
`Lower PI [0.025]` = c(pred_cvr_ur$lowerPR, pred_vr_ur$lowerPR, pred_mean_ur$lowerPR, pred_cvr_rr$lowerPR, pred_vr_rr$lowerPR, pred_mean_rr$lowerPR),
`Upper PI [0.975]` = c(pred_cvr_ur$upperPR, pred_vr_ur$upperPR, pred_mean_ur$upperPR, pred_cvr_rr$upperPR, pred_vr_rr$upperPR, pred_mean_rr$upperPR)) %>%
kable("html", digits = 3) %>%
kable_styling("striped", position = "left")%>%
scroll_box(width = "800px", height = "300px")
Effect size | Overall mean | Lower CI [0.025] | Upper CI [0.975] | P value | Lower PI [0.025] | Upper PI [0.975] |
---|---|---|---|---|---|---|
lnCVR - unrestored | -0.152 | -0.248 | -0.055 | 0.002 | -1.071 | 0.768 |
lnVR - unrestored | 0.079 | -0.031 | 0.190 | 0.158 | -0.955 | 1.113 |
lnRR - unrestored | 0.182 | 0.112 | 0.251 | 0.000 | -0.425 | 0.788 |
lnCVR - reference | 0.183 | 0.051 | 0.315 | 0.007 | -1.004 | 1.370 |
lnVR - reference | 0.048 | -0.056 | 0.152 | 0.368 | -0.981 | 1.076 |
lnRR - referemce | -0.139 | -0.218 | -0.061 | 0.000 | -1.007 | 0.728 |
Table S2: Heterogeneity among effects of restoration, measured using I^2.
cvrur<-I2(cvr_ur)
vrur<-I2(vr_ur)
meanur<-I2(mean_ur)
cvrrr<-I2(cvr_rr)
vrrr<-I2(vr_rr)
meanrr<-I2(mean_rr)
tbl<-rbind(cvrur, vrur, meanur, cvrrr, vrrr, meanrr)
tbl<-as.data.frame(tbl)
tbl$Model<-c("LnCVR - unrestored/restored", "LnVR - unrestored/restored","LnRR - unrestored/restored",
"LnCVR - reference/restored", "LnVR - reference/restored", "LnRR - reference/restored")
tbl %>% kable("html", digits = 4) %>%
kable_styling("striped", position = "left")
I2_total | I2_id | I2_plot_id | I2_unit | Model | |
---|---|---|---|---|---|
cvrur | 0.6717 | 0.1461 | 0.2175 | 0.3081 | LnCVR - unrestored/restored |
vrur | 0.7712 | 0.2642 | 0.1750 | 0.3320 | LnVR - unrestored/restored |
meanur | 0.9979 | 0.5724 | 0.0163 | 0.4093 | LnRR - unrestored/restored |
cvrrr | 0.8014 | 0.4050 | 0.0708 | 0.3256 | LnCVR - reference/restored |
vrrr | 0.7853 | 0.2785 | 0.0473 | 0.4595 | LnVR - reference/restored |
meanrr | 0.9994 | 0.3454 | 0.0039 | 0.6501 | LnRR - reference/restored |
######
# SIZE #
######
# getting a table of CI and PI
un_re$site_size<-ifelse(un_re$site_size == 0, 0.1, un_re$site_size)
un_re_sz<-un_re %>% drop_na(site_size)
# need a new vcv matrix because above reduces the sample slightly (NA age removal)
vcv_cvr_sz<-make_VCV_matrix(un_re_sz, V ="vi_cvr", "shared_ctrl", "unit", rho=0.5)
vcv_mean_sz<-make_VCV_matrix(un_re_sz, V ="vi_mean", "shared_ctrl", "unit", rho=0.5)
vcv_vr_sz<-make_VCV_matrix(un_re_sz, V ="vi_vr", "shared_ctrl", "unit", rho=0.5)
mean_size_ur <- rma.mv(yi_mean, vcv_mean_sz, mods = ~log(site_size), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_sz)
vr_size_ur <- rma.mv(yi_vr, vcv_vr_sz, mods = ~log(site_size), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_sz)
cvr_size_ur <- rma.mv(yi_cvr, vcv_cvr_sz, mods = ~log(site_size), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_sz)
mean_size_ur_q <- rma.mv(yi_mean, vcv_mean_sz, mods = ~log(site_size) + log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_sz)
vr_size_ur_q <- rma.mv(yi_vr, vcv_vr_sz, mods = ~log(site_size) + log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_sz)
cvr_size_ur_q <- rma.mv(yi_cvr, vcv_cvr_sz, mods = ~log(site_size) + log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_sz)
# need a new vcv matrix because above reduces the sample slightly (NA size removal)
re_ref$site_size<-ifelse(re_ref$site_size == 0, 0.1, re_ref$site_size)
re_ref_sz<-re_ref %>% drop_na(site_size)
vcv_cvr_rr_sz<-make_VCV_matrix(re_ref_sz, V ="vi_cvr", "shared_ctrl", "unit", rho=0.5)
vcv_mean_rr_sz<-make_VCV_matrix(re_ref_sz, V ="vi_mean", "shared_ctrl", "unit", rho=0.5)
vcv_vr_rr_sz<-make_VCV_matrix(re_ref_sz, V ="vi_vr", "shared_ctrl", "unit", rho=0.5)
mean_size_rr <- rma.mv(yi_mean, vcv_mean_rr_sz, mods = ~log(site_size), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_sz)
vr_size_rr <- rma.mv(yi_vr, vcv_vr_rr_sz, mods = ~log(site_size), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_sz)
cvr_size_rr <- rma.mv(yi_cvr, vcv_cvr_rr_sz, mods = ~log(site_size), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_sz)
mean_size_rr_q <- rma.mv(yi_mean, vcv_mean_rr_sz, mods = ~log(site_size)+ log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_sz)
vr_size_rr_q <- rma.mv(yi_vr, vcv_vr_rr_sz, mods = ~log(site_size)+ log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_sz)
cvr_size_rr_q <- rma.mv(yi_cvr, vcv_cvr_rr_sz, mods = ~log(site_size)+ log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_sz)
#####
# AGE #
#####
un_re$age.rest.<-ifelse(un_re$age.rest. == 0, 0.1, un_re$age.rest.)
un_re_ag<-un_re %>% tidyr::drop_na(age.rest.)
# need a new vcv matrix because above reduces the sample slightly (NA age removal)
vcv_cvr_ag<-make_VCV_matrix(un_re_ag, V ="vi_cvr", "shared_ctrl", "unit", rho=0.5)
vcv_mean_ag<-make_VCV_matrix(un_re_ag, V ="vi_mean", "shared_ctrl", "unit", rho=0.5)
vcv_vr_ag<-make_VCV_matrix(un_re_ag, V ="vi_vr", "shared_ctrl", "unit", rho=0.5)
mean_age_ur <- rma.mv(yi_mean, vcv_mean_ag, mods = ~(age.rest.), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_ag)
vr_age_ur <- rma.mv(yi_vr, vcv_vr_ag, mods = ~(age.rest.) , random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_ag)
cvr_age_ur <- rma.mv(yi_cvr, vcv_cvr_ag, mods = ~(age.rest.), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_ag)
mean_age_ur_q <- rma.mv(yi_mean, vcv_mean_ag, mods = ~(age.rest.)+ log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_ag)
vr_age_ur_q <- rma.mv(yi_vr, vcv_vr_ag, mods = ~(age.rest.) + log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_ag)
cvr_age_ur_q <- rma.mv(yi_cvr, vcv_cvr_ag, mods = ~(age.rest.)+ log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re_ag)
# need a new vcv matrix because above reduces the sample slightly (NA age removal)
re_ref$age.rest.<-ifelse(re_ref$age.rest. == 0, 0.1, re_ref$age.rest.)
re_ref_ag<-re_ref %>% tidyr::drop_na(age.rest.)
vcv_cvr_rr_ag<-make_VCV_matrix(re_ref_ag, V ="vi_cvr", "shared_ctrl", "unit", rho=0.5)
vcv_mean_rr_ag<-make_VCV_matrix(re_ref_ag, V ="vi_mean", "shared_ctrl", "unit", rho=0.5)
vcv_vr_rr_ag<-make_VCV_matrix(re_ref_ag, V ="vi_vr", "shared_ctrl", "unit", rho=0.5)
mean_age_rr <- rma.mv(yi_mean, vcv_mean_rr_ag, mods = ~(age.rest.), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_ag)
vr_age_rr <- rma.mv(yi_vr, vcv_vr_rr_ag, mods = ~(age.rest.) , random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_ag)
cvr_age_rr <- rma.mv(yi_cvr, vcv_cvr_rr_ag, mods = ~(age.rest.), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_ag)
mean_age_rr_q <- rma.mv(yi_mean, vcv_mean_rr_ag, mods = ~(age.rest.)+ log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_ag)
vr_age_rr_q <- rma.mv(yi_vr, vcv_vr_rr_ag, mods = ~(age.rest.) + log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_ag)
cvr_age_rr_q <- rma.mv(yi_cvr, vcv_cvr_rr_ag, mods = ~(age.rest.)+ log(t_qsize_m2), random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref_ag)
#####
# PLU #
#####
mean_plu_ur <- rma.mv(yi_mean, vcv_mean, mods = ~plu - 1 , random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
vr_plu_ur <- rma.mv(yi_vr, vcv_vr, mods = ~plu - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
cvr_plu_ur <- rma.mv(yi_cvr, vcv_cvr, mods = ~plu - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
mean_plu_ur_q <- rma.mv(yi_mean, vcv_mean, mods = ~plu + log(t_qsize_m2) - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
vr_plu_ur_q <- rma.mv(yi_vr, vcv_vr, mods = ~plu + log(t_qsize_m2)- 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
cvr_plu_ur_q <- rma.mv(yi_cvr, vcv_cvr, mods = ~plu + log(t_qsize_m2)- 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
mean_plu_rr <- rma.mv(yi_mean, vcv_mean_rr, mods = ~plu - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
vr_plu_rr <- rma.mv(yi_vr, vcv_vr_rr, mods = ~plu - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
cvr_plu_rr <- rma.mv(yi_cvr, vcv_cvr_rr, mods = ~plu - 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
mean_plu_rr_q <- rma.mv(yi_mean, vcv_mean_rr, mods = ~plu + log(t_qsize_m2)- 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
vr_plu_rr_q <- rma.mv(yi_vr, vcv_vr_rr, mods = ~plu + log(t_qsize_m2)- 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
cvr_plu_rr_q <- rma.mv(yi_cvr, vcv_cvr_rr, mods = ~plu + log(t_qsize_m2)- 1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
Our study sites had a global distribution, however with some clear biases towards the Global North (particularly North America and Europe), with the continents of Africa, Asia and South America poorly represented.
library(ggplot2) # ggplot() fortify()
library(rworldmap) # getMap()
#load spatial data
spatial_data <- read_csv("Data/studies.csv")
world <- getMap(resolution = "high")
ggplot() +
geom_polygon(data=map_data('world'), mapping=aes(x=long, y=lat, group=group), fill="gray90", colour="gray70", size = 0.25) +
geom_point(data = spatial_data, aes(x = Y, y = X), shape= 19, color = "red4", size = 1)+
theme_bw(base_size = 15)+
coord_equal()+
ylim(-60, 90) +
xlim(-179, 195) +
theme(axis.title = element_blank(),
axis.ticks = element_blank(),
axis.text = element_blank(),
panel.grid.major = element_blank(), panel.grid.minor = element_blank())
#ggsave("Figure_1.pdf", height = 4, width = 8)
Figure S4. Location of studies included in the meta-analysis.
I^2 (heterogeneity index) values are calculated within the code chunk.
# drawing plots
i2cvrur<-I2(cvr_ur)
p1 <- orchard_plot(cvr_ur, mod="Int", xlab = "log(CV ratio) - unrestored/restored", alpha = 0.05, k = TRUE) +
scale_y_discrete(labels = "Overall mean") +
scale_fill_manual(values="green4") +
scale_colour_manual(values="green4") +
coord_cartesian(xlim = c(-3, 3)) + theme(legend.position = "none")+
geom_richtext(x = 2,
y = 0.7,
label = paste('<i>N<sub>effect size</sub</i> =', cvr_ur$k.all), size =3, label.size = NA)
i2vrur<-I2(vr_ur)
p2 <- orchard_plot(vr_ur, mod="Int", xlab = "log(variability ratio) - unrestored/restored", alpha = 0.1, k=F) +
scale_y_discrete(labels = "Overall mean") +
scale_fill_manual(values="red") +
scale_colour_manual(values="red") +
coord_cartesian(xlim = c(-3, 3))+ theme(legend.position = "none")+
geom_richtext(x = 2,
y = 0.7,
label = paste('<i>N<sub>effect size</sub</i> =', vr_ur$k.all), size =3, label.size = NA)
i2meanur<-I2(mean_ur)
p3 <- orchard_plot(mean_ur, mod="Int", xlab = "log(Response ratio) - unrestored/restored", alpha = 0.1, k=F) +
scale_y_discrete(labels = "Overall mean") +
scale_fill_manual(values="purple") +
scale_colour_manual(values="purple") +
coord_cartesian(xlim = c(-3, 3))+ theme(legend.position = "none")+
geom_richtext(x = 2,
y = 0.7,
label = paste('<i>N<sub>effect size</sub</i> =', mean_ur$k.all), size =3, label.size = NA)
i2cvrrr<-I2(cvr_rr)
p4 <- orchard_plot(cvr_rr, mod="Int", xlab = "log(CV ratio) - reference/restored", alpha = 0.05, k=F) +
scale_y_discrete(labels = "Overall mean") +
scale_fill_manual(values="green4") +
scale_colour_manual(values="green4") +
coord_cartesian(xlim = c(-3, 3))+ theme(legend.position = "none")+
geom_richtext(x = 2,
y = 0.7,
label = paste('<i>N<sub>effect size</sub</i> =', cvr_rr$k.all), size =3, label.size = NA)
i2vrrr<-I2(vr_rr)
p5 <- orchard_plot(vr_rr, mod="Int", xlab = "log(variability ratio) - reference/restored", alpha = 0.1, k=F) +
scale_y_discrete(labels = "Overall mean") +
scale_fill_manual(values="red") +
scale_colour_manual(values="red") +
coord_cartesian(xlim = c(-3, 3))+ theme(legend.position = "none") +
geom_richtext(x = 2,
y = 0.7,
label = paste('<i>N<sub>effect size</sub</i> =', vr_rr$k.all), size =3, label.size = NA)
i2meanrr<-I2(mean_rr)
p6 <- orchard_plot(mean_rr, mod="Int", xlab = "log(Response ratio) - reference/restored", alpha = 0.1, k=F) +
scale_y_discrete(labels = "Overall mean") +
scale_fill_manual(values="purple") +
scale_colour_manual(values="purple") +
coord_cartesian(xlim = c(-3, 3))+ theme(legend.position = "none")+
geom_richtext(x = 2,
y = 0.7,
label = paste('<i>N<sub>effect size</sub</i> =', mean_rr$k.all), size =3, label.size = NA)
fig<-p1/p2/p3/p4/p5/p6
fig
Figure2<-p3/p1/p6/p4+plot_annotation(tag_prefix = "(", tag_levels = "a", tag_suffix = ")")
#ggsave("Figure_2.pdf", Figure2, height = 10, width = 7)
rr<-(((p3+theme(axis.title = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_text(angle=0)
)+scale_y_discrete(labels="Relative to \nunrestored")))
)/
(p6+theme(
axis.line.x.top = element_blank(),
axis.text.y = element_text(angle=0),
panel.grid.major = element_blank(), panel.grid.minor = element_blank())+xlab("Log response ratio")+scale_y_discrete(labels="Relative to \nreference"))/
(((p1+theme(axis.title = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text.x = element_blank(),
axis.text.y = element_text(angle=0),
)+scale_y_discrete(labels="Relative to \nunrestored")))
)/
(p4+theme(
axis.text.y = element_text(angle=0),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank())+xlab("Log CV ratio")+scale_y_discrete(labels="Relative to \nreference"))
#ggsave("Figure_2.pdf", rr)
Figure S4. An orchard plot showing the meta-analytic mean (mean effect size) with its 95% confidence interval (thick line) and 95% prediction interval (thin line), with observed effect sizes based on various precisions (1/SE).
names<-as.data.frame(c("mean - restored/unrestored", "mean - restored/reference", "cvr - restored/unrestored", "cvr - restored/reference", "vr - restored/unrestored", "vr - restored/reference"))
names<-`colnames<-`(names, "model")
i2_all<-bind_rows(i2meanur, i2meanrr, i2cvrur, i2cvrrr, i2vrur, i2vrrr)
i2_all<-bind_cols(names, i2_all)
kable(i2_all) %>% kable_styling()%>%
scroll_box(width = "800px", height = "300px")
model | I2_total | I2_id | I2_plot_id | I2_unit |
---|---|---|---|---|
mean - restored/unrestored | 0.9979406 | 0.5724067 | 0.0162736 | 0.4092603 |
mean - restored/reference | 0.9994044 | 0.3453757 | 0.0039141 | 0.6501146 |
cvr - restored/unrestored | 0.6717313 | 0.1461263 | 0.2174874 | 0.3081176 |
cvr - restored/reference | 0.8014435 | 0.4050007 | 0.0708160 | 0.3256269 |
vr - restored/unrestored | 0.7712294 | 0.2642332 | 0.1749586 | 0.3320375 |
vr - restored/reference | 0.7853423 | 0.2785496 | 0.0473188 | 0.4594739 |
Table S3. i2 values (measure of heterogeneity among results) for all models
We ran a univariate meta-regression models above for each of the
following moderators: 1) site_size
, 2)
age.rest.
, 3) plu
, to test our research
questions. We also ran the same models with the quadrat size on a
reduced sample of the data (not all sampling methods use sampling method
measurable in area). In no cases did terms change in significance or
direction as a result of the inclusion of quadrat size.
The following code runs plots and tables of the result.
a1<-uni_mod_plot_ns(cvr_age_ur, un_re_ag, log_ratio = un_re_ag$yi_cvr, response = un_re_ag$age.rest., variance = un_re_ag$vi_cvr)+ylab("Log CV ratio (relative to unrestored")+xlab("Restored site age (yr)")
a2<-uni_mod_plot_ns(vr_age_ur, un_re_ag, log_ratio = un_re_ag$yi_vr, response = un_re_ag$age.rest., variance = un_re_ag$vi_vr)+ylab("Log SD ratio (relative to unrestored)")+xlab("Restored site age (yr)")
a3<-uni_mod_plot(mean_age_ur, un_re_ag, log_ratio = un_re_ag$yi_mean, response = un_re_ag$age.rest., variance = un_re_ag$vi_mean)+ylab("Log response ratio (relative to unrestored)")+xlab("Restored site age (yr)")
a4<-uni_mod_plot_ns(cvr_age_rr, re_ref_ag, log_ratio = re_ref_ag$yi_cvr, response = re_ref_ag$age.rest., variance = re_ref_ag$vi_cvr)+ylab("Log CV ratio (relative to reference)")+xlab("Restored site age (yr)")
a5<-uni_mod_plot_ns(vr_age_rr, re_ref_ag, log_ratio = re_ref_ag$yi_vr, response = re_ref_ag$age.rest., variance = re_ref_ag$vi_vr)+ylab("Log SD ratio (relative to referenec)")+xlab("Restored site age (yr)")
a6<-uni_mod_plot_ns(mean_age_rr, re_ref_ag, log_ratio = re_ref_ag$yi_mean, response = re_ref_ag$age.rest., variance = re_ref_ag$vi_mean)+ylab("Log response ratio (relative to reference)")+xlab("Restored site age (yr)")
(a1| a2 | a3) / (a4 | a5 | a6) +plot_annotation(tag_levels = "A")
fig3<-(a1|a3)/(a4|a6)+plot_annotation(tag_prefix = "(", tag_levels = "a", tag_suffix = ")")
#ggsave("Figure_3.pdf", fig3, height = 8, width = 8)
Figure S5. The relationship between site age and the meta-analyitic mean, with its 95% confidence interval (red dashed line) and 95% prediction interval (blue dashed line), with observed effect sizes based on various precisions (1/SE).
sz1<-uni_mod_plot_ns(cvr_size_ur, un_re_sz, log_ratio = un_re_sz$yi_cvr, response = log(un_re_sz$site_size), variance = un_re_sz$vi_cvr)
sz2<-uni_mod_plot_ns(vr_size_ur, un_re_sz, log_ratio = un_re_sz$yi_vr, response = log(un_re_sz$site_size), variance = un_re_sz$vi_vr)
sz3<-uni_mod_plot_ns(mean_size_ur, un_re_sz, log_ratio = un_re_sz$yi_mean, response = log(un_re_sz$site_size), variance = un_re_sz$vi_mean)
sz4<-uni_mod_plot_ns(cvr_size_rr, re_ref_sz, log_ratio = re_ref_sz$yi_cvr, response = log(re_ref_sz$site_size), variance = re_ref_sz$vi_cvr)
sz5<-uni_mod_plot_ns(vr_size_rr, re_ref_sz, log_ratio = re_ref_sz$yi_vr, response = log(re_ref_sz$site_size), variance = re_ref_sz$vi_vr)
sz6<-uni_mod_plot_ns(mean_size_rr, re_ref_sz, log_ratio = re_ref_sz$yi_mean, response = log(re_ref_sz$site_size), variance = re_ref_sz$vi_mean)
sz_list<-list(sz1,sz2,sz3,sz4,sz5,sz6)
(sz1 + xlab("ln restoration site size (ha)") + ylab("ln(restored / unrestored) [lnCVR]") | sz2 + xlab("ln restoration site size (ha)")+ ylab("ln(restored / unrestored) [lnVR]")| sz3+ xlab("ln restoration site size (ha)")+ ylab("ln(restored / unrestored) [lnRR]") ) / (sz4+ xlab("ln restoration site size (ha)") + ylab("ln(restored / reference) [lnCVR]") | sz5 + xlab("ln restoration site size (ha)") + ylab("ln(restored / unrestored) [lnVR]")| sz6+ xlab("ln restoration site size (ha)")+ ylab("ln(restored / unrestored) [lnRR]")) +plot_annotation(tag_levels = "A")
Figure_4<-(sz1 + xlab("Restored site size (log ha)")+ ylab("Log CV ratio (relative to unrestored)")|sz4+ xlab("Restored site size (log ha)")+ ylab("Log CV ratio (relative to reference)")) / (sz3+ xlab("Restored site size (log ha)")+ ylab("Log response ratio (relative to unrestored)") | sz6+ xlab("Restored site size (log ha)")+ ylab("Log response ratio (relative to reference")) +plot_annotation(tag_prefix = "(", tag_levels = "a", tag_suffix = ")")
#ggsave("Figure_4.pdf", plot = Figure_4, height = 8, width = 8)
Figure S6. The relationship between restoration site size (ha) and the biodiversity change following restoration compared to unrestored and reference levels.
# modify orchard_plot function to not paste K but N instead
orchard_plot<-function (object, mod = "Int", xlab, N = "none",
alpha = 0.1, angle = 90, cb = TRUE, k = TRUE, transfm = c("none",
"tanh"))
{
transfm <- match.arg(transfm)
if (any(class(object) %in% c("rma.mv", "rma"))) {
if (mod != "Int") {
object <- mod_results(object, mod)
}
else {
object <- mod_results(object, mod = "Int")
}
}
mod_table <- object$mod_table
data <- object$data
data$moderator <- factor(data$moderator, levels = mod_table$name,
labels = mod_table$name)
data$scale <- (1/sqrt(data[, "vi"]))
legend <- "Precision (1/SE)"
if (any(N != "none")) {
data$scale <- N
legend <- "Sample Size (N)"
}
if (transfm == "tanh") {
cols <- sapply(mod_table, is.numeric)
mod_table[, cols] <- Zr_to_r(mod_table[, cols])
data$yi <- Zr_to_r(data$yi)
label <- xlab
}
else {
label <- xlab
}
mod_table$K <- as.vector(by(data, data[, "moderator"],
function(x) length(x[, "yi"])))
group_no <- nrow(mod_table)
cbpl <- c("#E69F00", "#009E73", "#F0E442",
"#0072B2", "#D55E00", "#CC79A7", "#56B4E9",
"#999999")
plot <- ggplot2::ggplot(data = mod_table, aes(x = estimate,
y = name)) + ggbeeswarm::geom_quasirandom(data = data,
aes(x = yi, y = moderator, size = scale, colour = moderator),
groupOnX = FALSE, alpha = alpha) + ggplot2::geom_errorbarh(aes(xmin = lowerPR,
xmax = upperPR), height = 0, show.legend = FALSE, size = 0.5,
alpha = 0.6) + ggplot2::geom_errorbarh(aes(xmin = lowerCL,
xmax = upperCL), height = 0, show.legend = FALSE, size = 1.2) +
ggplot2::geom_vline(xintercept = 0, linetype = 2, colour = "black",
alpha = alpha) + ggplot2::geom_point(aes(fill = name),
size = 3, shape = 21) + ggplot2::theme_bw() + ggplot2::guides(fill = "none",
colour = "none") + ggplot2::theme(legend.position = c(1,
0), legend.justification = c(1, 0)) + ggplot2::theme(legend.title = element_text(size = 9)) +
ggplot2::theme(legend.direction = "horizontal") +
ggplot2::theme(legend.background = element_blank()) +
ggplot2::labs(x = label, y = "", size = legend) +
ggplot2::theme(axis.text.y = element_text(size = 10,
colour = "black", hjust = 0.5, angle = angle))
if (cb == TRUE) {
plot <- plot + scale_fill_manual(values = cbpl) + scale_colour_manual(values = cbpl)
}
if (k == TRUE) {
plot <- plot + ggplot2::annotate("text", x = (max(data$yi) +
(max(data$yi) * 0.1)), y = (seq(1, group_no, 1) +
0.3), label = paste("italic(N)==", mod_table$K),
parse = TRUE, hjust = "right", size = 3.5)
}
return(plot)
}
pl3<-orchard_plot(mean_plu_ur, mod = "plu", alpha = 0.08, xlab = "lnRR - unrestored/restored")+ theme(legend.position = "none")
pl2<-orchard_plot(vr_plu_ur, mod = "plu", alpha = 0.08,xlab = "lnVR - unrestored/restored")+ theme(legend.position = "none")
pl1<-orchard_plot(cvr_plu_ur, mod = "plu", alpha = 0.08,xlab = "lnCVR - unrestored/restored")+ theme(legend.position = "none")
pl6<-orchard_plot(mean_plu_rr, mod = "plu", alpha = 0.08,xlab = "lnRR - reference/restored")+ theme(legend.position = "none")
pl5<-orchard_plot(vr_plu_rr, mod = "plu", alpha = 0.08,xlab = "lnVR - reference/restored")+ theme(legend.position = "none")
pl4<-orchard_plot(cvr_plu_rr, mod = "plu", alpha = 0.08,xlab = "lnCVR - reference/restored")+ theme(legend.position = "none")
(pl1 | pl2 | pl3) / (pl4 | pl5 | pl6) +plot_annotation(tag_levels = "A")
pl1<-pl1+ scale_fill_manual(values = rep("green4", 5)) + scale_colour_manual(values = rep("green4", 5))+
theme(axis.title.y = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text.y = element_text(angle=0),
)+xlab("Log CV ratio (relative to unrestored)")
pl3<-pl3+ scale_fill_manual(values = rep("purple", 5)) + scale_colour_manual(values = rep("purple", 5)) +
theme(axis.title.y = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text.y = element_text(angle=0),
)+xlab("Log response ratio (relative to unrestored)")
pl6<-pl6+ scale_fill_manual(values = rep("purple", 5)) + scale_colour_manual(values = rep("purple", 5)) +
theme(axis.title.y = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text.y = element_blank(),
)+xlab("Log response ratio (relative to reference)")
pl4<-pl4+ scale_fill_manual(values = rep("green4", 5)) + scale_colour_manual(values = rep("green4", 5))+
theme(axis.title.y = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text.y = element_blank(),
)+xlab("Log CV ratio (relative to reference)")
Figure5<-((pl3 + pl6) / (pl1 + pl4)) +plot_annotation(tag_prefix = "(", tag_levels = "a", tag_suffix = ")")
#ggsave("Figure_5.pdf", Figure5, height = 8.5, width = 11)
Figure S7 Orchard plots showing the relationship between restoration site past land use and the biodiversity change following restoration compared to unrestored and reference levels.
Table S4. Effect of age of restoration site on variability of biodiversity (lnCVR, lnVR) and mean biodiversity (lnRR) compared to unrestored and reference levels
age_list<-list(cvr_age_ur, cvr_age_ur_q, vr_age_ur, vr_age_ur_q, mean_age_ur, mean_age_ur_q, cvr_age_rr, cvr_age_rr_q, vr_age_rr, vr_age_rr_q, mean_age_rr, mean_age_rr_q)
age<-map(.x = age_list, .f = tidy)
age_res<-bind_rows(age)
names<-c("lnCVR restored/unrestored", "lnCVR restored/unrestored - with quadrat size","lnVR restored/unrestored","lnVR restored/unrestored - with quadrat size","lnRR restored/unrestored","lnRR restored/unrestored - with quadrat size", "lnCVR restored/reference", "lnCVR restored/reference - with quadrat size","lnVR restored/reference","lnVR restored/reference - with quadrat size","lnRR restored/reference","lnRR restored/reference - with quadrat size")
age_res<-age_res %>% mutate(model = rep(names, times = c(2,3,2,3,2,3,2,3,2,3,2,3))) %>% select(model, everything())
kable(age_res) %>% kable_styling()%>%
scroll_box(width = "800px", height = "300px")
model | term | type | estimate | std.error | statistic | p.value |
---|---|---|---|---|---|---|
lnCVR restored/unrestored | intercept | summary | -0.1068276 | 0.0607740 | -1.7577842 | 0.0787842 |
lnCVR restored/unrestored | age.rest. | summary | -0.0057333 | 0.0037186 | -1.5417827 | 0.1231264 |
lnCVR restored/unrestored - with quadrat size | intercept | summary | -0.1588189 | 0.1027788 | -1.5452503 | 0.1222857 |
lnCVR restored/unrestored - with quadrat size | age.rest. | summary | -0.0069050 | 0.0053638 | -1.2873307 | 0.1979790 |
lnCVR restored/unrestored - with quadrat size | log(t_qsize_m2) | summary | 0.0178760 | 0.0220671 | 0.8100739 | 0.4178977 |
lnVR restored/unrestored | intercept | summary | 0.0439135 | 0.0636302 | 0.6901364 | 0.4901084 |
lnVR restored/unrestored | age.rest. | summary | 0.0024611 | 0.0035212 | 0.6989235 | 0.4845999 |
lnVR restored/unrestored - with quadrat size | intercept | summary | -0.0439626 | 0.1153917 | -0.3809859 | 0.7032137 |
lnVR restored/unrestored - with quadrat size | age.rest. | summary | 0.0049332 | 0.0048394 | 1.0193958 | 0.3080151 |
lnVR restored/unrestored - with quadrat size | log(t_qsize_m2) | summary | 0.0234839 | 0.0242783 | 0.9672798 | 0.3334042 |
lnRR restored/unrestored | intercept | summary | 0.1250887 | 0.0383468 | 3.2620400 | 0.0011061 |
lnRR restored/unrestored | age.rest. | summary | 0.0057740 | 0.0016158 | 3.5735175 | 0.0003522 |
lnRR restored/unrestored - with quadrat size | intercept | summary | 0.1185138 | 0.0659021 | 1.7983325 | 0.0721243 |
lnRR restored/unrestored - with quadrat size | age.rest. | summary | 0.0070783 | 0.0022683 | 3.1205543 | 0.0018051 |
lnRR restored/unrestored - with quadrat size | log(t_qsize_m2) | summary | 0.0002807 | 0.0134049 | 0.0209428 | 0.9832913 |
lnCVR restored/reference | intercept | summary | 0.1609789 | 0.0788196 | 2.0423700 | 0.0411148 |
lnCVR restored/reference | age.rest. | summary | 0.0015570 | 0.0037609 | 0.4139927 | 0.6788794 |
lnCVR restored/reference - with quadrat size | intercept | summary | 0.1597338 | 0.1259884 | 1.2678454 | 0.2048532 |
lnCVR restored/reference - with quadrat size | age.rest. | summary | 0.0038033 | 0.0049450 | 0.7691173 | 0.4418237 |
lnCVR restored/reference - with quadrat size | log(t_qsize_m2) | summary | 0.0082353 | 0.0242982 | 0.3389254 | 0.7346660 |
lnVR restored/reference | intercept | summary | 0.0067172 | 0.0633476 | 0.1060364 | 0.9155534 |
lnVR restored/reference | age.rest. | summary | 0.0033310 | 0.0032555 | 1.0231973 | 0.3062146 |
lnVR restored/reference - with quadrat size | intercept | summary | -0.0341376 | 0.0923360 | -0.3697103 | 0.7115984 |
lnVR restored/reference - with quadrat size | age.rest. | summary | 0.0042421 | 0.0038553 | 1.1003215 | 0.2711921 |
lnVR restored/reference - with quadrat size | log(t_qsize_m2) | summary | 0.0121269 | 0.0190593 | 0.6362697 | 0.5246007 |
lnRR restored/reference | intercept | summary | -0.1468596 | 0.0470307 | -3.1226325 | 0.0017924 |
lnRR restored/reference | age.rest. | summary | 0.0007055 | 0.0022126 | 0.3188355 | 0.7498512 |
lnRR restored/reference - with quadrat size | intercept | summary | -0.1867170 | 0.0872582 | -2.1398224 | 0.0323691 |
lnRR restored/reference - with quadrat size | age.rest. | summary | 0.0000736 | 0.0032305 | 0.0227871 | 0.9818201 |
lnRR restored/reference - with quadrat size | log(t_qsize_m2) | summary | 0.0076610 | 0.0172119 | 0.4451001 | 0.6562474 |
Table S5. Effect of size (ha) of restoration site on variability of biodiversity (lnCVR, lnVR) and mean biodiversity (lnRR) compared to unrestored and reference levels
size_list<-list(cvr_size_ur, cvr_size_ur_q, vr_size_ur, vr_size_ur_q, mean_size_ur,mean_size_ur_q, cvr_size_rr,cvr_size_rr_q, vr_size_rr, vr_size_rr_q, mean_size_rr, mean_size_rr_q)
size<-map(.x = size_list, .f = tidy)
size_res<-bind_rows(size)
names<-c("lnCVR restored/unrestored", "lnCVR restored/unrestored - with quadrat size","lnVR restored/unrestored","lnVR restored/unrestored - with quadrat size","lnRR restored/unrestored","lnRR restored/unrestored - with quadrat size", "lnCVR restored/reference", "lnCVR restored/reference - with quadrat size","lnVR restored/reference","lnVR restored/reference - with quadrat size","lnRR restored/reference","lnRR restored/reference - with quadrat size")
size_res<-size_res %>% mutate(model = rep(names, times = c(2,3,2,3,2,3,2,3,2,3,2,3))) %>% select(model, everything())
kable(size_res) %>% kable_styling()%>%
scroll_box(width = "800px", height = "300px")
model | term | type | estimate | std.error | statistic | p.value |
---|---|---|---|---|---|---|
lnCVR restored/unrestored | intercept | summary | -0.1650070 | 0.0633310 | -2.6054691 | 0.0091749 |
lnCVR restored/unrestored | log(site_size) | summary | 0.0113341 | 0.0169283 | 0.6695349 | 0.5031544 |
lnCVR restored/unrestored - with quadrat size | intercept | summary | -0.2882260 | 0.1189602 | -2.4228784 | 0.0153981 |
lnCVR restored/unrestored - with quadrat size | log(site_size) | summary | -0.0104319 | 0.0234301 | -0.4452365 | 0.6561489 |
lnCVR restored/unrestored - with quadrat size | log(t_qsize_m2) | summary | 0.0400190 | 0.0341938 | 1.1703582 | 0.2418569 |
lnVR restored/unrestored | intercept | summary | 0.1010521 | 0.0794432 | 1.2720053 | 0.2033712 |
lnVR restored/unrestored | log(site_size) | summary | 0.0137065 | 0.0209209 | 0.6551590 | 0.5123654 |
lnVR restored/unrestored - with quadrat size | intercept | summary | 0.0566133 | 0.1671474 | 0.3387027 | 0.7348337 |
lnVR restored/unrestored - with quadrat size | log(site_size) | summary | 0.0012972 | 0.0336589 | 0.0385384 | 0.9692584 |
lnVR restored/unrestored - with quadrat size | log(t_qsize_m2) | summary | 0.0210472 | 0.0442273 | 0.4758864 | 0.6341553 |
lnRR restored/unrestored | intercept | summary | 0.2615080 | 0.0573297 | 4.5614773 | 0.0000051 |
lnRR restored/unrestored | log(site_size) | summary | -0.0128193 | 0.0139094 | -0.9216260 | 0.3567237 |
lnRR restored/unrestored - with quadrat size | intercept | summary | 0.2142117 | 0.1135340 | 1.8867627 | 0.0591922 |
lnRR restored/unrestored - with quadrat size | log(site_size) | summary | -0.0037902 | 0.0236403 | -0.1603288 | 0.8726221 |
lnRR restored/unrestored - with quadrat size | log(t_qsize_m2) | summary | 0.0209292 | 0.0272426 | 0.7682542 | 0.4423362 |
lnCVR restored/reference | intercept | summary | 0.2444956 | 0.0847242 | 2.8857826 | 0.0039044 |
lnCVR restored/reference | log(site_size) | summary | -0.0185232 | 0.0227547 | -0.8140358 | 0.4156244 |
lnCVR restored/reference - with quadrat size | intercept | summary | 0.2596436 | 0.1239166 | 2.0953098 | 0.0361435 |
lnCVR restored/reference - with quadrat size | log(site_size) | summary | -0.0509273 | 0.0274077 | -1.8581370 | 0.0631496 |
lnCVR restored/reference - with quadrat size | log(t_qsize_m2) | summary | -0.0046997 | 0.0303315 | -0.1549444 | 0.8768651 |
lnVR restored/reference | intercept | summary | 0.1301382 | 0.0778002 | 1.6727220 | 0.0943820 |
lnVR restored/reference | log(site_size) | summary | -0.0198852 | 0.0208759 | -0.9525410 | 0.3408227 |
lnVR restored/reference - with quadrat size | intercept | summary | 0.0750873 | 0.1102572 | 0.6810190 | 0.4958595 |
lnVR restored/reference - with quadrat size | log(site_size) | summary | -0.0524892 | 0.0235936 | -2.2247170 | 0.0261002 |
lnVR restored/reference - with quadrat size | log(t_qsize_m2) | summary | 0.0073618 | 0.0272550 | 0.2701095 | 0.7870760 |
lnRR restored/reference | intercept | summary | -0.1017665 | 0.0490825 | -2.0733749 | 0.0381374 |
lnRR restored/reference | log(site_size) | summary | -0.0048247 | 0.0131968 | -0.3655968 | 0.7146660 |
lnRR restored/reference - with quadrat size | intercept | summary | -0.1773332 | 0.0808711 | -2.1927878 | 0.0283227 |
lnRR restored/reference - with quadrat size | log(site_size) | summary | 0.0020029 | 0.0181781 | 0.1101847 | 0.9122629 |
lnRR restored/reference - with quadrat size | log(t_qsize_m2) | summary | 0.0125650 | 0.0193315 | 0.6499744 | 0.5157088 |
Table S6. Effect of past land status of restoration site on variability of biodiversity (lnCVR, lnVR) and mean biodiversity (lnRR) compared to unrestored and reference levels
plu_list<-list(cvr_plu_ur, cvr_plu_ur_q, vr_plu_ur, vr_plu_ur_q, mean_plu_ur, mean_plu_ur_q, cvr_plu_rr, cvr_plu_rr_q, vr_plu_rr, vr_plu_rr_q, mean_plu_rr, mean_plu_rr_q)
plu<-map(.x = plu_list, .f = tidy)
plu_res<-bind_rows(plu)
names<-c("lnCVR restored/unrestored", "lnCVR restored/unrestored - with quadrat size","lnVR restored/unrestored","lnVR restored/unrestored - with quadrat size","lnRR restored/unrestored","lnRR restored/unrestored - with quadrat size", "lnCVR restored/reference", "lnCVR restored/reference - with quadrat size","lnVR restored/reference","lnVR restored/reference - with quadrat size","lnRR restored/reference","lnRR restored/reference - with quadrat size")
plu_res<-plu_res %>% mutate(model = rep(names, times = c(5,5,5,5,5,5,5,6,5,6,5,6))) #%>% select(model, everything())
kable(plu_res) %>% kable_styling()%>%
scroll_box(width = "800px", height = "300px")
term | type | estimate | std.error | statistic | p.value | model |
---|---|---|---|---|---|---|
plusemi-natural | summary | -0.3852357 | 0.1077520 | -3.5752081 | 0.0003499 | lnCVR restored/unrestored |
pluagriculture | summary | -0.0829547 | 0.0710309 | -1.1678664 | 0.2428607 | lnCVR restored/unrestored |
pluforestry | summary | -0.0846212 | 0.0962468 | -0.8792107 | 0.3792871 | lnCVR restored/unrestored |
plumining | summary | -0.1584071 | 0.2076465 | -0.7628693 | 0.4455413 | lnCVR restored/unrestored |
pluurban | summary | -0.2599954 | 0.3680248 | -0.7064615 | 0.4799012 | lnCVR restored/unrestored |
plusemi-natural | summary | -0.4413136 | 0.1281706 | -3.4431738 | 0.0005749 | lnCVR restored/unrestored - with quadrat size |
pluagriculture | summary | -0.0853426 | 0.1023533 | -0.8338049 | 0.4043910 | lnCVR restored/unrestored - with quadrat size |
pluforestry | summary | -0.2638104 | 0.1492127 | -1.7680153 | 0.0770583 | lnCVR restored/unrestored - with quadrat size |
pluurban | summary | -0.2566981 | 0.3698492 | -0.6940616 | 0.4876436 | lnCVR restored/unrestored - with quadrat size |
log(t_qsize_m2) | summary | 0.0257898 | 0.0214315 | 1.2033554 | 0.2288388 | lnCVR restored/unrestored - with quadrat size |
plusemi-natural | summary | -0.0082467 | 0.1223165 | -0.0674209 | 0.9462466 | lnVR restored/unrestored |
pluagriculture | summary | 0.1866603 | 0.0818572 | 2.2803175 | 0.0225889 | lnVR restored/unrestored |
pluforestry | summary | -0.0103818 | 0.1148719 | -0.0903771 | 0.9279876 | lnVR restored/unrestored |
plumining | summary | 0.0164567 | 0.2608203 | 0.0630960 | 0.9496901 | lnVR restored/unrestored |
pluurban | summary | -0.3516609 | 0.4317616 | -0.8144793 | 0.4153704 | lnVR restored/unrestored |
plusemi-natural | summary | -0.1714823 | 0.1529290 | -1.1213197 | 0.2621518 | lnVR restored/unrestored - with quadrat size |
pluagriculture | summary | 0.2179067 | 0.1234627 | 1.7649601 | 0.0775705 | lnVR restored/unrestored - with quadrat size |
pluforestry | summary | -0.2748811 | 0.1837485 | -1.4959634 | 0.1346632 | lnVR restored/unrestored - with quadrat size |
pluurban | summary | -0.3511681 | 0.4477038 | -0.7843760 | 0.4328195 | lnVR restored/unrestored - with quadrat size |
log(t_qsize_m2) | summary | 0.0386884 | 0.0242723 | 1.5939330 | 0.1109511 | lnVR restored/unrestored - with quadrat size |
plusemi-natural | summary | 0.2956695 | 0.0731717 | 4.0407623 | 0.0000533 | lnRR restored/unrestored |
pluagriculture | summary | 0.2083782 | 0.0491856 | 4.2365694 | 0.0000227 | lnRR restored/unrestored |
pluforestry | summary | 0.0347762 | 0.0721479 | 0.4820126 | 0.6297970 | lnRR restored/unrestored |
plumining | summary | 0.1678914 | 0.1656187 | 1.0137226 | 0.3107151 | lnRR restored/unrestored |
pluurban | summary | -0.1310971 | 0.2517307 | -0.5207831 | 0.6025179 | lnRR restored/unrestored |
plusemi-natural | summary | 0.2476480 | 0.0950021 | 2.6067642 | 0.0091402 | lnRR restored/unrestored - with quadrat size |
pluagriculture | summary | 0.2500708 | 0.0774378 | 3.2293127 | 0.0012409 | lnRR restored/unrestored - with quadrat size |
pluforestry | summary | 0.0075252 | 0.1153611 | 0.0652314 | 0.9479897 | lnRR restored/unrestored - with quadrat size |
pluurban | summary | -0.1326478 | 0.2781277 | -0.4769313 | 0.6334111 | lnRR restored/unrestored - with quadrat size |
log(t_qsize_m2) | summary | 0.0043270 | 0.0131356 | 0.3294128 | 0.7418437 | lnRR restored/unrestored - with quadrat size |
plusemi-natural | summary | -0.0228100 | 0.1941139 | -0.1175084 | 0.9064572 | lnCVR restored/reference |
pluagriculture | summary | 0.1314184 | 0.0966701 | 1.3594519 | 0.1740034 | lnCVR restored/reference |
pluforestry | summary | 0.3612461 | 0.1335275 | 2.7054073 | 0.0068221 | lnCVR restored/reference |
plumining | summary | 0.3291036 | 0.2081652 | 1.5809728 | 0.1138842 | lnCVR restored/reference |
pluurban | summary | -0.1934379 | 0.3967512 | -0.4875547 | 0.6258653 | lnCVR restored/reference |
plusemi-natural | summary | -0.1258523 | 0.2673475 | -0.4707444 | 0.6378233 | lnCVR restored/reference - with quadrat size |
pluagriculture | summary | 0.1967008 | 0.1357583 | 1.4489044 | 0.1473643 | lnCVR restored/reference - with quadrat size |
pluforestry | summary | 0.5183067 | 0.1940891 | 2.6704574 | 0.0075748 | lnCVR restored/reference - with quadrat size |
plumining | summary | 0.6026451 | 0.2945680 | 2.0458606 | 0.0407701 | lnCVR restored/reference - with quadrat size |
pluurban | summary | -0.1859859 | 0.3922212 | -0.4741861 | 0.6353672 | lnCVR restored/reference - with quadrat size |
log(t_qsize_m2) | summary | -0.0079093 | 0.0255702 | -0.3093172 | 0.7570802 | lnCVR restored/reference - with quadrat size |
plusemi-natural | summary | 0.0094039 | 0.1580410 | 0.0595030 | 0.9525515 | lnVR restored/reference |
pluagriculture | summary | 0.0177378 | 0.0771091 | 0.2300352 | 0.8180644 | lnVR restored/reference |
pluforestry | summary | 0.1835670 | 0.1047408 | 1.7525826 | 0.0796737 | lnVR restored/reference |
plumining | summary | -0.0451151 | 0.1646990 | -0.2739244 | 0.7841427 | lnVR restored/reference |
pluurban | summary | -0.2390748 | 0.3301516 | -0.7241365 | 0.4689820 | lnVR restored/reference |
plusemi-natural | summary | -0.0718948 | 0.2012747 | -0.3571972 | 0.7209442 | lnVR restored/reference - with quadrat size |
pluagriculture | summary | 0.0124196 | 0.1016058 | 0.1222331 | 0.9027145 | lnVR restored/reference - with quadrat size |
pluforestry | summary | 0.2325126 | 0.1421050 | 1.6362030 | 0.1017971 | lnVR restored/reference - with quadrat size |
plumining | summary | -0.0041445 | 0.2082891 | -0.0198978 | 0.9841249 | lnVR restored/reference - with quadrat size |
pluurban | summary | -0.2336051 | 0.3075150 | -0.7596541 | 0.4474614 | lnVR restored/reference - with quadrat size |
log(t_qsize_m2) | summary | 0.0023398 | 0.0205270 | 0.1139867 | 0.9092483 | lnVR restored/reference - with quadrat size |
plusemi-natural | summary | 0.0653162 | 0.1166493 | 0.5599365 | 0.5755228 | lnRR restored/reference |
pluagriculture | summary | -0.1127956 | 0.0568177 | -1.9852179 | 0.0471202 | lnRR restored/reference |
pluforestry | summary | -0.1936367 | 0.0788148 | -2.4568577 | 0.0140158 | lnRR restored/reference |
plumining | summary | -0.3526318 | 0.1192666 | -2.9566677 | 0.0031098 | lnRR restored/reference |
pluurban | summary | -0.1252452 | 0.2358817 | -0.5309661 | 0.5954423 | lnRR restored/reference |
plusemi-natural | summary | 0.0948855 | 0.1823099 | 0.5204629 | 0.6027410 | lnRR restored/reference - with quadrat size |
pluagriculture | summary | -0.1563267 | 0.0942632 | -1.6584061 | 0.0972355 | lnRR restored/reference - with quadrat size |
pluforestry | summary | -0.2794606 | 0.1363858 | -2.0490451 | 0.0404577 | lnRR restored/reference - with quadrat size |
plumining | summary | -0.5663590 | 0.2020657 | -2.8028461 | 0.0050654 | lnRR restored/reference - with quadrat size |
pluurban | summary | -0.1392828 | 0.2674524 | -0.5207760 | 0.6025228 | lnRR restored/reference - with quadrat size |
log(t_qsize_m2) | summary | 0.0100630 | 0.0176291 | 0.5708176 | 0.5681233 | lnRR restored/reference - with quadrat size |
We used multiple approaches to assess the effect of publication bias on our results. We used a multilevel version of Egger’s regression with the square-root of the sampling variances as a moderator to test for asymmetry in funnel plots of meta-analytic models (Nakagawa & Poulin 2012). We also used traditional funnel plots to visually assess asymmetry. Intercepts in Egger’s regressions were different from zero in all models, providing evidence for publication bias. We added the publication year to meta-regressions to test for the effect of a time-lag bias on our results (Appendix S2, Table S4-S7). The effect of publication year was not related to effect sizes in any model (Appendix S2, Table S4-S7).
############################################################
###AND majority of code lifted from from Johnson et al 2020 \####
###Silicon is a global plant defence but effectiveness######
###depends on herbivore feeding strategy: a meta-analysis"##
library(metafor)
library(kableExtra)
library(knitr)
library(ggplot2)
#univariate egger regressoin
egger_uni_ur_cvr <- rma.mv(yi = yi_cvr, V = vi_cvr, mods = ~sqrt(vi_cvr), test = "t", random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
egger_uni_ur_vr <- rma.mv(yi = yi_vr, V = vi_vr, mods = ~sqrt(vi_vr), test = "t", random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
egger_uni_ur_mean <- rma.mv(yi = yi_mean, V = vi_mean, mods = ~sqrt(vi_mean), test = "t", random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
egger_uni_rr_cvr <- rma.mv(yi = yi_cvr, V = vi_cvr, mods = ~sqrt(vi_cvr), test = "t", random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
egger_uni_rr_vr <- rma.mv(yi = yi_vr, V = vi_vr, mods = ~sqrt(vi_vr), test = "t", random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
egger_uni_rr_mean <- rma.mv(yi = yi_mean, V = vi_mean, mods = ~sqrt(vi_mean), test = "t", random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
###Publication bias analysis - unscaled models
# can't get this to print neatly, for now? something to do with metafor::funnel ? nvm this works:
par(mfrow=c(3,2))
funnel(egger_uni_ur_cvr, yaxis = "seinv", level = c(90, 95, 99), shade = c("white", "gray55", "gray75"), refline = 0, legend = TRUE)
funnel(egger_uni_ur_vr, yaxis = "seinv", level = c(90, 95, 99), shade = c("white", "gray55", "gray75"), refline = 0, legend = TRUE)
funnel(egger_uni_ur_mean, yaxis = "seinv", level = c(90, 95, 99), shade = c("white", "gray55", "gray75"), refline = 0, legend = TRUE)
funnel(egger_uni_rr_cvr, yaxis = "seinv", level = c(90, 95, 99), shade = c("white", "gray55", "gray75"), refline = 0, legend = TRUE)
funnel(egger_uni_rr_vr, yaxis = "seinv", level = c(90, 95, 99), shade = c("white", "gray55", "gray75"), refline = 0, legend = TRUE)
funnel(egger_uni_rr_mean, yaxis = "seinv", level = c(90, 95, 99), shade = c("white", "gray55", "gray75"), refline = 0, legend = TRUE)
Figure S8 Funnel plots testing for asymmetry for all models and effect sizes. A = restored/unrestored lnCVR, B = restored/unrestored lnVR, C = restored/unrestored lnRR, D = restored/reference lnCVR, E = restored/reference lnVR, F = restored/reference lnRR
uni1<-uni_egger_plot_cvr(egger_uni_ur_cvr, data = un_re)+ylab("lnCVR (effect size")
uni2<-uni_egger_plot_vr(egger_uni_ur_vr, data = un_re)+ylab("lnVR (effect size")
uni3<-uni_egger_plot_mean(egger_uni_ur_mean, data = un_re)
uni4<-uni_egger_plot_cvr(egger_uni_rr_cvr, data = re_ref)+ylab("lnCVR (effect size")
uni5<-uni_egger_plot_vr(egger_uni_rr_vr, data = re_ref)+ylab("lnVR (effect size")
uni6<-uni_egger_plot_mean(egger_uni_rr_mean, data = re_ref)
(uni1 + uni2 + uni3) / (uni4 + uni5 + uni6) + plot_annotation(tag_levels = "A")
Figure S9. Plot of univariate egger regression for all models and effect sizes
Table S7. Relationship between publication year and effect size (lnRR - restored/unrestored)
##################
time_lag_effect_uni_lnRR <- rma.mv(yi = yi_mean, V = vcv_mean, mods = ~Year, test = "t",
random = list(~1 | id, ~1 | shared_ctrl, ~1 | unit), method = "REML", data = un_re)
# getting marginal R2
r2_time_lag_effect_uni_lnRR <- r2_ml(time_lag_effect_uni_lnRR)
# getting estimates: name does not work for slopes
res_time_lag_effect_uni_lnRR <- get_est(time_lag_effect_uni_lnRR, mod = "Year")
# creating a table
tibble(`Fixed effect` = row.names(time_lag_effect_uni_lnRR$beta), Estimate = c(res_time_lag_effect_uni_lnRR$estimate),
`Lower CI [0.025]` = c(res_time_lag_effect_uni_lnRR$lowerCL), `Upper CI [0.975]` = c(res_time_lag_effect_uni_lnRR$upperCL),
`P value` = time_lag_effect_uni_lnRR$pval, R2 = c(r2_time_lag_effect_uni_lnRR[1],
NA)) %>% kable("html", digits = 3) %>% kable_styling("striped", position = "left")
Fixed effect | Estimate | Lower CI [0.025] | Upper CI [0.975] | P value | R2 |
---|---|---|---|---|---|
intrcpt | -7.803 | -45.842 | 30.236 | 0.687 | 0.002 |
Year | 0.004 | -0.015 | 0.023 | 0.680 | NA |
Table S8. Relationship between publication year and effect size (lnCVR - restored/unrestored)
##################
time_lag_effect_uni_lnCVR <- rma.mv(yi = yi_cvr, V = vcv_cvr, mods = ~Year, test = "t",
random = list(~1 | id, ~1 | shared_ctrl, ~1 | unit), method = "REML", data = un_re)
# getting marginal R2
r2_time_lag_effect_uni_lnCVR <- r2_ml(time_lag_effect_uni_lnCVR)
# getting estimates: name does not work for slopes
res_time_lag_effect_uni_lnCVR <- get_est(time_lag_effect_uni_lnCVR, mod = "Year")
# creating a table
tibble(`Fixed effect` = row.names(time_lag_effect_uni_lnCVR$beta), Estimate = c(res_time_lag_effect_uni_lnCVR$estimate),
`Lower CI [0.025]` = c(res_time_lag_effect_uni_lnCVR$lowerCL), `Upper CI [0.975]` = c(res_time_lag_effect_uni_lnCVR$upperCL),
`P value` = time_lag_effect_uni_lnCVR$pval, R2 = c(r2_time_lag_effect_uni_lnCVR[1],
NA)) %>% kable("html", digits = 3) %>% kable_styling("striped", position = "left")
Fixed effect | Estimate | Lower CI [0.025] | Upper CI [0.975] | P value | R2 |
---|---|---|---|---|---|
intrcpt | 9.285 | -40.984 | 59.555 | 0.717 | 0.001 |
Year | -0.005 | -0.030 | 0.020 | 0.713 | NA |
Table S9. Relationship between publication year and effect size (lnRR - restored/reference)
##################
time_lag_effect_uni_lnRRreref <- rma.mv(yi = yi_mean, V = vcv_mean_rr, mods = ~Year, test = "t",
random = list(~1 | id, ~1 | shared_ctrl, ~1 | unit), method = "REML", data = re_ref)
# getting marginal R2
r2_time_lag_effect_uni_lnRRreref <- r2_ml(time_lag_effect_uni_lnRRreref)
# getting estimates: name does not work for slopes
res_time_lag_effect_uni_lnRRreref <- get_est(time_lag_effect_uni_lnRRreref, mod = "Year")
# creating a table
tibble(`Fixed effect` = row.names(time_lag_effect_uni_lnRRreref$beta), Estimate = c(res_time_lag_effect_uni_lnRRreref$estimate),
`Lower CI [0.025]` = c(res_time_lag_effect_uni_lnRRreref$lowerCL), `Upper CI [0.975]` = c(res_time_lag_effect_uni_lnRRreref$upperCL),
`P value` = time_lag_effect_uni_lnRRreref$pval, R2 = c(r2_time_lag_effect_uni_lnRRreref[1],
NA)) %>% kable("html", digits = 3) %>% kable_styling("striped", position = "left")
Fixed effect | Estimate | Lower CI [0.025] | Upper CI [0.975] | P value | R2 |
---|---|---|---|---|---|
intrcpt | 32.946 | -5.642 | 71.535 | 0.094 | 0.015 |
Year | -0.016 | -0.036 | 0.003 | 0.093 | NA |
Table S10. Relationship between publication year and effect size (lnRR - restored/reference)
##################
time_lag_effect_uni_lnCVRreref <- rma.mv(yi = yi_cvr, V = vcv_cvr_rr, mods = ~Year, test = "t",
random = list(~1 | id, ~1 | shared_ctrl, ~1 | unit), method = "REML", data = re_ref)
# getting marginal R2
r2_time_lag_effect_uni_lnRRreref <- r2_ml(time_lag_effect_uni_lnRRreref)
# getting estimates: name does not work for slopes
res_time_lag_effect_uni_lnRRreref <- get_est(time_lag_effect_uni_lnRRreref, mod = "Year")
# creating a table
tibble(`Fixed effect` = row.names(time_lag_effect_uni_lnRRreref$beta), Estimate = c(res_time_lag_effect_uni_lnRRreref$estimate),
`Lower CI [0.025]` = c(res_time_lag_effect_uni_lnRRreref$lowerCL), `Upper CI [0.975]` = c(res_time_lag_effect_uni_lnRRreref$upperCL),
`P value` = time_lag_effect_uni_lnRRreref$pval, R2 = c(r2_time_lag_effect_uni_lnRRreref[1],
NA)) %>% kable("html", digits = 3) %>% kable_styling("striped", position = "left")
Fixed effect | Estimate | Lower CI [0.025] | Upper CI [0.975] | P value | R2 |
---|---|---|---|---|---|
intrcpt | 32.946 | -5.642 | 71.535 | 0.094 | 0.015 |
Year | -0.016 | -0.036 | 0.003 | 0.093 | NA |
We follow recommendations by Spake et al. (2020) where possible to reduce the scale bias in our meta-analyses. Firstly, we use the log response ratio which has been shown to be more robust in scenarios of cross-study syntheses at varying spatial grain, compared with Hedges’ g (Spake et al. 2020) . Our data does not allow the use of asymptotic measures of richness (e.g. rarefied richness) since only a very small minority of studies report biodiversity in this manner. However, we run all models including the quadrat size as a term in all our models and compare to the results without this term. The significance or non-significance of all results reported were not changed when models were run on the reduced dataset models including quadrat sizes where available. Though, the nature of many biodiversity sampling methods (e.g. pitfall traps, butterfly nets, transects) are not comparable in m2 meaning that these diagnostic models exclude 20-30% of the data points. Therefore, the model results presented in the main text are excluding quadrat size.
The plots below show that our effect sizes would have been sensitive to size had we used Hedges g, however they show little response to scale when using the log response ratio or log CV ratio.
dug <- read.csv("Data/variation_data.csv")#put data file here
duglr <- metafor::escalc(measure="ROM",m1i=dug$t_mean, m2i=dug$c_mean, sd1i=dug$t_sd, sd2i=c_sd, n1i=dug$t_quad_n, n2i=dug$c_quad_n, append=T, data=dug) #non-equal variances
#lnCVR
dugcvr <- metafor::escalc(measure="CVR",m1i=dug$t_mean, m2i=dug$c_mean, sd1i=dug$t_sd, sd2i=c_sd, n1i=dug$t_quad_n, n2i=dug$c_quad_n, append=T, data=dug)
#Hedges' g
dughg <- metafor::escalc(measure="SMD",m1i=dug$t_mean, m2i=dug$c_mean, sd1i=dug$t_sd, sd2i=c_sd, n1i=dug$t_quad_n, n2i=dug$c_quad_n, append=T, data=dug)
#alternative variance estimate for g
n1=as.numeric(dug$t_quad_n); n2=as.numeric(dug$c_quad_n)
n_tilde=n2*n1/(n2+n1)
var_d_n.DENS=((1-3/(4*(n2+n1-2)-1))^2)*(n2+n1-2)/(n_tilde*(n2+n1-4)) #Hedges variance that does not contain d https://esajournals.onlinelibrary.wiley.com/doi/full/10.1002/ecs2.2419
dughg$vi2<- var_d_n.DENS
unit <- factor(1:length(duglr$yi))
duglr$unit <- unit
unit <- factor(1:length(dugcvr$yi))
dugcvr$unit <- unit
unit <- factor(1:length(dughg$yi))
dughg$unit <- unit
duglr<-duglr %>% drop_na(c(id, plot_id, unit))
dugcvr<-duglr %>% drop_na(c(id, plot_id, unit))
dughg<-dughg %>% drop_na(c(id, plot_id, unit))
duglr<-duglr %>% drop_na(t_qsize_m2)
dugcvr<-duglr %>% drop_na(t_qsize_m2)
dughg<-dughg %>% drop_na(t_qsize_m2)
#random-effects, conventional weighted meta-analysis
lr.ma.ran <- rma.mv(yi=yi, V=vi, data=duglr, method="REML", random = list(~1 | id, ~1 | plot_id, ~1 | unit))
#unweighted
lr.ma.un <- rma.mv(yi=yi, V=vi, data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed-effects, conventional weighted meta-analysis
lr.ma.fix <- rma.mv(yi=yi, V=vi, data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
#random-effects, conventional weighted meta-analysis
cvr.ma.ran <- rma.mv(yi=yi, V=vi, data=dugcvr, method="REML", random = list(~1 | id, ~1 | plot_id, ~1 | unit))
#unweighted
cvr.ma.un <- rma.mv(yi=yi, V=vi, data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed-effects, conventional weighted meta-analysis
cvr.ma.fix <- rma.mv(yi=yi, V=vi, data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
#random-effects, conventional weighted meta-analysis
hg.ma.ran <- rma.mv(yi=yi, V=vi, data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
#unweighted
hg.ma.un <- rma.mv(yi=yi, V=vi, data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed-effects, conventional weighted meta-analysis
hg.ma.fix <- rma.mv(yi=yi, V=vi, data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
hg.ma.ran.d_alt <- rma.mv(yi=yi, V=vi2, data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
hg.ma.fix.dalt <- rma.mv(yi=yi, V=vi2, data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi2)
duglr<-duglr %>% mutate(id = as.factor(id)) # currently thinks id is numeric - is that an issue?
dugcvr<-dugcvr %>% mutate(id = as.factor(id)) # currently thinks id is numeric - is that an issue?
dughg<-dughg %>% mutate(id = as.factor(id)) # currently thinks id is numeric - is that an issue?
NvsA.LR <- ggplot(duglr) + geom_point(aes(x=log(t_qsize_m2/10000), y=t_quad_n, size=1/vi,col=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic(N)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") + scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
NvsA.CVR <- ggplot(dugcvr) + geom_point(aes(x=log(t_qsize_m2/10000), y=t_quad_n, size=1/vi,col=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic(N)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") + scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
NvsA.g <- ggplot(dughg) + geom_point(aes(x=log(t_qsize_m2/10000), y=t_quad_n, size=1/vi, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic(N)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") + scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
LRvsA <- ggplot(duglr) + geom_point(aes(x=log(t_qsize_m2/10000), y=yi, size=1/vi, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic("LR")))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") + scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("study")+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
CVRvsA <- ggplot(dugcvr) + geom_point(aes(x=log(t_qsize_m2/10000), y=yi, size=1/vi, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic("CVR")))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") + scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("study")+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
gvsA <- ggplot(dughg) + geom_point(aes(x=log(t_qsize_m2/10000), y=yi, size=1/vi, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic(g)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") +scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
LR.VarvsA <- ggplot(duglr) + geom_point(aes(x=log(t_qsize_m2/10000), y=vi, size=t_quad_n, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(paste("Variance of ",italic(LR))))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") +scale_size_continuous(name = expression(italic(N)),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
CVR.VarvsA <- ggplot(dugcvr) + geom_point(aes(x=log(t_qsize_m2/10000), y=vi, size=t_quad_n, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(paste("Variance of ",italic(CVR))))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") +scale_size_continuous(name = expression(italic(N)),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
g.VarvsA <- ggplot(dughg) + geom_point(aes(x=log(t_qsize_m2/10000), y=vi, size=t_quad_n, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(paste("Variance of ",italic(g))))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") +scale_size_continuous(name = expression(italic(N)),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text=element_text(size=rel(0.7)))
library(gridExtra)
gridExtra::grid.arrange(NvsA.g, gvsA, g.VarvsA,NvsA.LR, LRvsA,LR.VarvsA, NvsA.CVR, CVRvsA,CVR.VarvsA, ncol=3)
Figure S10 Bubble plot of plot size against various effect sizes (labelled)
hdeff <- data.frame(estimate=c(hg.ma.ran$b,hg.ma.un$b,hg.ma.fix$b,hg.ma.ran.d_alt$b,hg.ma.fix.dalt$b),ci.up=c(hg.ma.ran$ci.ub,hg.ma.un$ci.ub,hg.ma.fix$ci.ub, hg.ma.ran.d_alt$ci.ub,hg.ma.fix.dalt$ci.ub), ci.lo=c(hg.ma.ran$ci.lb,hg.ma.un$ci.lb,hg.ma.fix$ci.lb,hg.ma.ran.d_alt$ci.lb,hg.ma.fix.dalt$ci.lb), weighting=c("R", "U", "F", "R", "F"), vtype=c("d","d","d","d_alt","d_alt"))
hdeff <- hdeff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
hdeff.p.a <-ggplot(hdeff) + geom_point(aes(y = estimate, x = weighting, colour=vtype), position=position_dodge(width = 0.5)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1, colour=vtype),, position=position_dodge(width = 0.5))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed",) +
xlab(NULL) +
ylab(expression(italic(g)))+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
hdeff.p.a <-hdeff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold'))) +scale_color_manual(values=c("black", "darkgray"))
lreff <- data.frame(estimate=c(lr.ma.ran$b,lr.ma.un$b,lr.ma.fix$b),ci.up=c(lr.ma.ran$ci.ub,lr.ma.un$ci.ub,lr.ma.fix$ci.ub), ci.lo=c(lr.ma.ran$ci.lb,lr.ma.un$ci.lb,lr.ma.fix$ci.lb), weighting=c("R", "U", "F"))
lreff <- lreff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
lreff.p.a <-ggplot(lreff) + geom_point(aes(y = estimate, x = weighting)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed") +
xlab(NULL) +
ylab(expression(italic(LR)))+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
lreff.p.a <-lreff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold')))
cvreff <- data.frame(estimate=c(cvr.ma.ran$b,cvr.ma.un$b,cvr.ma.fix$b),ci.up=c(cvr.ma.ran$ci.ub,cvr.ma.un$ci.ub,cvr.ma.fix$ci.ub), ci.lo=c(cvr.ma.ran$ci.lb,cvr.ma.un$ci.lb,cvr.ma.fix$ci.lb), weighting=c("R", "U", "F"))
cvreff <- cvreff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
cvreff.p.a <-ggplot(cvreff) + geom_point(aes(y = estimate, x = weighting)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed") +
xlab(NULL) +
ylab(expression(italic(cvr)))+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
cvreff.p.a <-cvreff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold')))
gridExtra::grid.arrange(hdeff.p.a, lreff.p.a, cvreff.p.a, ncol=3, widths = c(3, 2.3, 2.3))
#LR
#random, conventionally weighted
lr.ma.ran <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
# unweighted
lr.ma.un <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed effect
lr.ma.fix <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
#cvr
#random, conventionally weighted
cvr.ma.ran <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
# unweighted
cvr.ma.un <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed effect
cvr.ma.fix <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
#HG
#random, conventionally weighted
hg.ma.ran <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
# unweighted
hg.ma.un <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed effects
hg.ma.fix <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
hg.ma.ran.d_alt <- rma.mv(yi=scale(yi), V=vi2, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
hg.ma.fix.dalt <- rma.mv(yi=scale(yi), V=vi2, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi2)
hdeff <- data.frame(estimate=c(hg.ma.ran$b[2],hg.ma.un$b[2],hg.ma.fix$b[2],hg.ma.ran.d_alt$b[2],hg.ma.fix.dalt$b[2]),ci.up=c(hg.ma.ran$ci.ub[2],hg.ma.un$ci.ub[2],hg.ma.fix$ci.ub[2], hg.ma.ran.d_alt$ci.ub[2],hg.ma.fix.dalt$ci.ub[2]), ci.lo=c(hg.ma.ran$ci.lb[2],hg.ma.un$ci.lb[2],hg.ma.fix$ci.lb[2],hg.ma.ran.d_alt$ci.lb[2],hg.ma.fix.dalt$ci.lb[2]), weighting=c("R", "U", "F", "R", "F"), vtype=c("d","d","d","d_alt","d_alt"))
hdeff <- hdeff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
hdeff.p.a <-ggplot(hdeff) + geom_point(aes(y = estimate, x = weighting, colour=vtype), position=position_dodge(width = 0.5)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1, colour=vtype),, position=position_dodge(width = 0.5))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed",) +
xlab(NULL) +
ylab("Effect of plot size (regression coefficient)")+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
hdeff.p.a <-hdeff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold')))+ylim(-1,1.2) +scale_color_manual(values=c("black", "darkgray"), guide=F)
lreff <- data.frame(estimate=c(lr.ma.ran$b[2],lr.ma.un$b[2],lr.ma.fix$b[2]),ci.up=c(lr.ma.ran$ci.ub[2],lr.ma.un$ci.ub[2],lr.ma.fix$ci.ub[2]), ci.lo=c(lr.ma.ran$ci.lb[2],lr.ma.un$ci.lb[2],lr.ma.fix$ci.lb[2]), weighting=c("R", "U", "F"))
lreff <- lreff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
lreff.p.a <-ggplot(lreff) + geom_point(aes(y = estimate, x = weighting)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed") +
xlab(NULL) +
ylab("Effect of plot size (regression coefficient)")+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
lreff.p.a <-lreff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold')))+ylim(-1.2,1.5)
cvreff <- data.frame(estimate=c(cvr.ma.ran$b[2],cvr.ma.un$b[2],cvr.ma.fix$b[2]),ci.up=c(cvr.ma.ran$ci.ub[2],cvr.ma.un$ci.ub[2],cvr.ma.fix$ci.ub[2]), ci.lo=c(cvr.ma.ran$ci.lb[2],cvr.ma.un$ci.lb[2],cvr.ma.fix$ci.lb[2]), weighting=c("R", "U", "F"))
cvreff <- cvreff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
cvreff.p.a <-ggplot(cvreff) + geom_point(aes(y = estimate, x = weighting)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed") +
xlab(NULL) +
ylab("Effect of plot size (regression coefficient)")+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
cvreff.p.a <-cvreff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold')))+ylim(-1.2,1.5)
gridExtra::grid.arrange(hdeff.p.a, lreff.p.a, cvreff.p.a, ncol=3, widths=c(3,2.3, 2.3))
Re-run meta-analyses, but on unscaled response variables so can make predictions of unscaled effect sizes.
hg.ma.ran <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
#random unweighted (same meta-est if fixed unweighted, but diff se)
hg.ma.un <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#random effect but control the weights, do 1/v. same est as a fixed effect
hg.ma.fix <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
hg.ma.ran.d_alt <- rma.mv(yi=yi, V=vi2, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
hg.ma.fix.dalt <- rma.mv(yi=yi, V=vi2, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi2)
lr.ma.ran <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
#random unweighted (same meta-est if fixed unweighted, but diff se)
lr.ma.un <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#random effect but control the weights, do 1/v. same est as a fixed effect
lr.ma.fix <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
cvr.ma.ran <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
#random unweighted (same meta-est if fixed unweighted, but diff se)
cvr.ma.un <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#random effect but control the weights, do 1/v. same est as a fixed effect
cvr.ma.fix <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
Now predict the effect sizes across all interpolated values of A, plot the meta-regression slopes:
newmods=data.frame(intercept=hg.ma.ran$b[1], t_qsize_m2=seq(min(dughg$t_qsize_m2), max(dughg$t_qsize_m2), 0.1) )
newmods=as.matrix(newmods)
#head(newmods)
hg.ma.ran.preds=data.frame(predict(hg.ma.ran, addx=TRUE))
hg.ma.fix.preds=data.frame(predict(hg.ma.fix, addx=TRUE))
hg.ma.un.preds=data.frame(predict(hg.ma.un, addx=TRUE))
#weights(hg.ma.ran)
hg.ma.ran.p=ggplot()+geom_point(data=dughg,aes(x=log(t_qsize_m2), y=yi,colour=id),
#size=weights(hg.ma.ran)),
alpha=0.3) +geom_line(aes(x=hg.ma.ran.preds$X.mods, y=hg.ma.ran.preds$pred))+geom_line(aes(x=hg.ma.ran.preds$X.mods, y=hg.ma.ran.preds$pred))+geom_ribbon(aes(x=hg.ma.ran.preds$X.mods,ymin=hg.ma.ran.preds$ci.lb, ymax=hg.ma.ran.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(g)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed") +ggtitle(expression(paste("Random-effects meta-analysis, wt = 1/(", italic("V"),"+",tau^2,")")))+theme(plot.title = element_text(size = 8))+ylim(-12,7.2)
hg.ma.fix.p=ggplot()+geom_point(data=dughg,aes(x=log(t_qsize_m2), y=yi,colour=id), #size=weights(hg.ma.fix)),
alpha=0.3) +geom_line(aes(x=hg.ma.fix.preds$X.mods, y=hg.ma.fix.preds$pred))+geom_line(aes(x=hg.ma.fix.preds$X.mods, y=hg.ma.fix.preds$pred))+geom_ribbon(aes(x=hg.ma.fix.preds$X.mods,ymin=hg.ma.fix.preds$ci.lb, ymax=hg.ma.fix.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(g)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed")+ggtitle(expression(paste("Fixed-effects meta-analysis, wt = 1/(", italic("V"),")")))+theme(plot.title = element_text(size = 8))+ylim(-12,7.2)
hg.ma.un.p=ggplot()+geom_point(data=dughg,aes(x=log(t_qsize_m2), y=yi,colour=id, size=1), alpha=0.3) +geom_line(aes(x=hg.ma.fix.preds$X.mods, y=hg.ma.un.preds$pred))+geom_line(aes(x=hg.ma.un.preds$X.mods, y=hg.ma.un.preds$pred))+geom_ribbon(aes(x=hg.ma.un.preds$X.mods,ymin=hg.ma.un.preds$ci.lb, ymax=hg.ma.un.preds$ci.ub ),alpha=0.2)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(g)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed")+scale_size_continuous(guide=FALSE)+ggtitle("Unweighted meta-analysis, wt = 1")+theme(plot.title = element_text(size = 8))+ylim(-12,7.2)
newmods=data.frame(intercept=lr.ma.ran$b[1], t_qsize_m2=seq(min(duglr$t_qsize_m2), max(duglr$t_qsize_m2), 0.1) )
newmods=as.matrix(newmods)
#head(newmods)
lr.ma.ran.preds=data.frame(predict(lr.ma.ran, addx=TRUE))
lr.ma.fix.preds=data.frame(predict(lr.ma.fix, addx=TRUE))
lr.ma.un.preds=data.frame(predict(lr.ma.un, addx=TRUE))
lr.ma.ran.p=ggplot()+geom_point(data=duglr,aes(x=log(t_qsize_m2), y=yi,colour=id),# size=weights(lr.ma.ran)),
alpha=0.3) +geom_line(aes(x=lr.ma.ran.preds$X.mods, y=lr.ma.ran.preds$pred))+geom_line(aes(x=lr.ma.ran.preds$X.mods, y=lr.ma.ran.preds$pred))+geom_ribbon(aes(x=lr.ma.ran.preds$X.mods,ymin=lr.ma.ran.preds$ci.lb, ymax=lr.ma.ran.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(LR)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed") +ggtitle("")+theme(plot.title = element_text(size = 8))+ylim(-1.6,1.2)
lr.ma.fix.p=ggplot()+geom_point(data=duglr,aes(x=log(t_qsize_m2), y=yi,colour=id),# size=weights(lr.ma.fix)),
alpha=0.3) +geom_line(aes(x=lr.ma.fix.preds$X.mods, y=lr.ma.fix.preds$pred))+geom_line(aes(x=lr.ma.fix.preds$X.mods, y=lr.ma.fix.preds$pred))+geom_ribbon(aes(x=lr.ma.fix.preds$X.mods,ymin=lr.ma.fix.preds$ci.lb, ymax=lr.ma.fix.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(LR)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed")+ggtitle("")+theme(plot.title = element_text(size = 8))+coord_cartesian(ylim = c(-1.6, 1.2))
lr.ma.un.p=ggplot()+geom_point(data=duglr,aes(x=log(t_qsize_m2), y=yi,colour=id, size=1), alpha=0.3) +geom_line(aes(x=lr.ma.fix.preds$X.mods, y=lr.ma.un.preds$pred))+geom_line(aes(x=lr.ma.un.preds$X.mods, y=lr.ma.un.preds$pred))+geom_ribbon(aes(x=lr.ma.un.preds$X.mods,ymin=lr.ma.un.preds$ci.lb, ymax=lr.ma.un.preds$ci.ub ),alpha=0.2)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(LR)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed")+scale_size_continuous(guide=FALSE)+ggtitle("")+theme(plot.title = element_text(size = 8))+ylim(-1.6, 1.2)
newmods=data.frame(intercept=cvr.ma.ran$b[1], t_qsize_m2=seq(min(dugcvr$t_qsize_m2), max(dugcvr$t_qsize_m2), 0.1) )
newmods=as.matrix(newmods)
#head(newmods)
cvr.ma.ran.preds=data.frame(predict(cvr.ma.ran, addx=TRUE))
cvr.ma.fix.preds=data.frame(predict(cvr.ma.fix, addx=TRUE))
cvr.ma.un.preds=data.frame(predict(cvr.ma.un, addx=TRUE))
cvr.ma.ran.p=ggplot()+geom_point(data=dugcvr,aes(x=log(t_qsize_m2), y=yi,colour=id),# size=weights(cvr.ma.ran)),
alpha=0.3) +geom_line(aes(x=cvr.ma.ran.preds$X.mods, y=cvr.ma.ran.preds$pred))+geom_line(aes(x=cvr.ma.ran.preds$X.mods, y=cvr.ma.ran.preds$pred))+geom_ribbon(aes(x=cvr.ma.ran.preds$X.mods,ymin=cvr.ma.ran.preds$ci.lb, ymax=cvr.ma.ran.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(cvr)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed") +ggtitle("")+theme(plot.title = element_text(size = 8))+ylim(-1.6,1.2)
cvr.ma.fix.p=ggplot()+geom_point(data=dugcvr,aes(x=log(t_qsize_m2), y=yi,colour=id),# size=weights(cvr.ma.fix)),
alpha=0.3) +geom_line(aes(x=cvr.ma.fix.preds$X.mods, y=cvr.ma.fix.preds$pred))+geom_line(aes(x=cvr.ma.fix.preds$X.mods, y=cvr.ma.fix.preds$pred))+geom_ribbon(aes(x=cvr.ma.fix.preds$X.mods,ymin=cvr.ma.fix.preds$ci.lb, ymax=cvr.ma.fix.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(cvr)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed")+ggtitle("")+theme(plot.title = element_text(size = 8))+coord_cartesian(ylim = c(-1.6, 1.2))
cvr.ma.un.p=ggplot()+geom_point(data=dugcvr,aes(x=log(t_qsize_m2), y=yi,colour=id, size=1), alpha=0.3) +geom_line(aes(x=cvr.ma.fix.preds$X.mods, y=cvr.ma.un.preds$pred))+geom_line(aes(x=cvr.ma.un.preds$X.mods, y=cvr.ma.un.preds$pred))+geom_ribbon(aes(x=cvr.ma.un.preds$X.mods,ymin=cvr.ma.un.preds$ci.lb, ymax=cvr.ma.un.preds$ci.ub ),alpha=0.2)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(cvr)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed")+scale_size_continuous(guide=FALSE)+ggtitle("")+theme(plot.title = element_text(size = 8))+ylim(-1.6, 1.2)
gridExtra::grid.arrange(hg.ma.ran.p, lr.ma.ran.p,cvr.ma.ran.p,
hg.ma.fix.p, lr.ma.fix.p,cvr.ma.fix.p,
hg.ma.un.p, lr.ma.un.p,cvr.ma.fix.p,
ncol=3, heights=c(2,2,2.2))#+ylim(-3.2, 0.7)
Figure S11. Meta-regression slopes of models using hedges g, lnRR, and lnCVR against log(plot size). Each meta-regression is conducted as a random-effect, fixed-effects, and unweighted meta-analysis
This size-bias testing has only been conducted for the restored/unrestored comparison. The chunk below will re-run the same tests on the restored/reference comparison, however these plots will not be presented as they do not deviate significantly from the results just presented
dug <- read.csv("Data/variation_data.csv")#put data file here
dug<-dug %>% filter(r_quad_n >= 1)
duglr <- metafor::escalc(measure="ROM",m1i=dug$t_mean, m2i=dug$r_mean, sd1i=dug$t_sd, sd2i=r_sd, n1i=dug$t_quad_n, n2i=dug$r_quad_n, append=T, data=dug) #non-equal variances
#lnCVR
dugcvr <- metafor::escalc(measure="CVR",m1i=dug$t_mean, m2i=dug$r_mean, sd1i=dug$t_sd, sd2i=r_sd, n1i=dug$t_quad_n, n2i=dug$r_quad_n, append=T, data=dug)
#Hedges' g
dughg <- metafor::escalc(measure="SMD",m1i=dug$t_mean, m2i=dug$r_mean, sd1i=dug$t_sd, sd2i=r_sd, n1i=dug$t_quad_n, n2i=dug$r_quad_n, append=T, data=dug)
#alternative variance estimate for g
n1=as.numeric(dug$t_quad_n); n2=as.numeric(dug$c_quad_n)
n_tilde=n2*n1/(n2+n1)
var_d_n.DENS=((1-3/(4*(n2+n1-2)-1))^2)*(n2+n1-2)/(n_tilde*(n2+n1-4)) #Hedges variance that does not contain d https://esajournals.onlinelibrary.wiley.com/doi/full/10.1002/ecs2.2419
dughg$vi2<- var_d_n.DENS
dughg<-dughg %>% filter(vi2 > 0 ) # some SD = 0 mucking up the calcs below?
unit <- factor(1:length(duglr$yi))
duglr$unit <- unit
unit <- factor(1:length(dugcvr$yi))
dugcvr$unit <- unit
unit <- factor(1:length(dughg$yi))
dughg$unit <- unit
duglr<-duglr %>% drop_na(c(id, plot_id, unit))
dugcvr<-duglr %>% drop_na(c(id, plot_id, unit))
dughg<-dughg %>% drop_na(c(id, plot_id, unit))
duglr<-duglr %>% drop_na(t_qsize_m2)
dugcvr<-duglr %>% drop_na(t_qsize_m2)
dughg<-dughg %>% drop_na(t_qsize_m2)
#random-effects, conventional weighted meta-analysis
lr.ma.ran <- rma.mv(yi=yi, V=vi, data=duglr, method="REML", random = list(~1 | id, ~1 | plot_id, ~1 | unit))
#unweighted
lr.ma.un <- rma.mv(yi=yi, V=vi, data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed-effects, conventional weighted meta-analysis
lr.ma.fix <- rma.mv(yi=yi, V=vi, data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
#random-effects, conventional weighted meta-analysis
cvr.ma.ran <- rma.mv(yi=yi, V=vi, data=dugcvr, method="REML", random = list(~1 | id, ~1 | plot_id, ~1 | unit))
#unweighted
cvr.ma.un <- rma.mv(yi=yi, V=vi, data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed-effects, conventional weighted meta-analysis
cvr.ma.fix <- rma.mv(yi=yi, V=vi, data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
#random-effects, conventional weighted meta-analysis
hg.ma.ran <- rma.mv(yi=yi, V=vi, data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
#unweighted
hg.ma.un <- rma.mv(yi=yi, V=vi, data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed-effects, conventional weighted meta-analysis
hg.ma.fix <- rma.mv(yi=yi, V=vi, data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
hg.ma.ran.d_alt <- rma.mv(yi=yi, V=vi2, data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
hg.ma.fix.dalt <- rma.mv(yi=yi, V=vi2, data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi2)
duglr<-duglr %>% mutate(id = as.factor(id)) # currently thinks id is numeric - is that an issue?
dugcvr<-dugcvr %>% mutate(id = as.factor(id)) # currently thinks id is numeric - is that an issue?
dughg<-dughg %>% mutate(id = as.factor(id)) # currently thinks id is numeric - is that an issue?
NvsA.LR <- ggplot(duglr) + geom_point(aes(x=log(t_qsize_m2/10000), y=t_quad_n, size=1/vi,col=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic(N)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") + scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
NvsA.CVR <- ggplot(dugcvr) + geom_point(aes(x=log(t_qsize_m2/10000), y=t_quad_n, size=1/vi,col=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic(N)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") + scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
NvsA.g <- ggplot(dughg) + geom_point(aes(x=log(t_qsize_m2/10000), y=t_quad_n, size=1/vi, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic(N)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") + scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
LRvsA <- ggplot(duglr) + geom_point(aes(x=log(t_qsize_m2/10000), y=yi, size=1/vi, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic("LR")))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") + scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("study")+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
CVRvsA <- ggplot(dugcvr) + geom_point(aes(x=log(t_qsize_m2/10000), y=yi, size=1/vi, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic("CVR")))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") + scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("study")+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
gvsA <- ggplot(dughg) + geom_point(aes(x=log(t_qsize_m2/10000), y=yi, size=1/vi, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(italic(g)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") +scale_size_continuous(name = expression(paste("1/",italic(V))),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
LR.VarvsA <- ggplot(duglr) + geom_point(aes(x=log(t_qsize_m2/10000), y=vi, size=t_quad_n, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(paste("Variance of ",italic(LR))))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") +scale_size_continuous(name = expression(italic(N)),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
CVR.VarvsA <- ggplot(dugcvr) + geom_point(aes(x=log(t_qsize_m2/10000), y=vi, size=t_quad_n, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(paste("Variance of ",italic(CVR))))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") +scale_size_continuous(name = expression(italic(N)),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text.x=element_text(size=rel(0.7)))
g.VarvsA <- ggplot(dughg) + geom_point(aes(x=log(t_qsize_m2/10000), y=vi, size=t_quad_n, color=id,alpha=0.3))+ theme_bw() + theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"))+ ylab(expression(paste("Variance of ",italic(g))))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed") +scale_size_continuous(name = expression(italic(N)),labels=NULL)+scale_color_discrete("", guide=F)+scale_alpha("",guide=F)+
theme(plot.title = element_text(size = 8))+theme(axis.text=element_text(size=rel(0.7)))
gridExtra::grid.arrange(NvsA.g, gvsA, g.VarvsA,NvsA.LR, LRvsA,LR.VarvsA, NvsA.CVR, CVRvsA,CVR.VarvsA, ncol=3)
hdeff <- data.frame(estimate=c(hg.ma.ran$b,hg.ma.un$b,hg.ma.fix$b,hg.ma.ran.d_alt$b,hg.ma.fix.dalt$b),ci.up=c(hg.ma.ran$ci.ub,hg.ma.un$ci.ub,hg.ma.fix$ci.ub, hg.ma.ran.d_alt$ci.ub,hg.ma.fix.dalt$ci.ub), ci.lo=c(hg.ma.ran$ci.lb,hg.ma.un$ci.lb,hg.ma.fix$ci.lb,hg.ma.ran.d_alt$ci.lb,hg.ma.fix.dalt$ci.lb), weighting=c("R", "U", "F", "R", "F"), vtype=c("d","d","d","d_alt","d_alt"))
hdeff <- hdeff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
hdeff.p.a <-ggplot(hdeff) + geom_point(aes(y = estimate, x = weighting, colour=vtype), position=position_dodge(width = 0.5)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1, colour=vtype),, position=position_dodge(width = 0.5))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed",) +
xlab(NULL) +
ylab(expression(italic(g)))+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
hdeff.p.a <-hdeff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold'))) +scale_color_manual(values=c("black", "darkgray"))
lreff <- data.frame(estimate=c(lr.ma.ran$b,lr.ma.un$b,lr.ma.fix$b),ci.up=c(lr.ma.ran$ci.ub,lr.ma.un$ci.ub,lr.ma.fix$ci.ub), ci.lo=c(lr.ma.ran$ci.lb,lr.ma.un$ci.lb,lr.ma.fix$ci.lb), weighting=c("R", "U", "F"))
lreff <- lreff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
lreff.p.a <-ggplot(lreff) + geom_point(aes(y = estimate, x = weighting)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed") +
xlab(NULL) +
ylab(expression(italic(LR)))+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
lreff.p.a <-lreff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold')))
cvreff <- data.frame(estimate=c(cvr.ma.ran$b,cvr.ma.un$b,cvr.ma.fix$b),ci.up=c(cvr.ma.ran$ci.ub,cvr.ma.un$ci.ub,cvr.ma.fix$ci.ub), ci.lo=c(cvr.ma.ran$ci.lb,cvr.ma.un$ci.lb,cvr.ma.fix$ci.lb), weighting=c("R", "U", "F"))
cvreff <- cvreff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
cvreff.p.a <-ggplot(cvreff) + geom_point(aes(y = estimate, x = weighting)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed") +
xlab(NULL) +
ylab(expression(italic(cvr)))+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
cvreff.p.a <-cvreff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold')))
gridExtra::grid.arrange(hdeff.p.a, lreff.p.a, cvreff.p.a, ncol=3, widths = c(3, 2.3, 2.3))
#LR
#random, conventionally weighted
lr.ma.ran <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
# unweighted
lr.ma.un <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed effect
lr.ma.fix <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
#cvr
#random, conventionally weighted
cvr.ma.ran <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
# unweighted
cvr.ma.un <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed effect
cvr.ma.fix <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
#HG
#random, conventionally weighted
hg.ma.ran <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
# unweighted
hg.ma.un <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#fixed effects
hg.ma.fix <- rma.mv(yi=scale(yi), V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
hg.ma.ran.d_alt <- rma.mv(yi=scale(yi), V=vi2, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
hg.ma.fix.dalt <- rma.mv(yi=scale(yi), V=vi2, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi2)
hdeff <- data.frame(estimate=c(hg.ma.ran$b[2],hg.ma.un$b[2],hg.ma.fix$b[2],hg.ma.ran.d_alt$b[2],hg.ma.fix.dalt$b[2]),ci.up=c(hg.ma.ran$ci.ub[2],hg.ma.un$ci.ub[2],hg.ma.fix$ci.ub[2], hg.ma.ran.d_alt$ci.ub[2],hg.ma.fix.dalt$ci.ub[2]), ci.lo=c(hg.ma.ran$ci.lb[2],hg.ma.un$ci.lb[2],hg.ma.fix$ci.lb[2],hg.ma.ran.d_alt$ci.lb[2],hg.ma.fix.dalt$ci.lb[2]), weighting=c("R", "U", "F", "R", "F"), vtype=c("d","d","d","d_alt","d_alt"))
hdeff <- hdeff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
hdeff.p.a <-ggplot(hdeff) + geom_point(aes(y = estimate, x = weighting, colour=vtype), position=position_dodge(width = 0.5)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1, colour=vtype),, position=position_dodge(width = 0.5))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed",) +
xlab(NULL) +
ylab("Effect of plot size (regression coefficient)")+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
hdeff.p.a <-hdeff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold')))+ylim(-1,1.2) +scale_color_manual(values=c("black", "darkgray"), guide=F)
lreff <- data.frame(estimate=c(lr.ma.ran$b[2],lr.ma.un$b[2],lr.ma.fix$b[2]),ci.up=c(lr.ma.ran$ci.ub[2],lr.ma.un$ci.ub[2],lr.ma.fix$ci.ub[2]), ci.lo=c(lr.ma.ran$ci.lb[2],lr.ma.un$ci.lb[2],lr.ma.fix$ci.lb[2]), weighting=c("R", "U", "F"))
lreff <- lreff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
lreff.p.a <-ggplot(lreff) + geom_point(aes(y = estimate, x = weighting)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed") +
xlab(NULL) +
ylab("Effect of plot size (regression coefficient)")+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
lreff.p.a <-lreff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold')))+ylim(-1.2,1.5)
cvreff <- data.frame(estimate=c(cvr.ma.ran$b[2],cvr.ma.un$b[2],cvr.ma.fix$b[2]),ci.up=c(cvr.ma.ran$ci.ub[2],cvr.ma.un$ci.ub[2],cvr.ma.fix$ci.ub[2]), ci.lo=c(cvr.ma.ran$ci.lb[2],cvr.ma.un$ci.lb[2],cvr.ma.fix$ci.lb[2]), weighting=c("R", "U", "F"))
cvreff <- cvreff %>%
arrange(weighting) %>% # First sort by val. This sort the dataframe but NOT the factor levels
mutate(weighting=factor(weighting, levels=
c("R", "F", "U"))) # This trick update the factor levels
cvreff.p.a <-ggplot(cvreff) + geom_point(aes(y = estimate, x = weighting)) + geom_errorbar(aes(x=weighting,ymin=ci.lo, ymax=ci.up, width = 0.1))+
geom_abline(intercept = 0, slope=0, colour = "darkgray", linetype="dashed") +
xlab(NULL) +
ylab("Effect of plot size (regression coefficient)")+
theme_bw() +
theme(plot.title = element_text(size=10),axis.title = element_text(size=10),axis.text = element_text(size=9) )
cvreff.p.a <-cvreff.p.a +theme(axis.text.x = element_text(angle=0,face = c(rep('plain',16), 'bold', 'bold')))+ylim(-1.2,1.5)
gridExtra::grid.arrange(hdeff.p.a, lreff.p.a, cvreff.p.a, ncol=3, widths=c(3,2.3, 2.3))
hg.ma.ran <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
#random unweighted (same meta-est if fixed unweighted, but diff se)
hg.ma.un <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#random effect but control the weights, do 1/v. same est as a fixed effect
hg.ma.fix <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
hg.ma.ran.d_alt <- rma.mv(yi=yi, V=vi2, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
hg.ma.fix.dalt <- rma.mv(yi=yi, V=vi2, mods=log(t_qsize_m2), data=dughg, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi2)
lr.ma.ran <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
#random unweighted (same meta-est if fixed unweighted, but diff se)
lr.ma.un <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#random effect but control the weights, do 1/v. same est as a fixed effect
lr.ma.fix <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=duglr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
cvr.ma.ran <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit))
#random unweighted (same meta-est if fixed unweighted, but diff se)
cvr.ma.un <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W=1)
#random effect but control the weights, do 1/v. same est as a fixed effect
cvr.ma.fix <- rma.mv(yi=yi, V=vi, mods=log(t_qsize_m2), data=dugcvr, method="REML", random= list(~1 | id, ~1 | plot_id, ~1 | unit), W = 1/vi)
newmods=data.frame(intercept=hg.ma.ran$b[1], t_qsize_m2=seq(min(dughg$t_qsize_m2), max(dughg$t_qsize_m2), 0.1) )
newmods=as.matrix(newmods)
hg.ma.ran.preds=data.frame(predict(hg.ma.ran, addx=TRUE))
hg.ma.fix.preds=data.frame(predict(hg.ma.fix, addx=TRUE))
hg.ma.un.preds=data.frame(predict(hg.ma.un, addx=TRUE))
hg.ma.ran.p=ggplot()+geom_point(data=dughg,aes(x=log(t_qsize_m2), y=yi,colour=id),
#size=weights(hg.ma.ran)),
alpha=0.3) +geom_line(aes(x=hg.ma.ran.preds$X.mods, y=hg.ma.ran.preds$pred))+geom_line(aes(x=hg.ma.ran.preds$X.mods, y=hg.ma.ran.preds$pred))+geom_ribbon(aes(x=hg.ma.ran.preds$X.mods,ymin=hg.ma.ran.preds$ci.lb, ymax=hg.ma.ran.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(g)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed") +ggtitle(expression(paste("Random-effects meta-analysis, wt = 1/(", italic("V"),"+",tau^2,")")))+theme(plot.title = element_text(size = 8))+ylim(-12,7.2)
hg.ma.fix.p=ggplot()+geom_point(data=dughg,aes(x=log(t_qsize_m2), y=yi,colour=id), #size=weights(hg.ma.fix)),
alpha=0.3) +geom_line(aes(x=hg.ma.fix.preds$X.mods, y=hg.ma.fix.preds$pred))+geom_line(aes(x=hg.ma.fix.preds$X.mods, y=hg.ma.fix.preds$pred))+geom_ribbon(aes(x=hg.ma.fix.preds$X.mods,ymin=hg.ma.fix.preds$ci.lb, ymax=hg.ma.fix.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(g)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed")+ggtitle(expression(paste("Fixed-effects meta-analysis, wt = 1/(", italic("V"),")")))+theme(plot.title = element_text(size = 8))+ylim(-12,7.2)
hg.ma.un.p=ggplot()+geom_point(data=dughg,aes(x=log(t_qsize_m2), y=yi,colour=id, size=1), alpha=0.3) +geom_line(aes(x=hg.ma.fix.preds$X.mods, y=hg.ma.un.preds$pred))+geom_line(aes(x=hg.ma.un.preds$X.mods, y=hg.ma.un.preds$pred))+geom_ribbon(aes(x=hg.ma.un.preds$X.mods,ymin=hg.ma.un.preds$ci.lb, ymax=hg.ma.un.preds$ci.ub ),alpha=0.2)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(g)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed")+scale_size_continuous(guide=FALSE)+ggtitle("Unweighted meta-analysis, wt = 1")+theme(plot.title = element_text(size = 8))+ylim(-12,7.2)
newmods=data.frame(intercept=lr.ma.ran$b[1], t_qsize_m2=seq(min(duglr$t_qsize_m2), max(duglr$t_qsize_m2), 0.1) )
newmods=as.matrix(newmods)
head(newmods)
lr.ma.ran.preds=data.frame(predict(lr.ma.ran, addx=TRUE))
lr.ma.fix.preds=data.frame(predict(lr.ma.fix, addx=TRUE))
lr.ma.un.preds=data.frame(predict(lr.ma.un, addx=TRUE))
lr.ma.ran.p=ggplot()+geom_point(data=duglr,aes(x=log(t_qsize_m2), y=yi,colour=id),# size=weights(lr.ma.ran)),
alpha=0.3) +geom_line(aes(x=lr.ma.ran.preds$X.mods, y=lr.ma.ran.preds$pred))+geom_line(aes(x=lr.ma.ran.preds$X.mods, y=lr.ma.ran.preds$pred))+geom_ribbon(aes(x=lr.ma.ran.preds$X.mods,ymin=lr.ma.ran.preds$ci.lb, ymax=lr.ma.ran.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(LR)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed") +ggtitle("")+theme(plot.title = element_text(size = 8))+ylim(-1.6,1.2)
lr.ma.fix.p=ggplot()+geom_point(data=duglr,aes(x=log(t_qsize_m2), y=yi,colour=id),# size=weights(lr.ma.fix)),
alpha=0.3) +geom_line(aes(x=lr.ma.fix.preds$X.mods, y=lr.ma.fix.preds$pred))+geom_line(aes(x=lr.ma.fix.preds$X.mods, y=lr.ma.fix.preds$pred))+geom_ribbon(aes(x=lr.ma.fix.preds$X.mods,ymin=lr.ma.fix.preds$ci.lb, ymax=lr.ma.fix.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(LR)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed")+ggtitle("")+theme(plot.title = element_text(size = 8))+coord_cartesian(ylim = c(-1.6, 1.2))
lr.ma.un.p=ggplot()+geom_point(data=duglr,aes(x=log(t_qsize_m2), y=yi,colour=id, size=1), alpha=0.3) +geom_line(aes(x=lr.ma.fix.preds$X.mods, y=lr.ma.un.preds$pred))+geom_line(aes(x=lr.ma.un.preds$X.mods, y=lr.ma.un.preds$pred))+geom_ribbon(aes(x=lr.ma.un.preds$X.mods,ymin=lr.ma.un.preds$ci.lb, ymax=lr.ma.un.preds$ci.ub ),alpha=0.2)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(LR)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed")+scale_size_continuous(guide=FALSE)+ggtitle("")+theme(plot.title = element_text(size = 8))+ylim(-1.6, 1.2)
newmods=data.frame(intercept=cvr.ma.ran$b[1], t_qsize_m2=seq(min(dugcvr$t_qsize_m2), max(dugcvr$t_qsize_m2), 0.1) )
newmods=as.matrix(newmods)
cvr.ma.ran.preds=data.frame(predict(cvr.ma.ran, addx=TRUE))
cvr.ma.fix.preds=data.frame(predict(cvr.ma.fix, addx=TRUE))
cvr.ma.un.preds=data.frame(predict(cvr.ma.un, addx=TRUE))
cvr.ma.ran.p=ggplot()+geom_point(data=dugcvr,aes(x=log(t_qsize_m2), y=yi,colour=id),# size=weights(cvr.ma.ran)),
alpha=0.3) +geom_line(aes(x=cvr.ma.ran.preds$X.mods, y=cvr.ma.ran.preds$pred))+geom_line(aes(x=cvr.ma.ran.preds$X.mods, y=cvr.ma.ran.preds$pred))+geom_ribbon(aes(x=cvr.ma.ran.preds$X.mods,ymin=cvr.ma.ran.preds$ci.lb, ymax=cvr.ma.ran.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(cvr)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed") +ggtitle("")+theme(plot.title = element_text(size = 8))+ylim(-1.6,1.2)
cvr.ma.fix.p=ggplot()+geom_point(data=dugcvr,aes(x=log(t_qsize_m2), y=yi,colour=id),# size=weights(cvr.ma.fix)),
alpha=0.3) +geom_line(aes(x=cvr.ma.fix.preds$X.mods, y=cvr.ma.fix.preds$pred))+geom_line(aes(x=cvr.ma.fix.preds$X.mods, y=cvr.ma.fix.preds$pred))+geom_ribbon(aes(x=cvr.ma.fix.preds$X.mods,ymin=cvr.ma.fix.preds$ci.lb, ymax=cvr.ma.fix.preds$ci.ub ),alpha=0.2)+scale_size_continuous(guide=FALSE)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(cvr)))+xlab(NULL)+geom_hline(yintercept = 0, linetype = "dashed")+ggtitle("")+theme(plot.title = element_text(size = 8))+coord_cartesian(ylim = c(-1.6, 1.2))
cvr.ma.un.p=ggplot()+geom_point(data=dugcvr,aes(x=log(t_qsize_m2), y=yi,colour=id, size=1), alpha=0.3) +geom_line(aes(x=cvr.ma.fix.preds$X.mods, y=cvr.ma.un.preds$pred))+geom_line(aes(x=cvr.ma.un.preds$X.mods, y=cvr.ma.un.preds$pred))+geom_ribbon(aes(x=cvr.ma.un.preds$X.mods,ymin=cvr.ma.un.preds$ci.lb, ymax=cvr.ma.un.preds$ci.ub ),alpha=0.2)+scale_color_discrete(guide=F)+theme_bw()+ylab(expression(italic(cvr)))+xlab("Log(Plot size (ha))")+geom_hline(yintercept = 0, linetype = "dashed")+scale_size_continuous(guide=FALSE)+ggtitle("")+theme(plot.title = element_text(size = 8))+ylim(-1.6, 1.2)
gridExtra::grid.arrange(hg.ma.ran.p, lr.ma.ran.p,cvr.ma.ran.p,
hg.ma.fix.p, lr.ma.fix.p,cvr.ma.fix.p,
hg.ma.un.p, lr.ma.un.p,cvr.ma.fix.p,
ncol=3, heights=c(2,2,2.2))#+ylim(-3.2, 0.7)
# studies with all three comparisons
re_ref %>% drop_na(c_mean, r_mean) %>% dplyr::select(id) %>% distinct()
# taxon breakdown
full_data %>% group_by(.$taxon) %>% summarise(n())
# metric breakdown
full_data %>% group_by(.$measure_type) %>% summarise(n())
# metric breakdown
full_data %>% group_by(.$plu) %>% summarise(n())
# size breakdown
full_data %>% drop_na(site_size, r_mean) %>% dplyr::summarise(n())
#final triple check of model values against in-text values
summary(mean_ur)
exp(.1815)
summary(cvr_ur)
exp(-0.1519)
summary(mean_rr)
exp(-0.1395)
summary(cvr_rr)
exp(0.183)
summary(mean_age_ur)
exp(0.006)
summary(cvr_age_ur)
summary(mean_age_rr)
summary(cvr_age_rr)
summary(mean_size_ur)
summary(cvr_size_ur)
summary(mean_size_rr)
summary(cvr_size_rr)
# resotration method breakdown
full_data %>% select(id, restoration_method) %>% distinct() %>% group_by(restoration_method) %>% summarise(n())
# number of studies for each separate MA
full_data %>% drop_na(c_mean) %>% dplyr::select(id) %>% distinct() %>% summarise(n())
full_data %>% drop_na(r_mean) %>% dplyr::select(id) %>% distinct() %>% summarise(n())
full_data %>% drop_na(r_mean, c_mean) %>% dplyr::select(id) %>% distinct() %>% summarise(n())
full_data %>% select(id) %>% distinct() %>% summarise(n())
library(purrr)
library(multcomp)
get_pred1 <- function(model, mod = " ") {
name <- name <- firstup(as.character(stringr::str_replace(row.names(model$beta),
mod, "")))
len <- length(name)
if (len != 1) {
newdata <- matrix(NA, ncol = len, nrow = len)
for (i in 1:len) {
pos <- which(model$X[, i] == 1)[[1]]
newdata[, i] <- model$X[pos, ]
}
pred <- metafor::predict.rma(model, newmods = newdata)
} else {
pred <- metafor::predict.rma(model)
}
estimate <- pred$pred
lowerCL <- pred$ci.lb
upperCL <- pred$ci.ub
lowerPR <- pred$cr.lb
upperPR <- pred$cr.ub
table <- tibble(name = factor(name, levels = name, labels = name), estimate = estimate,
lowerCL = lowerCL, upperCL = upperCL, pval = model$pval, lowerPR = lowerPR,
upperPR = upperPR)
}
get_pred2 <- function(model, mod = " ") {
name <- as.factor(str_replace(row.names(model$beta), paste0("relevel", "\\(",
mod, ", ref = name", "\\)"), ""))
len <- length(name)
if (len != 1) {
newdata <- diag(len)
pred <- predict.rma(model, intercept = FALSE, newmods = newdata[, -1])
} else {
pred <- predict.rma(model)
}
estimate <- pred$pred
lowerCL <- pred$ci.lb
upperCL <- pred$ci.ub
lowerPR <- pred$cr.lb
upperPR <- pred$cr.ub
table <- tibble(name = factor(name, levels = name, labels = name), estimate = estimate,
lowerCL = lowerCL, upperCL = upperCL, pval = model$pval, lowerPR = lowerPR,
upperPR = upperPR)
}
uni_mod_plot<-function(m, df, log_ratio, response, variance){
p <- predict.rma(m)
df %>% mutate(ymin = p$ci.lb,
ymax = p$ci.ub, ymin2 = p$cr.lb,
ymax2 = p$cr.ub, pred = p$pred) %>%
ggplot(aes(x = response, y = log_ratio, size = sqrt(1/variance))) + geom_point(shape = 21, alpha= 0.2,
fill = "grey90") +
geom_hline(yintercept = 0, size = .5, colour = "gray70")+
geom_smooth(aes(y = ymin2), method = "lm", se = FALSE, lty = "solid", lwd = 0.75,
colour = "#0072B2") + geom_smooth(aes(y = ymax2), method = "lm", se = FALSE,
lty = "solid", lwd = 0.75, colour = "#0072B2") + geom_smooth(aes(y = ymin),
method = "lm", se = FALSE, lty = "dashed", lwd = 0.75, colour = "#D55E00") +
geom_smooth(aes(y = ymax), method = "lm", se = FALSE, lty = "solid", lwd = 0.75,
colour = "#D55E00") + geom_smooth(aes(y = pred), method = "lm", se = FALSE,
lty = "solid", lwd = 1, colour = "black") +
labs(x = "\n ln(restoration site age)", y = "ln(restored/unrestored) - mean biodiversity", size = "Precision (1/SE)") + guides(fill = "none",
colour = "none") + # themses
theme_classic() + theme(legend.position = c(0, 1), legend.justification = c(0, 1)) + theme(legend.direction = "horizontal") +
theme(legend.background = element_blank()) + theme(axis.text.y = element_text(size = 8,
colour = "black", hjust = 0.5, angle = 90))+
coord_cartesian(ylim = c(-2.5, 2.5))+
scale_y_continuous(limits = c(-2.5, 2.5),
breaks = c(-2, -1, 0, 1, 2),
labels = c("\n \n -2", "100% decrease \n \n -1", "\n \n 0.0", "100% increase \n \n 1", "\n \n2")) +
theme(legend.position = "none")
}
uni_mod_plot_ns<-function(m, df, log_ratio, response, variance){
p <- predict.rma(m)
df %>% mutate(ymin = p$ci.lb,
ymax = p$ci.ub, ymin2 = p$cr.lb,
ymax2 = p$cr.ub, pred = p$pred) %>%
ggplot(aes(x = response, y = log_ratio, size = sqrt(1/variance))) + geom_point(shape = 21, alpha= 0.2,
fill = "grey90") +
geom_hline(yintercept = 0, size = .5, colour = "gray70")+
geom_smooth(aes(y = ymin2), method = "lm", se = FALSE, lty = "dashed", lwd = 0.75,
colour = "#0072B2") + geom_smooth(aes(y = ymax2), method = "lm", se = FALSE,
lty = "dashed", lwd = 0.75, colour = "#0072B2") + geom_smooth(aes(y = ymin),
method = "lm", se = FALSE, lty = "dashed", lwd = 0.75, colour = "#D55E00") +
geom_smooth(aes(y = ymax), method = "lm", se = FALSE, lty = "dashed", lwd = 0.75,
colour = "#D55E00") + geom_smooth(aes(y = pred), method = "lm", se = FALSE,
lty = "dashed", lwd = 1, colour = "black") +
labs(x = "\n ln(restoration site age)", y = "ln(restored/unrestored) - mean biodiversity", size = "Precision (1/SE)") + guides(fill = "none",
colour = "none") + # themses
theme_classic() + theme(legend.position = c(0, 1), legend.justification = c(0, 1)) + theme(legend.direction = "horizontal") +
theme(legend.background = element_blank()) + theme(axis.text.y = element_text(size = 8,
colour = "black", hjust = 0.5, angle = 90))+
coord_cartesian(ylim = c(-2.5, 2.5))+
scale_y_continuous(limits = c(-2.5, 2.5),
breaks = c(-2, -1, 0, 1, 2),
labels = c("\n \n -2", "100% decrease \n \n -1", "\n \n 0.0", "100% increase \n \n 1", "\n \n2")) +
theme(legend.position = "none")
}
dat<-read.csv("Data/variation_data.csv")
Below are three tables that summarise various subgroups within the data including: the breakdown of broad vegetation types, categorised into woody/non-woody. These are very coarse categories and “woody” encompasses a large range of vegetation types from woodland to shrubland to rainforest. Non-woody is a catch-all for herbaceous vegetation communities, e.g. prairie, forb- or herb-dominated ecosystems.
Table S11 Number of effect sizes included in the meta-analysis by dominant vegetation
df<-dat
df %>% group_by(woody_nonwoody) %>% summarise(n()) %>% rename(`Dominant vegetation type` = woody_nonwoody, `Number of effect sizes` = `n()`) %>% kable("html") %>%
kable_styling("striped", position = "left")
Dominant vegetation type | Number of effect sizes |
---|---|
nonwoody | 406 |
woody | 583 |
hile broad taxonomic groups were used for subgroup analyses in the main-text, we include here the more detailed notes on taxon collected during the literature search which may be of additional interest.
Table S12 Number of effect sizes included in the meta-analysis by taxon
df %>% group_by(taxon, taxon_detail) %>% summarise(n()) %>% rename(Taxon = taxon, Taxon_detail = taxon_detail, `Number of effect sizes` = `n()`) %>% kable("html") %>%
kable_styling("striped", position = "left") %>%
scroll_box(width = "800px", height = "300px")
Taxon | Taxon_detail | Number of effect sizes |
---|---|---|
amoebae | amoebae | 12 |
fungi | fungi | 41 |
invertebrates | ants | 3 |
invertebrates | arthropods | 55 |
invertebrates | bees | 12 |
invertebrates | beetles | 58 |
invertebrates | birds | 1 |
invertebrates | butterflies | 14 |
invertebrates | diptera | 9 |
invertebrates | dragonflies | 4 |
invertebrates | epigeic beetles | 2 |
invertebrates | floricolous beetles | 2 |
invertebrates | invertebrates | 14 |
invertebrates | leafhoppers | 1 |
invertebrates | Lepidoptera | 2 |
invertebrates | mites | 8 |
invertebrates | moths | 2 |
invertebrates | nematodes | 21 |
invertebrates | odonata | 2 |
invertebrates | orthoptera | 35 |
invertebrates | pollinators | 4 |
invertebrates | reptiles | 2 |
invertebrates | saproxylic beetles | 2 |
invertebrates | spiders | 13 |
invertebrates | termites | 9 |
invertebrates | vascular plants | 2 |
invertebrates | vegetation | 3 |
plants | bryophytes | 2 |
plants | Eurasian steppe | 6 |
plants | ferns | 8 |
plants | grassland | 35 |
plants | herbs | 10 |
plants | lichens | 8 |
plants | pollinators | 1 |
plants | seedbank | 9 |
plants | seeds | 2 |
plants | shrubs | 2 |
plants | steppe | 28 |
plants | trees | 2 |
plants | understorey plants | 9 |
plants | vascular plants | 3 |
plants | vegetation | 478 |
plants | woody plants | 5 |
soil microbes | soil microbes | 6 |
vertebrates | amphibians | 3 |
vertebrates | bats | 3 |
vertebrates | birds | 12 |
vertebrates | reptiles | 3 |
vertebrates | small-medium mammals | 15 |
vertebrates | small mammals | 6 |
While we conducted all analyses through the lens of mean “biodiversity” and variability of “biodiversity”, biodiversity can be measured in many different ways. Below we detail the variety of measures of biodiversity included in the meta-analysis.
Table S13 Number of effect sizes included in the meta-analysis by measure of biodiversity
df %>% group_by(measure_type, measure) %>% summarise(n()) %>% rename(Measure = measure, Measure_detail = measure_type, `Number of effect sizes` = `n()`) %>% kable("html") %>%
kable_styling("striped", position = "left")%>%
scroll_box(width = "800px", height = "300px")
Measure_detail | Measure | Number of effect sizes |
---|---|---|
functional | func_disp | 11 |
functional | func_div | 66 |
functional | func_even | 55 |
functional | func_rich | 66 |
functional | RaoQ | 45 |
index | even | 58 |
index | pielou | 12 |
index | shan_div | 16 |
index | Shan_div | 127 |
index | Simp_div | 34 |
index | struc_div | 1 |
phylogenetic | phylo_div | 9 |
taxonomic | Chao1 | 9 |
taxonomic | Chao2 | 4 |
taxonomic | Jack1 | 3 |
taxonomic | rare_sp_rich | 20 |
taxonomic | sp_div | 30 |
taxonomic | sp_rich | 422 |
taxonomic | taxo_distinct | 1 |
Table S14 Number of effect sizes included in the meta-analysis by measure of biodiversity
df %>% group_by(taxon, measure) %>% summarise(n()) %>% rename(Measure = measure, Taxon = taxon, `Number of effect sizes` = `n()`) %>% kable("html") %>%
kable_styling("striped", position = "left")%>%
scroll_box(width = "800px", height = "300px")
Taxon | Measure | Number of effect sizes |
---|---|---|
amoebae | Shan_div | 6 |
amoebae | sp_rich | 6 |
fungi | Chao1 | 8 |
fungi | rare_sp_rich | 3 |
fungi | Shan_div | 11 |
fungi | Simp_div | 8 |
fungi | sp_rich | 11 |
invertebrates | Chao2 | 3 |
invertebrates | even | 29 |
invertebrates | func_disp | 3 |
invertebrates | func_even | 3 |
invertebrates | func_rich | 9 |
invertebrates | Jack1 | 3 |
invertebrates | pielou | 3 |
invertebrates | rare_sp_rich | 17 |
invertebrates | shan_div | 4 |
invertebrates | Shan_div | 35 |
invertebrates | Simp_div | 9 |
invertebrates | sp_div | 8 |
invertebrates | sp_rich | 153 |
invertebrates | taxo_distinct | 1 |
plants | Chao1 | 1 |
plants | even | 29 |
plants | func_disp | 5 |
plants | func_div | 62 |
plants | func_even | 48 |
plants | func_rich | 53 |
plants | phylo_div | 9 |
plants | pielou | 9 |
plants | RaoQ | 45 |
plants | shan_div | 12 |
plants | Shan_div | 72 |
plants | Simp_div | 17 |
plants | sp_div | 7 |
plants | sp_rich | 238 |
plants | struc_div | 1 |
soil microbes | sp_div | 6 |
vertebrates | Chao2 | 1 |
vertebrates | func_disp | 3 |
vertebrates | func_div | 4 |
vertebrates | func_even | 4 |
vertebrates | func_rich | 4 |
vertebrates | Shan_div | 3 |
vertebrates | sp_div | 9 |
vertebrates | sp_rich | 14 |
###########################
## UNRESTORED / RESTORED ##
###########################
# un_re = unrestored / restored
un_re<-read.csv("Data/variation_data.csv", stringsAsFactors = F)
un_re$c_quad_n = as.numeric(un_re$c_quad_n)
un_re$c_mean = as.numeric(un_re$c_mean)
un_re$c_sd = as.numeric(un_re$c_sd)
#remove studies with only a restored sites comparison
un_re<-un_re[!is.na(un_re$c_mean),]
#un_re %>% group_by(id, c_mean, c_sd) %>% distinct(shared_ctrl) %>% filter(n()>1) # checking shared controls is accurate
#calculate the lnCVR and lnRR and lnVR effect size and un_reiance with escalc
CVR<-escalc(measure = "CVR", n1i = un_re$t_quad_n, n2i = un_re$c_quad_n, m1i = un_re$t_mean, m2i = un_re$c_mean, sd1i = un_re$t_sd, sd2i = un_re$c_sd)
lnRR<-escalc(measure = "ROM", n1i = un_re$t_quad_n, n2i = un_re$c_quad_n, m1i = un_re$t_mean, m2i = un_re$c_mean, sd1i = un_re$t_sd, sd2i = un_re$c_sd)
lnVR<-escalc(measure = "VR", n1i = un_re$t_quad_n, n2i = un_re$c_quad_n, m1i = un_re$t_mean, m2i = un_re$c_mean, sd1i = un_re$t_sd, sd2i = un_re$c_sd)
#combined effect sizes with relevant un_rea frames
un_re <-bind_cols(un_re, lnRR, lnVR, CVR)
# name the un_rea something meaningful and remove all the columns unneeded
un_re<-un_re %>% rename(yi_mean = yi...36, vi_mean = vi...37, yi_vr = yi...38, vi_vr = vi...39, yi_cvr = yi...40, vi_cvr = vi...41)
#remove studies that have vi=NA - usually where control SD = 0
un_re<-un_re[!is.na(un_re$vi_vr),]
un_re$plu<-as.factor(un_re$plu)
un_re$plu<-relevel(un_re$plu, "semi-natural")
#need another random factor for 'unit'
unit <- factor(1:length(un_re$yi_mean))
un_re$unit <- unit
vcv_cvr<-make_VCV_matrix(un_re, V ="vi_cvr", "shared_ctrl", "unit", rho=0.5)
vcv_mean<-make_VCV_matrix(un_re, V ="vi_mean", "shared_ctrl", "unit", rho=0.5)
vcv_vr<-make_VCV_matrix(un_re, V ="vi_vr", "shared_ctrl", "unit", rho=0.5)
##########################
## RESTORED / REFERENCE ##
##########################
# re_ref = restored / reference
re_ref<-read.csv("Data/variation_data.csv", stringsAsFactors = F)
#remove studies with only a degraded site comparison
re_ref<-re_ref[!is.na(re_ref$r_mean),]
#remove studies that have vi=NA - usually where control SD = 0
re_ref<-re_ref %>% filter(r_sd != 0)
re_ref<-re_ref %>% filter(!is.na(r_sd))
# there is a few sites where the reference control is shared, but the degraded one is not, need to add a "ref_shared_ctrl" to correct this
re_ref<-re_ref %>% group_by(id, r_mean, r_sd) %>% mutate(ref_shared_ctrl = cur_group_id())
#re_ref %>% group_by(id, r_mean, r_sd) %>% distinct(ref_shared_ctrl) %>% filter(n()>1) # to check any errors in the shared_control tagging
re_ref$r_quad_n = as.numeric(re_ref$r_quad_n)
re_ref$r_mean = as.numeric(re_ref$r_mean)
re_ref$r_sd = as.numeric(re_ref$r_sd)
re_ref<-re_ref %>% filter(r_quad_n > 1) # a few sample sizes of 1 or 0?
#calculate the lnCVR and lnRR effect size and re_refiance with escalc
CVR<-escalc(measure = "CVR", n1i = re_ref$t_quad_n, n2i = re_ref$r_quad_n, m1i = re_ref$t_mean, m2i = re_ref$r_mean, sd1i = re_ref$t_sd, sd2i = re_ref$r_sd)
lnRR<-escalc(measure = "ROM", n1i = re_ref$t_quad_n, n2i = re_ref$r_quad_n, m1i = re_ref$t_mean, m2i = re_ref$r_mean, sd1i = re_ref$t_sd, sd2i = re_ref$r_sd)
lnVR<-escalc(measure = "VR", n1i = re_ref$t_quad_n, n2i = re_ref$r_quad_n, m1i = re_ref$t_mean, m2i = re_ref$r_mean, sd1i = re_ref$t_sd, sd2i = re_ref$r_sd)
#combined effect sizes with relevant data frames
re_ref <-bind_cols(re_ref, lnRR, lnVR, CVR)
# name the data something meaningful and remove all the columns unneeded
re_ref<-re_ref %>% rename(yi_mean = yi...37, vi_mean = vi...38, yi_vr = yi...39, vi_vr = vi...40, yi_cvr = yi...41, vi_cvr = vi...42)
re_ref$plu<-as.factor(re_ref$plu)
re_ref$plu<-relevel(re_ref$plu, "semi-natural")
#need another random factor for 'unit'
unit <- factor(1:length(re_ref$yi_mean))
re_ref$unit <- unit
re_ref<-as.data.frame(re_ref) # the group_by to do the shared control check above turns this bad boy into a tibble, needs to be a dataframe for the below function
vcv_cvr_rr<-make_VCV_matrix(data = re_ref, V ="vi_cvr", cluster = "ref_shared_ctrl", obs = "unit", rho=0.5)
vcv_mean_rr<-make_VCV_matrix(re_ref, V ="vi_mean", "ref_shared_ctrl", "unit", rho=0.5)
vcv_vr_rr<-make_VCV_matrix(re_ref, V ="vi_vr", "ref_shared_ctrl", "unit", rho=0.5)
Additionally, we test for any differences of both main effects and age effects for each broad taxon category (‘plants’, ‘invertebrates’, ‘vertebrates’, ‘soil microbes’, ‘amoeba’, and ‘fungi’). First we run meta-analytic models of LnCVR and LnRR for both restored/unrestored and restored/reference comparisons. In Table S4, we print the Qm statistic for these or the so-called “omnibus test” which to paraphrase Wolfgang Viechtbauer (see http://www.metafor-project.org/doku.php/tips:testing_factors_lincoms ) for extended discussion) is to test if at least part of the heterogeneity in the true effects is related to some of the variables in the model (in this case, taxon).
cvr_ur <- rma.mv(yi_cvr, vcv_cvr, mods=~taxon, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re) # can't remove intercept, or else we are testing whether the average true outcome is equal to 0 for all levels, not if there are between-group differences. grande differenza!!
mean_ur <- rma.mv(yi_mean, vcv_mean,mods=~taxon, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
cvr_rr <- rma.mv(yi_cvr, vcv_cvr_rr, mods=~taxon,random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
mean_rr <- rma.mv(yi_mean, vcv_mean_rr, mods=~taxon,random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
Table S15: QM statistics, degrees of freedom, and p-values for the test of moderators for each meta-analytic model.
options(scipen = 999)
x<-cbind(c("Log CV - restored/unrestored", "Log response ratio - restored/unrestored", "Log CV - restored/reference", "Log response ratio - restored/reference"), c(cvr_ur$QM, mean_ur$QM, cvr_rr$QM, mean_rr$QM),
c(cvr_ur$QMdf[1], mean_ur$QMdf[1], cvr_rr$QMdf[1], mean_rr$QMdf[1]),
c(cvr_ur$QMp, mean_ur$QMp, cvr_rr$QMp, mean_rr$QMp))
x<-`colnames<-`(x, c("Model", "QM", "QM df", "QM p value"))
x<-as.data.frame(x)
x<-x %>% mutate(QM = as.numeric(QM),
`QM df` = as.numeric(`QM df`),
`QM p value` = as.numeric(`QM p value`))
x %>% kable("html", digits = 3) %>%
kable_styling("striped", position = "left")
Model | QM | QM df | QM p value |
---|---|---|---|
Log CV - restored/unrestored | 9.798 | 5 | 0.081 |
Log response ratio - restored/unrestored | 5.972 | 5 | 0.309 |
Log CV - restored/reference | 1.184 | 4 | 0.881 |
Log response ratio - restored/reference | 5.242 | 4 | 0.263 |
We see no evidence for this in any of the models, therefore do not proceed to posthoc tests to adjust for the multiple comparisons and get pairwise differences between groups.
# this was to make plots, which are current not printing because unecessary
# cvrorgur<-orchard_plot(cvr_ur, mod="taxon", xlab = "log CV ratio - unrestored/restored", alpha = 0.1, k=T)+theme_classic()
# meanorgur<-orchard_plot(mean_ur, mod="taxon", xlab = "log response ratio - unrestored/restored", alpha = 0.1, k=T)+theme_classic()
# cvrorgrr<-orchard_plot(cvr_rr, mod="taxon", xlab = "log CV ratio - reference/restored", alpha = 0.1, k=T)+theme_classic()
# meanorgrr<-orchard_plot(mean_rr, mod="taxon", xlab = "log response ratio - reference/restored", alpha = 0.1, k=T)+theme_classic()
#
#
# (cvrorgur/meanorgur)+plot_annotation(tag_levels = "a", tag_suffix = ")")
# as above
# (cvrorgrr/meanorgrr)+plot_annotation(tag_levels = "a", tag_suffix = ")")
Next, we do the same thing to test if there is significant variation
in the interaction between taxon
and age
.
cvr_ur_age <- rma.mv(yi_cvr, vcv_cvr, mods = ~age.rest.:taxon, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
mean_ur_age <- rma.mv(yi_mean, vcv_mean, mods = ~age.rest.:taxon, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
cvr_rr_age <- rma.mv(yi_cvr, vcv_cvr_rr, mods = ~age.rest.:taxon, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
mean_rr_age <- rma.mv(yi_mean, vcv_mean_rr, mods = ~age.rest.:taxon, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = re_ref)
# cvrurage<-orchard_plot(cvr_ur_age, mod="taxon", xlab = "log(variability ratio) - unrestored/restored", alpha = 0.1, k=T)+theme_classic()
# meanurage<-orchard_plot(mean_ur_age, mod="taxon", xlab = "log(variability ratio) - unrestored/restored", alpha = 0.1, k=T)+theme_classic()
# cvrrrage<-orchard_plot(cvr_rr_age, mod="taxon", xlab = "log(variability ratio) - unrestored/restored", alpha = 0.1, k=T)+theme_classic()
# meanrrage<-orchard_plot(mean_rr_age, mod="taxon", xlab = "log(variability ratio) - unrestored/restored", alpha = 0.1, k=T)+theme_classic()
Table S16: QM statistics, degrees of freedom, and p-values for the test of moderators for each meta-analytic model.
x<-cbind(c("Log CV - restored/unrestored (age:taxon interaction)", "Log response ratio - restored/unrestored (age:taxon interaction)", "Log CV - restored/reference (age:taxon interaction)", "Log response ratio - restored/reference (age:taxon interaction)"), c(cvr_ur_age$QM, mean_ur_age$QM, cvr_rr_age$QM, mean_rr_age$QM),
c(cvr_ur_age$QMdf[1], mean_ur_age$QMdf[1], cvr_rr_age$QMdf[1], mean_rr_age$QMdf[1]),
c(cvr_ur_age$QMp, mean_ur_age$QMp, cvr_rr_age$QMp, mean_rr_age$QMp))
x<-`colnames<-`(x, c("Model", "QM", "QM df", "QM p value"))
x<-as.data.frame(x)
x<-x %>% mutate(QM = as.numeric(QM),
`QM df` = as.numeric(`QM df`),
`QM p value` = as.numeric(`QM p value`))
x %>% kable("html", digits = 3) %>%
kable_styling("striped", position = "left")
Model | QM | QM df | QM p value |
---|---|---|---|
Log CV - restored/unrestored (age:taxon interaction) | 5.465 | 6 | 0.486 |
Log response ratio - restored/unrestored (age:taxon interaction) | 19.643 | 6 | 0.003 |
Log CV - restored/reference (age:taxon interaction) | 7.722 | 5 | 0.172 |
Log response ratio - restored/reference (age:taxon interaction) | 2.359 | 5 | 0.798 |
Here, we can see that there is evidence that some of the heterogeneity in the “true effect” is due to the included moderators
Last, since we had a significant QM statistic in the LnRR model comparing restored/unrestored model, we conduct a posthoc test below to test for differences between each group (each group being the interaction between taxon and age of restored site). We have to run a new model without the intercept, because otherwise we are including that in the combinations of pairs (see discussion here: https://stats.stackexchange.com/questions/324885/easy-post-hoc-tests-when-meta-analyzing-with-the-metafor-package-in-r and Wolfgang Viechtbauer’s discussion of this here http://www.metafor-project.org/doku.php/tips:testing_factors_lincoms).
In the code, but not printed in the output, we run a second posthoc test adjusted for multiplicity just to be thorough, also finding no differences.
Table S17. Pairwise comparison between subgroups (taxon:age interaction) for log response ratio between restored and unrestored sites.
mean_ur_age <- rma.mv(yi_mean, vcv_mean, mods = ~age.rest.:taxon-1, random = list(~1 | id, ~1 | plot_id, ~1 | unit), method = "REML", data = un_re)
rrmean_age<-summary(glht(mean_ur_age, linfct=cbind(contrMat(rep(1,6), type="Tukey"))), test=adjusted("none"))
#rrmean_age<-summary(glht(mean_ur_age, linfct=cbind(contrMat(rep(1,6), type="Tukey"))), test=adjusted("Westfall")) # check using a correction for multiplicity, no different so leaving along to keep consistent with the above models
# plus, on reading Westfall/Shaffer, it seems that corrections reduces the Type I error rate, and then not correcting reduces the Type II error - which since thre is n.s. results either way this is not that important here?
rrmeanage<-as.data.frame(cbind(rrmean_age$test$coefficients, rrmean_age$test$sigma, rrmean_age$test$tstat, rrmean_age$test$pvalues)) %>%
rename(coefficient = V1,
sigma = V2,
tstat = V3,
p = V4)
a<-bind_cols(c(1:6), c("amoebae", "fungi", "invertebrates", "plants", "soil microbes", "vertebrates")) %>% rename(num = `...1`, tax = `...2`)
rmeanage<-as.data.frame(rownames(rrmeanage)) %>% rename(comp = `rownames(rrmeanage)`) %>% mutate(ref = as.numeric(word(comp, 2, sep = "-")), comparison = as.numeric(word(comp, 1, sep = "-"))) %>% left_join(., a, by = c("ref" = "num")) %>% rename(reference_taxa = tax) %>%
left_join(., a, by = c("comparison" = "num")) %>% rename(comparison_taxa = tax) %>% bind_cols(., rrmeanage)
rownames(rmeanage) <- NULL
rmeanage %>% dplyr::select(-c(1:3)) %>% kable(digits = 3) %>% kable_styling()%>%
scroll_box(width = "800px", height = "350px")
reference_taxa | comparison_taxa | coefficient | sigma | tstat | p |
---|---|---|---|---|---|
amoebae | fungi | 0.050 | 0.030 | 1.663 | 0.096 |
amoebae | invertebrates | 0.023 | 0.021 | 1.096 | 0.273 |
amoebae | plants | 0.028 | 0.021 | 1.315 | 0.189 |
amoebae | soil microbes | 0.018 | 0.022 | 0.789 | 0.430 |
amoebae | vertebrates | 0.032 | 0.022 | 1.440 | 0.150 |
fungi | invertebrates | -0.027 | 0.022 | -1.243 | 0.214 |
fungi | plants | -0.023 | 0.022 | -1.040 | 0.299 |
fungi | soil microbes | -0.033 | 0.023 | -1.413 | 0.158 |
fungi | vertebrates | -0.019 | 0.023 | -0.819 | 0.413 |
invertebrates | plants | 0.004 | 0.003 | 1.684 | 0.092 |
invertebrates | soil microbes | -0.005 | 0.008 | -0.685 | 0.493 |
invertebrates | vertebrates | 0.009 | 0.007 | 1.220 | 0.222 |
plants | soil microbes | -0.010 | 0.008 | -1.248 | 0.212 |
plants | vertebrates | 0.004 | 0.007 | 0.603 | 0.547 |
soil microbes | vertebrates | 0.014 | 0.010 | 1.372 | 0.170 |
library(pander)
sessionInfo() %>% pander()
R version 4.1.2 (2021-11-01)
Platform: x86_64-w64-mingw32/x64 (64-bit)
locale: LC_COLLATE=English_Australia.1252, LC_CTYPE=English_Australia.1252, LC_MONETARY=English_Australia.1252, LC_NUMERIC=C and LC_TIME=English_Australia.1252
attached base packages: stats, graphics, grDevices, utils, datasets, methods and base
other attached packages: pander(v.0.6.4), multcomp(v.1.4-18), TH.data(v.1.1-0), MASS(v.7.3-54), survival(v.3.2-13), mvtnorm(v.1.1-3), knitr(v.1.37), rworldmap(v.1.3-6), sp(v.1.4-6), ggtext(v.0.1.1), jtools(v.2.1.4), gridExtra(v.2.3), sjPlot(v.2.8.10), patchwork(v.1.1.1), orchaRd(v.0.0.0.9000), kableExtra(v.1.3.4), rmarkdown(v.2.12), forcats(v.0.5.1), stringr(v.1.4.0), dplyr(v.1.0.8), purrr(v.0.3.4), readr(v.2.1.2), tidyr(v.1.2.0), tibble(v.3.1.6), ggplot2(v.3.3.5), tidyverse(v.1.3.1), readxl(v.1.3.1), broom(v.0.7.12), metafor(v.3.0-2) and Matrix(v.1.3-4)
loaded via a namespace (and not attached): ggbeeswarm(v.0.6.0), minqa(v.1.2.4), colorspace(v.2.0-3), ellipsis(v.0.3.2), sjlabelled(v.1.1.8), estimability(v.1.3), markdown(v.1.1), parameters(v.0.16.0), fs(v.1.5.2), gridtext(v.0.1.4), rstudioapi(v.0.13), farver(v.2.1.0), bit64(v.4.0.5), fansi(v.1.0.2), lubridate(v.1.8.0), mathjaxr(v.1.6-0), xml2(v.1.3.3), codetools(v.0.2-18), splines(v.4.1.2), sjmisc(v.2.8.9), spam(v.2.8-0), jsonlite(v.1.8.0), nloptr(v.2.0.0), ggeffects(v.1.1.1), dbplyr(v.2.1.1), effectsize(v.0.6.0.1), compiler(v.4.1.2), httr(v.1.4.2), sjstats(v.0.18.1), emmeans(v.1.7.2), backports(v.1.4.1), assertthat(v.0.2.1), fastmap(v.1.1.0), cli(v.3.2.0), htmltools(v.0.5.2), tools(v.4.1.2), dotCall64(v.1.0-1), gtable(v.0.3.0), glue(v.1.6.2), maps(v.3.4.0), Rcpp(v.1.0.8), cellranger(v.1.1.0), jquerylib(v.0.1.4), vctrs(v.0.3.8), svglite(v.2.1.0), nlme(v.3.1-153), insight(v.0.16.0), xfun(v.0.29), lme4(v.1.1-28), rvest(v.1.0.2), lifecycle(v.1.0.1), zoo(v.1.8-9), scales(v.1.1.1), vroom(v.1.5.7), hms(v.1.1.1), parallel(v.4.1.2), sandwich(v.3.0-1), fields(v.13.3), yaml(v.2.3.5), sass(v.0.4.0), stringi(v.1.7.6), highr(v.0.9), bayestestR(v.0.11.5), maptools(v.1.1-2), boot(v.1.3-28), rlang(v.1.0.1), pkgconfig(v.2.0.3), systemfonts(v.1.0.4), evaluate(v.0.15), lattice(v.0.20-45), labeling(v.0.4.2), bit(v.4.0.4), tidyselect(v.1.1.2), magrittr(v.2.0.2), R6(v.2.5.1), generics(v.0.1.2), DBI(v.1.1.2), foreign(v.0.8-81), pillar(v.1.7.0), haven(v.2.4.3), withr(v.2.5.0), mgcv(v.1.8-38), datawizard(v.0.2.3), performance(v.0.8.0), modelr(v.0.1.8), crayon(v.1.5.0), utf8(v.1.2.2), tzdb(v.0.2.0), viridis(v.0.6.2), grid(v.4.1.2), reprex(v.2.0.1), digest(v.0.6.29), webshot(v.0.5.2), xtable(v.1.8-4), munsell(v.0.5.0), beeswarm(v.0.4.0), viridisLite(v.0.4.0), vipor(v.0.4.5) and bslib(v.0.3.1)