Here we reviewed meta-analysis that reported the number of sites and duration of years associated with each study. The goal is to get a coarse overview of temporal and spatial replication in ecology research.
## Libraries
library(tidyverse)
## Extra code and functions
source("functions.r")
## how many studies based on each duration
getYears <- function(x, dataset){
nfilt <- dataset %>% filter(Nyears > x) %>% nrow()
return(as.vector(nfilt))
}
## how many studies based on each duration
getYear <- function(x, dataset){
nfilt <- dataset %>% filter(Nyear > x) %>% nrow()
return(as.vector(nfilt))
}
## how many studies based on each site
getSites <- function(x, dataset){
nfilt <- dataset %>% filter(Nsite > x) %>% nrow()
return(as.vector(nfilt))
}
## Load Filazzola et al. studies
## GI meta-analysis
GIraw <- read.csv("data//raw//Filazzola et al. GI.csv", stringsAsFactors = F) ## GI meta-analysis
studiesYears <- unlist(sapply(1:30, FUN= getYear, dataset=GIraw))
studiesSites <- unlist(sapply(1:30, FUN= getSites, dataset=GIraw))
GIDF <- data.frame(study = "GI",rep = 1:30, type = rep(c("years","sites"),each=30), nstudies=c(studiesYears,studiesSites))
## Water-quality meta-analysis
waterQraw <- read.csv("data//raw//Filazzola et al. Chla.csv", stringsAsFactors = F) ## Water quality synthesis
studiesYears <- unlist(sapply(1:30, FUN= getYear, dataset=waterQraw))
studiesSites <- unlist(sapply(1:30, FUN= getSites, dataset=waterQraw))
chlaDF <- data.frame(study = "WaterQ",rep = 1:30, type = rep(c("years","sites"),each=30), nstudies=c(studiesYears,studiesSites))
## Grazing meta-analysis
grazingraw <- read.csv("data//raw//Filazzola et al. 2020 Grazing.csv", stringsAsFactors = F) ## Grazing meta-analysis
studiesYears <- unlist(sapply(1:30, FUN= getYear, dataset=grazingraw))
studiesSites <- unlist(sapply(1:30, FUN= getSites, dataset=grazingraw))
grazeDF <- data.frame(study = "Grazing",rep = 1:30, type = rep(c("years","sites"),each=30), nstudies=c(studiesYears,studiesSites))
filacompare <- rbind(GIDF, chlaDF,grazeDF)
#### Load other ecology studies
## Li, W., Jin, C., Guan, D., Wang, Q., Wang, A., Yuan, F., & Wu, J. (2015). The effects of simulated nitrogen deposition on plant root traits: a meta-analysis. Soil Biology and Biochemistry, 82, 112-118.
# https://www.sciencedirect.com/science/article/pii/S0038071715000115?casa_token=ailE-bZ_3LEAAAAA:3BnJdVitzKbrhLBiCNnriP41sY3-fgTrnxQgkITynyxkf8ogDZIExWHAAD9VCxXzH7TFVs-SUhOo
lisoil <- read.csv("data//LiSoilduration.csv")
studiesYears <- unlist(sapply(1:30, FUN= getYears, dataset=lisoil))
studiesSites <- unlist(sapply(1:30, FUN= getSites, dataset=lisoil))
liDF <- data.frame(study = "LiSoil",rep = 1:30, type = rep(c("years","sites"),each=30), nstudies=c(studiesYears,studiesSites))
## Bowles, T. M., Jackson, L. E., Loeher, M., & Cavagnaro, T. R. (2017). Ecological intensification and arbuscular mycorrhizas: a meta‐analysis of tillage and cover crop effects. Journal of Applied Ecology, 54(6), 1785-1793.
# https://besjournals.onlinelibrary.wiley.com/doi/abs/10.1111/1365-2664.12815
bowles <- read.csv("data//raw//Bowles2017.csv")
studiesYears <- unlist(sapply(1:30, FUN= getYears, dataset=bowles))
studiesSites <- unlist(sapply(1:30, FUN= getSites, dataset=bowles))
bowlesDF <- data.frame(study = "bowles",rep = 1:30, type = rep(c("years","sites"),each=30), nstudies=c(studiesYears,studiesSites))
## Jia, S., Wang, X., Yuan, Z., Lin, F., Ye, J., Hao, Z., & Luskin, M. S. (2018). Global signal of top-down control of terrestrial plant communities by herbivores. Proceedings of the National Academy of Sciences, 115(24), 6237-6242.
# https://www.pnas.org/content/115/24/6237.short
jia <- read.csv("data//raw//Jia2018.csv")
studiesYears <- unlist(sapply(1:30, FUN= getYears, dataset=jia))
studiesSites <- unlist(sapply(1:30, FUN= getSites, dataset=jia))
jiaDF <- data.frame(study = "Jia",rep = 1:30, type = rep(c("years","sites"),each=30), nstudies=c(studiesYears,studiesSites))
othercompare <- rbind(liDF, bowlesDF,jiaDF)
## Create function that counts the number of studies with multiple replicates
countReps <- function(df){
nsite <- nrow(df[df$Nsite>1,])
nyear <- nrow(df[df$Nyear>1,])
nboth <- nrow(df[df$Nyear>1 & df$Nsite>1,])
noRep <- nrow(df[df$Nyear==1 & df$Nsite==1,])
totalStudies <- nrow(df)
return(data.frame(nsite, nyear, nboth,noRep, totalStudies))
}
## Count replication in time and space
allDf <- list(lisoil, bowles, jia,GIraw,waterQraw,grazingraw)
allOut <- sapply(allDf, countReps)
allOut
## [,1] [,2] [,3] [,4] [,5] [,6]
## nsite 13 41 89 35 240 188
## nyear 34 25 80 9 180 172
## nboth 10 23 63 6 158 125
## noRep 17 1 7 47 22 15
## totalStudies 54 44 113 85 271 245
## Log-transform and drop -inf
filacompare[,"logstudies"] <- log(filacompare$nstudies)
filacompare[is.infinite(filacompare$logstudies),"logstudies"] <-0
othercompare[,"logstudies"] <- log(othercompare$nstudies)
othercompare[is.infinite(othercompare$logstudies),"logstudies"] <-0
### Plot of Filazzola et al. studies
plot1 <- ggplot(filacompare, aes(x=rep, y=logstudies, color=type)) +facet_grid(study~., scales = "free") + geom_point(size=2) + theme_Publication() + ylab("Number of Studies") + xlab("Replication") + scale_color_manual(values=c("orange","blue"))
plot1
### Plot of Other studies
plot2 <- ggplot(othercompare, aes(x=rep, y=logstudies, color=type)) +facet_grid(study~., scales = "free") + geom_point(size=2) + theme_Publication() + ylab("Number of Studies") + xlab("Replication") + scale_color_manual(values=c("orange","blue"))
plot2
gridExtra::grid.arrange(plot1, plot2, ncol=2)
### Total studies per meta
totalN1 <- filacompare %>% group_by(study) %>% summarize(totalStudies = max(nstudies))
## `summarise()` ungrouping output (override with `.groups` argument)
totalN1
## Warning: `...` is not empty.
##
## We detected these problematic arguments:
## * `needs_dots`
##
## These dots only exist to allow future extensions and should be empty.
## Did you misspecify an argument?
## # A tibble: 3 x 2
## study totalStudies
## <chr> <int>
## 1 GI 35
## 2 Grazing 178
## 3 WaterQ 218
totalN2 <- othercompare %>% group_by(study) %>% summarize(totalStudies = max(nstudies))
## `summarise()` ungrouping output (override with `.groups` argument)
totalN2
## Warning: `...` is not empty.
##
## We detected these problematic arguments:
## * `needs_dots`
##
## These dots only exist to allow future extensions and should be empty.
## Did you misspecify an argument?
## # A tibble: 3 x 2
## study totalStudies
## <chr> <int>
## 1 bowles 41
## 2 Jia 89
## 3 LiSoil 34
sum(totalN2$totalStudies, totalN1$totalStudies) ## total studies examined
## [1] 595
## Load votecount data
voteCount <- read.csv("data//voteCountMetas.csv")
sum(voteCount$Nsites=="yes", na.rm=T) # n meta with sites
## [1] 6
sum(voteCount$NyearsSingle=="yes", na.rm=T) # n meta with years
## [1] 6
library(metafor)
## Loading required package: Matrix
##
## Attaching package: 'Matrix'
## The following objects are masked from 'package:tidyr':
##
## expand, pack, unpack
## Loading 'metafor' package (version 2.4-0). For an overview
## and introduction to the package please type: help(metafor).
## Calculate effect sizes for studies with just estimates
effectSizes <- read.csv("data//raw//EffectSizes.csv")
meta.ready <- escalc(n1i = treatmentN, n2i = controlN, m1i = treatment, m2i = control, sd1i = treatmentSD, sd2i = controlSD, data = effectSizes, measure = "ROM", append = TRUE)
## Warning in log(m1i/m2i): NaNs produced
## Warning in escalc(n1i = treatmentN, n2i = controlN, m1i = treatment, m2i =
## control, : Some 'yi' and/or 'vi' values equal to +-Inf. Recoded to NAs.
meta.ready <- meta.ready[!is.na(meta.ready$yi),]
meta.ready[,"n"] <- (meta.ready$treatmentN+meta.ready$controlN)/2
effectRep <- meta.ready %>% select(Meta, n, yi, vi) %>% data.frame()
## Join with studies that already have effect sizes
effectOthers <- read.csv("data//effectSizeReplication.csv")
effectNAll <- rbind(effectRep, effectOthers)
### Effect estimate
plot1 <- ggplot(effectNAll, aes(x=n, y=abs(yi), color=Meta)) + geom_point() + ylab("Effect size (LRR)") + xlab("Replication") + theme_Publication()
## Warning: `legend.margin` must be specified using `margin()`. For the old
## behavior use legend.spacing
plot2 <- ggplot(effectNAll %>% filter(vi <6), aes(x=n, y=vi, color=Meta)) + geom_point() + ylab("Error estimate") + xlab("Replication") + theme_Publication()
## Warning: `legend.margin` must be specified using `margin()`. For the old
## behavior use legend.spacing
gridExtra::grid.arrange(plot1, plot2, ncol=2)
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Plot just grazing and green infrastructurre data
FilaOnly <- effectNAll %>% filter(Meta %in% c("grazing","greenInfrastructure"))
plot1 <- ggplot(FilaOnly, aes(x=n, y=abs(yi), color=Meta)) + geom_point() + ylab("Effect size (LRR)") + xlab("Replication") + theme_Publication() + scale_colour_manual(values=c("#00BFFF", "#F5A500"))
## Warning: `legend.margin` must be specified using `margin()`. For the old
## behavior use legend.spacing
plot2 <- ggplot(FilaOnly %>% filter(vi <6), aes(x=n, y=vi, color=Meta)) + geom_point() + ylab("Error estimate") + xlab("Replication") + theme_Publication() + scale_colour_manual(values=c("#00BFFF", "#F5A500"))
## Warning: `legend.margin` must be specified using `margin()`. For the old
## behavior use legend.spacing
gridExtra::grid.arrange(plot1, plot2, ncol=2)
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, :
## font family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database
## Warning in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, : font
## family not found in Windows font database