# Start with clear working space
rm(list=ls())

# import libraries 
# for meta, graphs, data manipulation
library(ggplot2)
library(dplyr)
library(metafor)


# for publication bias
library(MCMCglmm)
library(Matrix)
library(matrixcalc)

# To extract data from figures
library(metaDigitise)
library(compute.es)


# To make orchard figures
library(devtools)
library(tidyverse)
library(patchwork)
library(R.rsp)
library(orchaRd)

# To make pretty tables
library(kableExtra)

# To arrange multiple plots in a figure
library(cowplot)

# Function for creating covariance matrix for MCMCglmm
# data = dataframe
# cluster = column with unique ID joining ES that are not independent within each study (blocks of correlated ES)
# V = variance of effect sizes
# obs = column with unique ID for each data row (effect size)

make_VCV_matrix <- function(data, V, cluster, obs, type=c("vcv", "cor"), rho=0.5){
  
  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" 
  
  ## V = variance, cluster = paper iD, ob = effect size id, type = default VCV settings
  
  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(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)
}


# Set working directory
setwd([blinded])

1 Literature search & PRISMA diagram


Literature search

We used the Preferred Reporting Items for Systematic Reviews and Meta-Analyses (PRISMA, Moher et.al., 2009) guidelines to perform a systematic literature search. We compiled a database derived from peer-reviewed, English language studies that examined how testes size and sperm morphology (sperm head, midpiece, flagellum, and total length) are influenced by variation in the strength of sperm competition using Scopus and Web of Science online databases on January 6, 2020. We performed two initial searches to capture relevant studies for all subsequent analyses using broad search strings.

For the testes meta-analysis, we used the following search strings:

In Scopus:

TITLE-ABS-KEY ( ( "sperm competition"  OR  "mating strateg*"  OR "mating syste*"  OR  "mating tacti*"  OR "breeding strateg*" OR  "breeding tacti*"  OR  "breeding syste*"  OR "extra-pair paternity" OR  "extra pair paternity"  OR  "multiple paternity" )  AND  ( size  OR mass  OR  volume OR  length  OR weight )  AND  ( test?s OR  testicular  OR ejaculat*  OR  "reproductive anatomy" )  AND (species OR taxa OR phylogen* OR bird* OR rodent* OR fish* OR primate* OR mammal* OR insect* OR comparative ) )

In Web of Science:

TS = ( ( "sperm competition" OR "mating strateg*" OR "mating syste*" OR "mating tacti*" OR "breeding strateg*" OR "breeding tacti*" OR "breeding syste*" OR "extra-pair paternity" OR "extra pair paternity" OR "multiple paternity" ) AND ( size OR mass OR volume OR length OR weight ) AND ( test?s OR testicular OR ejaculat* OR "reproductive anatomy" ) AND (species OR taxa OR phylogen* OR bird* OR rodent* OR fish* OR primate* OR mammal* OR insect* OR comparative ) )

For the sperm meta-analysis, we used the following search strings:

In Scopus:

TITLE-ABS-KEY ( ( sperm  W/6  size OR  length  OR long*  OR  form OR  morpholog*  OR volume  OR  small* ) AND  ( species  OR taxa  OR  phylogen* OR  bird*  OR rodent*  OR  fish* OR  primate*  OR mammal*  OR  insect* OR  comparative )  AND  ( "sperm competition"  OR  test?s ) ) AND NOT  TITLE-ABS-KEY ( patient  OR  treatment OR  dose  OR protein  OR  exposure )

In Web of Science:

TS = ( ( sperm near/6 (size OR length OR long* OR form OR morpholog* OR volume OR small* )) AND ( species OR taxa OR phylogen* OR bird* OR rodent* OR fish* OR primate* OR mammal* OR insect* OR comparative ) AND ( "sperm competition" OR test?s ) ) NOT TS = ( patient OR treatment OR dose OR protein OR exposure )

Our search criteria identified 1243 unique papers for screening for the testes meta-analysis and 1404 unique papers for the sperm meta-analysis. Together they resulted in 2211 unique papers. We used Rayyan software (Ouzzani et al., 2016) to initially screen these papers by reading and assessing their titles and abstracts. Using a Decision tree, three researchers (RdB, JLF, SL) screened the paper titles and abstracts, and removed papers that did not fit our inclusion criteria. We randomly screened the abstracts with regard to year to avoid any bias regarding the order, in which the abstracts were presented to the screener. To ensure consistency in screening procedures among researchers, we assessed repeatability in scoring decisions by comparing the decisions of the three researchers for 100 abstracts. There was broad overlap in scoring decisions (for N=65 papers all three scorers derived the same decision). The remaining papers (N=35) where two of the three scorers disagreed were discussed and resolved by further clarifying the inclusion and exclusion criteria. In addition, we utilized the option to score a paper as ?Maybe? in Rayyan as a way to ask for a second opinion by another scorer if there was doubt about whether the full-text should be screened.

After reviewing titles and abstracts, we removed N=1875 papers from further consideration. We read the full-text of the remaining N=336 papers and screened them based on the inclusion criteria. Studies were included for data extraction at the full-text screening phase if they fit our inclusion criteria (see Decision tree). In short, we only included papers written in English, that contained statistics or data of the size of testes in relation to a behavioural or genetic estimate of sperm competition (testes meta-analysis) or of the length of sperm in relation to testes size (controlling for body size), or to behavioural or genetic estimates of sperm competition (sperm meta-analysis). A summary of the results of the systematic review of the literature is provided in the Prisma diagram. A bibliography of all papers screened with the inclusion decision on the title/abstract and full-text screening stage (including the reason for their exclusion) is provided in the supplemental data files.

Updated Search

We updated the literature survey on June 15th by running the same search strings as described above in both Scopus and Web of Science while filtering for publication year = 2020. The testes search resulted in N=10 new papers in Scopus and N=13 in Web of Science, of which N=15 were unique. The sperm search resulted in N=15 papers in Scopus and N=10 papers in Web of Science, of which N=16 were unique. Between the testes and sperm searches, N=26 papers were unique and screened based on title/abstract. Of these, we included N=5 for full-text screening. Based on full-text screening, we excluded N=1 because it was already in our previous search and N=3 because the study design was ineligible, and we included N=1 for data extraction.



1.1 Decision tree

knitr::include_graphics(rep("IMAGES/decision-tree.png"))
Decision tree showing how it was decided whether to include or exclude a paper at the title/abstract screening phase and the full-text screening phase

Figure 1.1: Decision tree showing how it was decided whether to include or exclude a paper at the title/abstract screening phase and the full-text screening phase

1.2 Prisma diagram

knitr::include_graphics(rep("IMAGES/prisma.png"))
Prisma diagram showing the results of the systematic literature review for the sperm and testes meta-analyses

Figure 1.2: Prisma diagram showing the results of the systematic literature review for the sperm and testes meta-analyses


2 Data extraction & effect size calculation


For each paper, we extracted correlation coefficient r values whenever possible. When other test values were provided we transformed these (F, ?2, t, Z-scores, Spearman?s r, Mann-Whitney U, or R2) into Pearson?s correlation coefficient r using the formulas in Box 13.3 of Lajeunesse (2013). Where no statistics were available, we calculated r from raw data whenever this was possible. We did this in the simplest way possible (i.e.?not accounting for phylogenetic dependence). We accounted for body mass by taking the relative testes mass, or when possible running a linear model with body mass as a covariate. When data were presented in graphs, we extracted them using metaDigitise (Pick et al., 2018). In this case or when only raw data were available in the form of means, we used the function mes in the package compute.es (Re, 2013) to transform mean values into a correlation coefficient r. Given that r becomes skewed as it approaches 1, we used Fisher?s Z-transformation in the meta-analyses and meta-regressions. Fishers Z-transformed r is calculated as follows (Rosenberg et al., 2013):

\[ Z_r=0.5ln(\frac{1+r} {1-r})\] with variance:

\[V_z=\frac{1}{n-3}\] Because the correlation coefficient r is more intuitive to understand, we back-transformed meta-analytic estimates and presented those in graphs. The back-transformation from Zr to r was done as follows:

\[r=\frac{e^{2Z_r}-1}{e^{2Z_r}+1}\]

Data visualization

The data was visualized using orchard plots (Nakagawa et al., 2020).



# formulas for effect size calculation

# Pearson r to Z
r_to_z <- function(r) {
  z = 0.5 * log((1+r)/ (1-r))
  return(z)
}

# variance of Z
var_z <- function(n) {
  var_z = 1 / (n-3)
  return(var_z)
}

# reverse of z
z_to_r <- function(z) {
  r = (exp(2*z)-1) / (exp(2*z)+1)
  return(r)
}

# standard error
se_z <- function(var_z) {
  se_z = sqrt(var_z)
  return(se_z)
}

# for multiple regression models t and for independent t-test t
# where df = n1 + n2 - 2
t_to_z <- function(t, df) {
  r = t / sqrt(t^2 + df)
  z = r_to_z(r)
  return(z)
}

# mann-whitney U
# we need the absolute value - very important or we will get the wrong sign
mannwhitu_to_z <- function(U, n1, n2) {
  r = (1-(2*U)) / (n1*n2)
  z = r_to_z(abs(r))
  return(z)
}

# Z score to z
# where N = n1 + n2
Z_to_z <- function(Z, n) {
  r = Z / sqrt(n)
  z = r_to_z(r)
  return(z)
}

# chisquare value to z
# where n = n1 + n2
# and df needs to be 1
# this can produce r's out of reach for z (i.e. >1)
# needs to be multiplied by effect size direction
chisq_to_z <- function(chi, n) {
  r = sqrt(chi / n)
  z = r_to_z(r)
  return(z)
}

# spearman
spearman_to_z <- function(rho) {
  r = 2 * sin((pi * rho) / 6)
  z = r_to_z(r)
  return(z)
}

# F-ratio of one way ANOVA !!THIS ONLY MAKES SENSE IF THERE IS 1 DEGREE OF FREEDOM!!
# where df = n1 + n2 - 2
# needs to be multiplied by effect size direction
F_to_z <- function(Fvalue, df) {
  r = sqrt(Fvalue / (Fvalue + df))
  z = r_to_z(r)
  return(z)
}


# R2 to Z
# Don't know if this is a great one, other values should be used if at all possible
r2_to_z <- function(r2) {
  r = sqrt(r2)
  z = r_to_z(r)
  return(z)
}

3 Testes meta-analysis


Testes size was primarily quantified using testes mass (N=93 effect sizes from 54 studies), with testes length (N=3 effect sizes from 2 studies) and testes volume (N=3 effect sizes from 2 studies) used less frequently. We combined these into a single testes size metric for all subsequent analyses as effect size estimates did not differ among the testes size measures (Proxies for testes size: Testes, Summary of moderators: Testes).

tes <- read.csv("Testes-metaV2.csv")
tes$UniqueBehav <- as.factor(tes$UniqueBehav)
tes$UniqueByTaxonBehav <- as.factor(tes$UniqueByTaxonBehav)
tes$UniqueByTaxonGenetic <- as.factor(tes$UniqueByTaxonGenetic)
tes$UniqueGenetic <- as.factor(tes$UniqueGenetic)

3.1 Testes size in relation to sperm competition (overall effect)

# Sample size
samplesize.mod.tm.overall <- tes %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")"))
samplesize.mod.tm.overall %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Overall number of effect sizes, studies and mean (range) sample size of species in the testes meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F)
Table 3.1: Overall number of effect sizes, studies and mean (range) sample size of species in the testes meta-analysis
EffectSizes Studies Sample Size
99 58 35.3 ( 2 - 776 )
# Model
mod.tm.overall <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.overall, digits=3)
  
# Model Results (includes a prediction interval)
orchard.tm.overall <- orchaRd::mod_results(mod.tm.overall, mod="Int")
pred <- orchard.tm.overall$mod_table # Makes it easier to repeat same plot

# I2
I2.tm.overall <- i2_ml(mod.tm.overall)

# R2
R2.tm.overall <- r2_ml(mod.tm.overall)
# Forest Plot
mod <- mod.tm.overall # Which model?
x_loc = -2 # Where does the summary statistic need to go?
col = '#f64949' # What color does the summary statistic need to be?
data = tes %>% 
  arrange(Z) %>% 
  mutate(EffectSizeKey = factor(EffectSizeKey, levels= EffectSizeKey)) # Which data and organise by Z

ggplot() +
  geom_hline(yintercept = 0, lty = 1, lwd = 1, colour = "black", alpha = 0.8) +
  geom_pointrange(data = data,aes(x = EffectSizeKey, y = Z, ymin = ci.lb, ymax = ci.ub), size=0.2) +
  geom_errorbar(aes(x=x_loc, ymin=pred$lowerPR, ymax = pred$upperPR), color='#ffcc00', width=1)+
  geom_point(aes(x=x_loc, y=mod$b),size=4, color=col, pch=18)+
  geom_errorbar(aes(x=x_loc, ymin=mod$ci.lb, ymax = mod$ci.ub), color=col, width=3)+
  coord_flip()+ 
  theme_classic() + 
  labs(x="Study", 
       y="Fisher's Z") +
  expand_limits(x=-5)+
  annotate(geom="text",x=10, y=2,label="k=99")
Forest plot of all estimates (Fisher's <i>Z</i>) of testes size in relation to sperm competition (meta-analytic mean and 95% confidence interval in red, 95% prediction interval in yellow).

Figure 3.1: Forest plot of all estimates (Fisher?s Z) of testes size in relation to sperm competition (meta-analytic mean and 95% confidence interval in red, 95% prediction interval in yellow).

# Orchard Plot
orchard_plot(orchard.tm.overall, 
             mod="Int", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values="#007aa3") +
  scale_colour_manual(values="#007aa3")
Orchard plot showing the correlation (correlation coefficient <i>r</i>) between testes size and sperm competition (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey)

Figure 3.2: Orchard plot showing the correlation (correlation coefficient r) between testes size and sperm competition (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey)

Taking all data together, there is an overall positive correlation between measures of testes size and sperm competition. The meta-analytic mean (Fisher?s Z) is 0.7 with confidence interval [0.58; 0.82] (Figure 3.1). The estimate is different from zero (P<0.0001) and translates into a correlation coefficient r of 0.6 (Figure 3.2).

3.2 Assessing moderators

3.2.1 Effect of sperm competition type: Testes

tes <- tes %>%
  mutate(SpermComp =case_when(
    SpermCompetition == 'Genetic estimate' ~ 'Genetic estimate',
    SpermCompetition == 'Behavioral estimate' ~ 'Behavioural estimate'
  ))

# sample size
samplesize.mod.tm.sc <- tes %>% group_by(SpermComp) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) 
samplesize.mod.tm.sc %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species in the testes meta-analysis grouped by sperm competition proxy") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 3.2: Number of effect sizes, studies and mean (range) sample size of species in the testes meta-analysis grouped by sperm competition proxy
SpermComp EffectSizes Studies Sample Size
Behavioural estimate 66 44 40 ( 2 - 776 )
Genetic estimate 33 14 25.7 ( 4 - 56 )
# model with intercept
mod.tm.sc0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(SpermComp), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.sc0, digits=3)

# model without intercept
mod.tm.sc <- rma.mv(yi=Z, V=Var_Z,  mods = ~ SpermComp -1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.sc, digits=3)

# Model Results (includes a prediction interval)
orchard.tm.sc <- orchaRd::mod_results(mod.tm.sc, mod="SpermComp")
pred <- orchard.tm.sc$mod_table # Makes it easier to repeat same plot


# I2
I2.tm.sc <- i2_ml(mod.tm.sc)

# R2
R2.tm.sc <- r2_ml(mod.tm.sc)
# Forest Plot
mod <- mod.tm.sc # Which model?
x_loc = -2 # Where does the summary statistic need to go?
x_loc2 = 68 # Where does the second summary statistic need to go?
col = '#b90702' # What color does the summary statistic need to be?

data = tes %>% 
  arrange(SpermCompetition, Z) %>% 
  add_row(EffectSizeKey="", Z=0, ci.lb=0, ci.ub=0, .before=67) %>%
  add_row(EffectSizeKey=" ", Z=0, ci.lb=0, ci.ub=0, .before=67) %>%
  add_row(EffectSizeKey="  ", Z=0, ci.lb=0, ci.ub=0, .before=67) %>%
  mutate(EffectSizeKey = factor(EffectSizeKey, levels= EffectSizeKey)) # Which data and organise by Z. Adding empty rows to add the second summary stat.

#label = levels(pred$name)
label = c("Behavioural estimates k=66", "Genetic estimates k=33")
x1 = (length(data[data$SpermCompetition == "Behavioral estimate",]$Z) / 2) -2
x2 = x1 + (length(data[data$SpermCompetition == "Genetic estimate",]$Z)) + 6

y = max(data$ci.ub) - 1

ggplot() +
  geom_hline(yintercept = 0, lty = 1, lwd = 2, colour = "black") +
  geom_pointrange(data = data,aes(x = EffectSizeKey, y = Z, ymin = ci.lb, ymax = ci.ub), size=0.1) +
  geom_errorbar(aes(x=x_loc, ymin=pred$lowerPR[1], ymax = pred$upperPR[1]), color='#ffcc00', width=1)+
  geom_point(aes(x=x_loc, y=mod$b[1]),size=4, color=col, pch=18)+
  geom_errorbar(aes(x=x_loc, ymin=mod$ci.lb[1], ymax = mod$ci.ub[1]), color=col, width=3)+
  geom_errorbar(aes(x=x_loc2, ymin=pred$lowerPR[2], ymax = pred$upperPR[2]), color='#ffcc00', width=1)+
  geom_point(aes(x=x_loc2, y=mod$b[2]),size=4, color=col, pch=18)+
  geom_errorbar(aes(x=x_loc2, ymin=mod$ci.lb[2], ymax = mod$ci.ub[2]), color=col, width=3)+
  coord_flip()+ 
  theme_classic() + 
  labs(x="Study", 
       y="Fisher's Z") +
  expand_limits(x= -5) +
  scale_x_discrete(drop=FALSE) +
  annotate("text", x = c(x1,x2), y = c(y,y), label = label, size=4)
Forest plot of the estimates (Fisher's <i>Z</i>) of testes size in relation to sperm competition separated by behavioural and genetic estimates of sperm competition (red=estimate with 95% CI, yellow=prediction interval).

Figure 3.3: Forest plot of the estimates (Fisher?s Z) of testes size in relation to sperm competition separated by behavioural and genetic estimates of sperm competition (red=estimate with 95% CI, yellow=prediction interval).

# Orchard Plot with precision
orchard_plot(orchard.tm.sc, 
             mod="SpermComp", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3","#ffcc00", "#00ff73")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73"))
Orchard plot showing the correlation (correlation coefficient <i>r</i>) between testes size and sperm competition separated by behavioural and genetic estimates of sperm competition (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

Figure 3.4: Orchard plot showing the correlation (correlation coefficient r) between testes size and sperm competition separated by behavioural and genetic estimates of sperm competition (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

ggsave("Figure1-testes-precision.pdf")

There is no difference in the estimates of the different sperm competition proxies (Qm=0.29, P=0.592). The meta-analytic mean (Fisher?s Z) for Behavioural estimate is 0.716 with confidence interval [0.58; 0.85], and for Genetic estimate is 0.64 with confidence interval [0.39; 0.89] (Figure 3.3). The estimates of the different levels of sperm competition are all different from zero, and translate into correlation coefficients r of 0.61 and 0.56 respectively (Figure 3.4).

Given that there are no differences between which type of sperm competition proxy we use, in theory we can pool all our data, as is done in Testes size in relation to sperm competition (overall effect).



3.2.2 Fertilization mode: Testes

NOTE: Excluding studies with both internal and external fertilizers.

# Sample size
ss.fert <- tes %>% filter(Fertilization != "Both") %>% group_by(Fertilization) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")"))
ss.fert %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species of internal and external fertilizing animals in the testes meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 3.3: Number of effect sizes, studies and mean (range) sample size of species of internal and external fertilizing animals in the testes meta-analysis
Fertilization EffectSizes Studies Sample Size
External 12 10 36.2 ( 2 - 111 )
Internal 78 47 36.3 ( 2 - 776 )
# model with intercept
mod.tes.fert0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Fertilization), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes %>% filter(Fertilization != "Both"))
summary(mod.tes.fert0, digits=3)

# model with intercept
mod.tes.fert <- rma.mv(yi=Z, V=Var_Z,  mods = ~ Fertilization-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes %>% filter(Fertilization != "Both"))
summary(mod.tes.fert, digits=3)

# I2
I2.tes.fert<- i2_ml(mod.tes.fert)

# R2
R2.tes.fert <- r2_ml(mod.tes.fert)
# Model Results (includes a prediction interval)
orchard.tes.fert <- orchaRd::mod_results(mod.tes.fert, mod="Fertilization")
pred <- orchard.tes.fert$mod_table # Makes it easier to repeat same plot

# Orchard Plot
orchard_plot(orchard.tes.fert, 
             mod="Fertilization", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00"))
Orchard plot showing the relationship between testes size and sperm competition (correlation coefficient <i>r</i>), separated for internally and externally fertilizing animals (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

Figure 3.5: Orchard plot showing the relationship between testes size and sperm competition (correlation coefficient r), separated for internally and externally fertilizing animals (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

There is a difference between estimates from internally and externally fertilizing species (Qm=4.091, P=0.043). The estimates are all different from zero. See Summary of moderators: Testes.



3.2.3 Phylogenetic control: Testes

# sample size
tes <- tes %>% mutate(PC = case_when(PhylogeneticControl == 0 ~ "No",
                                     PhylogeneticControl == 1 ~ "Yes"))

ss.pc <- tes %>% group_by(PhylogeneticControl) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) 
ss.pc %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species with (=1) and without (=0) phylogenetic control in the testes meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 3.4: Number of effect sizes, studies and mean (range) sample size of species with (=1) and without (=0) phylogenetic control in the testes meta-analysis
PhylogeneticControl EffectSizes Studies Sample Size
0 46 32 37.6 ( 2 - 776 )
1 53 29 33.2 ( 5 - 141 )
# model with intercept
mod.tm.pc0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(PhylogeneticControl), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.pc0, digits=3)

# model without intercept
mod.tm.pc <- rma.mv(yi=Z, V=Var_Z,  mods = ~ PC-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.pc, digits=3)

# I2
I2.tm.pc <- i2_ml(mod.tm.pc)

# R2
R2.tm.pc <- r2_ml(mod.tm.pc)
# Model Results (includes a prediction interval)
orchard.tm.pc <- orchaRd::mod_results(mod.tm.pc, mod="PC")
pred <- orchard.tm.pc$mod_table # Makes it easier to repeat same plot

# Orchard Plot
orchard_plot(orchard.tm.pc, 
             mod="PC", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3","#ffcc00")) +
  scale_colour_manual(values=c("#007aa3","#ffcc00"))
Orchard plot showing the relationship between testes size and sperm competition (correlation coefficient r) separate for estimates that were phylogenetically corrected or not (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

Figure 3.6: Orchard plot showing the relationship between testes size and sperm competition (correlation coefficient r) separate for estimates that were phylogenetically corrected or not (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

There is a difference between estimates where phylogenetic dependency was accounted for and those where it was not (Qm=5.8, P=0.016). The estimates were all different from zero. See Summary of moderators: Testes.

3.2.4 Animal phylum: Testes

samplesize.tes.animals <- tes %>% group_by(Phylum, Class, Order) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")"))
## `summarise()` regrouping output by 'Phylum', 'Class' (override with `.groups` argument)
samplesize.tes.animals %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species for different animal phyla, classes and orders in the testes meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1:2, valign = "top")
Table 3.5: Number of effect sizes, studies and mean (range) sample size of species for different animal phyla, classes and orders in the testes meta-analysis
Phylum Class Order EffectSizes Studies Sample Size
Arthropoda Arachnida Scorpiones 1 1 8 ( 8 - 8 )
Insecta Coleoptera 2 1 14.5 ( 13 - 16 )
Hemiptera 1 1 2 ( 2 - 2 )
Hymenoptera 2 1 11 ( 11 - 11 )
Lepidoptera 1 1 28 ( 28 - 28 )
Orthoptera 1 1 21 ( 21 - 21 )
Chordata Actinopterygii 7 2 29.4 ( 24 - 36 )
Blenniiformes 2 1 2 ( 2 - 2 )
Cichliformes 4 3 13.5 ( 8 - 29 )
Cypriniformes 2 2 74 ( 37 - 111 )
Amphibia Anura 6 5 40.8 ( 24 - 65 )
Aves 8 6 137.1 ( 17 - 776 )
Anseriformes 2 1 25.5 ( 14 - 37 )
Charadriiformes 1 1 18 ( 18 - 18 )
Galliformes 1 1 32 ( 32 - 32 )
Passeriformes 12 8 22.5 ( 2 - 56 )
Chondrichthyes 2 1 12 ( 12 - 12 )
Mammalia 8 5 42.4 ( 15 - 141 )
Carnivora 3 2 39.7 ( 14 - 59 )
Chiroptera 2 2 29.5 ( 29 - 30 )
Primates 24 10 26.9 ( 2 - 63 )
Rodentia 7 6 9.7 ( 2 - 21 )
# Sample size
ss.phylum <- tes %>% group_by(Phylum) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) 
ss.phylum %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Number of effect sizes, studies, and mean (range) sample size of species of the different phyla included in the testes meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 

# model with intercept
mod.tm.phylum0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Phylum), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.phylum0, digits=3)

# model with intercept
mod.tm.phylum <- rma.mv(yi=Z, V=Var_Z,  mods = ~ Phylum-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.phylum, digits=3)

# I2
I2.tm.phylum <- i2_ml(mod.tm.phylum)

# R2
R2.tm.phylum <- r2_ml(mod.tm.phylum)

# Model Results (includes a prediction interval)
orchard.tm.phylum <- orchaRd::mod_results(mod.tm.phylum, mod="Phylum")
pred <- orchard.tm.phylum$mod_table # Makes it easier to repeat same plot
# Orchard Plot
orchard_plot(orchard.tm.phylum, 
             mod="Phylum", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00"))
Orchard plot showing the relationship between testes size and sperm competition (correlation coefficient <i>r</i>) separate for estimates for the different animal phyla included in the meta-analysis (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

Figure 3.7: Orchard plot showing the relationship between testes size and sperm competition (correlation coefficient r) separate for estimates for the different animal phyla included in the meta-analysis (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

There is no statistically significant difference (Qm=2.97, P=0.085) between the different animal phyla. The estimates were all different from zero. See Summary of moderators: Testes.

3.2.5 Model covariates: Testes

tes <- tes %>% mutate(MP = case_when(ModelPredictors == 0 ~ "No covariates",
                                     ModelPredictors == 1 ~ "Body size covariate",
                                     ModelPredictors == 2 ~ "Body size and other covariates"))      


ss.cov <- tes %>% group_by(ModelPredictors) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) 
ss.cov %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species with no covariates (=0), only body mass (=1) or more covariates (=2) in the model in the testes meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 3.6: Number of effect sizes, studies and mean (range) sample size of species with no covariates (=0), only body mass (=1) or more covariates (=2) in the model in the testes meta-analysis
ModelPredictors EffectSizes Studies Sample Size
0 59 40 38.5 ( 2 - 776 )
1 33 15 27.9 ( 5 - 141 )
2 7 4 42.3 ( 28 - 63 )
# model with intercept
mod.tm.cov0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(ModelPredictors), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.cov0, digits=3)

# model without intercept
mod.tm.cov <- rma.mv(yi=Z, V=Var_Z,  mods = ~ MP-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.cov, digits=3)

# I2
I2.tm.cov <- i2_ml(mod.tm.cov)

# R2
R2.tm.cov <- r2_ml(mod.tm.cov)

# Model Results (includes a prediction interval)
orchard.tm.cov <- orchaRd::mod_results(mod.tm.cov, mod="MP")
pred <- orchard.tm.cov$mod_table # Makes it easier to repeat same plot
# Orchard Plot
orchard_plot(orchard.tm.cov, 
             mod="MP", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00","#00ff73")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73"))
Orchard plot showing the relationship between testes size and sperm competition (correlation coefficient <i>r</i>), separate for estimates resulting from analyses with no other covariates, body size covariates or more complex models (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

Figure 3.8: Orchard plot showing the relationship between testes size and sperm competition (correlation coefficient r), separate for estimates resulting from analyses with no other covariates, body size covariates or more complex models (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

There is no difference between estimates that resulted from analyses with no covariates, body size as covariate or more covariates in the model (Qm=2.3, P=0.316). The estimates were all different from zero. See Summary of moderators: Testes.

3.2.6 Level of correlation: Testes

# Sample size
tes <- tes %>%
  mutate(LC=case_when(
    LevelCorrelation == 'Group' ~ 'Species',
    LevelCorrelation == 'Species' ~ 'Species',
    LevelCorrelation == 'Genus' ~ 'Genus'
  ))

# Sample size
ss.corr <- tes %>% group_by(LC) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")"))
ss.corr %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species calculated at different analysis levels in the testes meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 3.7: Number of effect sizes, studies and mean (range) sample size of species calculated at different analysis levels in the testes meta-analysis
LC EffectSizes Studies Sample Size
Genus 9 4 33.3 ( 28 - 54 )
Species 90 55 35.4 ( 2 - 776 )
# Level of Correlation
mod.tm.corr0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(LC), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.corr0, digits=3)

# Level of Correlation no intercept
mod.tm.corr <- rma.mv(yi=Z, V=Var_Z,  mods = ~ LC-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.corr, digits=3)

# I2
I2.tm.corr <- i2_ml(mod.tm.corr)

# R2
R2.tm.corr <- r2_ml(mod.tm.corr)
# Model Results (includes a prediction interval)
orchard.tm.corr <- orchaRd::mod_results(mod.tm.corr, mod="LC")
pred <- orchard.tm.corr$mod_table # Makes it easier to repeat same plot

# Orchard Plot
orchard_plot(orchard.tm.corr, 
             mod="LC", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00","#00ff73")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73"))
Orchard plot showing the relation between testes size and sperm competition (correlation coefficient <i>r</i>), separated for estimates resulting from correlations on the genus or species level (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

Figure 3.9: Orchard plot showing the relation between testes size and sperm competition (correlation coefficient r), separated for estimates resulting from correlations on the genus or species level (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

There is no difference between estimates that resulted from analyses performed on the genus or species level (Qm=0.53, P=0.468). The estimates were all different from zero. See Summary of moderators: Testes.

3.2.7 Effect of risk or intensity of sperm competition: Testes

# Sample size

ss.roi <- tes %>% group_by(RiskOrIntensity) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")"))
ss.roi %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species of sperm competition risk and intensity estimates in the testes meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 3.8: Number of effect sizes, studies and mean (range) sample size of species of sperm competition risk and intensity estimates in the testes meta-analysis
RiskOrIntensity EffectSizes Studies Sample Size
Sperm competition intensity 14 3 20.9 ( 8 - 36 )
Sperm competition risk 85 56 37.6 ( 2 - 776 )
# Sample size

ss.roi.sc <- tes %>% group_by(SpermComp, RiskOrIntensity) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")"))
## `summarise()` regrouping output by 'SpermComp' (override with `.groups` argument)
ss.roi.sc %>% select(-Mean, -Min, -Max) %>%
  kable(booktabs=TRUE, caption="Number of effect sizes, studies and mean (range) sample size of species of sperm competition risk and intensity estimates in the testes meta-analysis, separated for behavioural and genetic estimates") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 3.9: Number of effect sizes, studies and mean (range) sample size of species of sperm competition risk and intensity estimates in the testes meta-analysis, separated for behavioural and genetic estimates
SpermComp RiskOrIntensity EffectSizes Studies Sample Size
Behavioural estimate Sperm competition intensity 2 1 11 ( 11 - 11 )
Sperm competition risk 64 43 41 ( 2 - 776 )
Genetic estimate Sperm competition intensity 12 2 22.6 ( 8 - 36 )
Sperm competition risk 21 13 27.4 ( 4 - 56 )
# Model with intercept
mod.tm.roi0 <- rma.mv(yi=Z, V=Var_Z, mods=~factor(RiskOrIntensity), random = list( ~1|PrimaryKey, ~1 | EffectSizeKey), slab=Reference, method='REML', data=tes)
summary(mod.tm.roi0, digits=3)


# Model without intercept
mod.tm.roi <- rma.mv(yi=Z, V=Var_Z, mods=~RiskOrIntensity -1, random = list( ~1|PrimaryKey, ~1 | EffectSizeKey), slab=Reference, method='REML', data=tes)
summary(mod.tm.roi, digits=3)


# Model Results (includes a prediction interval)
orchard.tm.roi <- orchaRd::mod_results(mod.tm.roi, mod="RiskOrIntensity")
pred <- orchard.tm.roi$mod_table # Makes it easier to repeat same plot

# I2
I2.tm.roi <- i2_ml(mod.tm.roi)

# R2
R2.tm.roi <- r2_ml(mod.tm.roi)
# Orchard Plot
orchard_plot(orchard.tm.roi, 
             mod="Int", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3","#ffcc00", "#00ff73")) +
  scale_colour_manual(values=c("#007aa3","#ffcc00", "#00ff73"))
Orchard plot showing the relationship between testes size and sperm competition (correlation coefficient <i>r</i>) separated for estimates of sperm competition risk and sperm competition intensity (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

Figure 3.10: Orchard plot showing the relationship between testes size and sperm competition (correlation coefficient r) separated for estimates of sperm competition risk and sperm competition intensity (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

There is no difference in the estimates of sperm competition risk or intensity (Qm=0.65, P=0.419). See Summary of moderators: Testes.



3.2.8 Proxies for testes size: Testes

ss.tsprox <- tes %>% group_by(Response) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")"))
ss.tsprox %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Number of effect sizes, studies, and mean (range) sample size of species in the different proxies for testes size in the testes meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 3.10: Number of effect sizes, studies, and mean (range) sample size of species in the different proxies for testes size in the testes meta-analysis
Response EffectSizes Studies Sample Size
Testes length 3 2 14.3 ( 12 - 18 )
Testes mass 93 54 36.5 ( 2 - 776 )
Testes volume 3 2 17 ( 2 - 28 )
# model with intercept
mod.tm.tsprox0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Response), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.tsprox0, digits=3)

# model without intercept
mod.tm.tsprox <- rma.mv(yi=Z, V=Var_Z,  mods = ~ Response-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes)
summary(mod.tm.tsprox, digits=3)

# I2
I2.tm.tsprox <- i2_ml(mod.tm.tsprox)

# R2
R2.tm.tsprox <- r2_ml(mod.tm.tsprox)

# Model Results (includes a prediction interval)
orchard.tm.tsprox <- orchaRd::mod_results(mod.tm.tsprox, mod="Response")
pred <- orchard.tm.tsprox$mod_table # Makes it easier to repeat same plot
# Orchard Plot
orchard_plot(orchard.tm.tsprox, 
             mod="Response", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00","#00ff73")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73"))

There is no difference (Qm=0.4, P=0.82) between the different proxies for testes size. We therefore can pool the different measurements. See Summary of moderators: Testes.

3.2.9 Summary of moderators: Testes

table_mods_testes <- data.frame("Name" = c("Testes Size Proxy"
                                           ,"Testes Size Proxy"
                                           ,"Testes Size Proxy"
                                           , "Sperm Competition"
                                           ,"Sperm Competition"
                                           , "Phylogenetic Control"
                                           , "Phylogenetic Control"
                                           , "Model Covariates"
                                           , "Model Covariates"
                                           , "Model Covariates"
                                           , paste0("Fertilization Mode", 
                                footnote_marker_symbol(1))
                                           , paste0("Fertilization Mode", 
                                footnote_marker_symbol(1))
                                          , "Animal Phylum", "Animal Phylum"
                                          , "Level of Correlation", "Level of Correlation"),
                               "R2_Marginal" = c(rep(R2.tm.tsprox[1],3)
                                                 , rep(R2.tm.roi[1],2)
                                                 , rep(R2.tm.pc[1],2)
                                                 , rep(R2.tm.cov[1],3)
                                                 , rep(R2.tes.fert[1],2)
                                                 , rep(R2.tm.phylum[1],2)
                                                 , rep(R2.tm.corr[1],2)),
                               "Qm" = c(rep(mod.tm.tsprox0$QM,3)
                                        , rep(mod.tm.roi0$QM,2)
                                        , rep(mod.tm.pc0$QM,2)
                                        , rep(mod.tm.cov0$QM,3)
                                        , rep(mod.tes.fert0$QM,2)
                                        , rep(mod.tm.phylum0$QM,2)
                                        , rep(mod.tm.corr0$QM,2)),
                               "P" = c(rep(mod.tm.tsprox0$QMp,3)
                                       , rep(mod.tm.roi0$QMp,2)
                                       , rep(mod.tm.pc0$QMp,2)
                                       , rep(mod.tm.cov0$QMp,3)
                                       , rep(mod.tes.fert0$QMp,2)
                                       , rep(mod.tm.phylum0$QMp,2)
                                       , rep(mod.tm.corr0$QMp,2)),
                               "k" = c(mod.tm.tsprox0$k,NA, NA
                                       , mod.tm.roi0$k,NA
                                       , mod.tm.pc0$k,NA
                                       , mod.tm.cov0$k,NA,NA
                                       , mod.tes.fert0$k,NA
                                       , mod.tm.phylum0$k,NA
                                       , mod.tm.corr0$k,NA),
                               "k_levels" = c(ss.tsprox$EffectSizes[1]
                                              ,ss.tsprox$EffectSizes[2]
                                              ,ss.tsprox$EffectSizes[3]
                                              ,ss.roi$EffectSizes[1]
                                              ,ss.roi$EffectSizes[2]
                                              ,ss.pc$EffectSizes[1]
                                              ,ss.pc$EffectSizes[2]
                                              ,ss.cov$EffectSizes[1]
                                              ,ss.cov$EffectSizes[2]
                                              ,ss.cov$EffectSizes[3]
                                              ,ss.fert$EffectSizes[1]
                                              ,ss.fert$EffectSizes[2]
                                              ,ss.phylum$EffectSizes[1]
                                              ,ss.phylum$EffectSizes[2]
                                              ,ss.corr$EffectSizes[1]
                                              ,ss.corr$EffectSizes[2]),
                               "No_Levels" = c(rep(length(mod.tm.tsprox0$b), 3)
                                       , rep(length(mod.tm.roi$b),2)
                                       , rep(length(mod.tm.pc$b),2)
                                       , rep(length(mod.tm.cov$b),3)
                                       , rep(length(mod.tes.fert$b),2)
                                       , rep(length(mod.tm.phylum$b),2)
                                       , rep(length(mod.tm.corr$b),2) ),
                               "Level_model" = c(levels(orchard.tm.tsprox$mod_table$name)[1]
                                             ,levels(orchard.tm.tsprox$mod_table$name)[2]
                                             ,levels(orchard.tm.tsprox$mod_table$name)[3]
                                             , levels(orchard.tm.roi$mod_table$name)[1]
                                             , levels(orchard.tm.roi$mod_table$name)[2]
                                       , levels(orchard.tm.pc$mod_table$name)[1]
                                                , levels(orchard.tm.pc$mod_table$name)[2]
                                       , levels(orchard.tm.cov$mod_table$name)[1]
                                                , levels(orchard.tm.cov$mod_table$name)[2]
                                                         , levels(orchard.tm.cov$mod_table$name)[3]
                                       , levels(orchard.tes.fert$mod_table$name)[1]
                                                , levels(orchard.tes.fert$mod_table$name)[2]
                                       , levels(orchard.tm.phylum$mod_table$name)[1]
                                                , levels(orchard.tm.phylum$mod_table$name)[2]
                                       , levels(orchard.tm.corr$mod_table$name)[1] 
                                                , levels(orchard.tm.corr$mod_table$name)[2]),
                               "Level" = c(levels(orchard.tm.tsprox$mod_table$name)[1]
                                             ,levels(orchard.tm.tsprox$mod_table$name)[2]
                                             ,levels(orchard.tm.tsprox$mod_table$name)[3]
                                             , "Intensity"
                                             , "Risk"
                                       , "No"
                                                , "Yes"
                                       , "No covariates"
                                                , "Body mass covariate"
                                                         , "More covariates"
                                       , levels(orchard.tes.fert$mod_table$name)[1]
                                                , levels(orchard.tes.fert$mod_table$name)[2]
                                       , levels(orchard.tm.phylum$mod_table$name)[1]
                                                , levels(orchard.tm.phylum$mod_table$name)[2]
                                       , levels(orchard.tm.corr$mod_table$name)[1] 
                                                , levels(orchard.tm.corr$mod_table$name)[2]),
                               "beta" = c( mod.tm.tsprox$beta[1]
                                        ,mod.tm.tsprox$beta[2]
                                        ,mod.tm.tsprox$beta[3]
                                        , mod.tm.roi$beta[1]
                                        , mod.tm.roi$beta[2]
                                       , mod.tm.pc$beta[1]
                                       , mod.tm.pc$beta[2]
                                       , mod.tm.cov$beta[1]
                                       , mod.tm.cov$beta[2]
                                       , mod.tm.cov$beta[3]
                                       , mod.tes.fert$beta[1]
                                       , mod.tes.fert$beta[2]
                                       , mod.tm.phylum$beta[1]
                                       , mod.tm.phylum$beta[2]
                                       , mod.tm.corr$beta[1]
                                       , mod.tm.corr$beta[2]),
                               "ci.lb" = c(mod.tm.tsprox$ci.ub[1]
                                        ,mod.tm.tsprox$ci.lb[2]
                                        ,mod.tm.tsprox$ci.lb[3]
                                        , mod.tm.roi$ci.lb[1]
                                        , mod.tm.roi$ci.lb[2]
                                       , mod.tm.pc$ci.lb[1]
                                       , mod.tm.pc$ci.lb[2]
                                       , mod.tm.cov$ci.lb[1]
                                       , mod.tm.cov$ci.lb[2]
                                       , mod.tm.cov$ci.lb[3]
                                       , mod.tes.fert$ci.lb[1]
                                       , mod.tes.fert$ci.lb[2]
                                       , mod.tm.phylum$ci.lb[1]
                                       , mod.tm.phylum$ci.lb[2]
                                       , mod.tm.corr$ci.lb[1]
                                       , mod.tm.corr$ci.lb[2]),
                               "ci.ub" = c(mod.tm.tsprox$ci.ub[1]
                                        ,mod.tm.tsprox$ci.ub[2]
                                        ,mod.tm.tsprox$ci.ub[3]
                                        , mod.tm.roi$ci.ub[1]
                                        , mod.tm.roi$ci.ub[2]
                                       , mod.tm.pc$ci.ub[1]
                                       , mod.tm.pc$ci.ub[2]
                                       , mod.tm.cov$ci.ub[1]
                                       , mod.tm.cov$ci.ub[2]
                                       , mod.tm.cov$ci.ub[3]
                                       , mod.tes.fert$ci.ub[1]
                                       , mod.tes.fert$ci.ub[2]
                                       , mod.tm.phylum$ci.ub[1]
                                       , mod.tm.phylum$ci.ub[2]
                                       , mod.tm.corr$ci.ub[1]
                                       , mod.tm.corr$ci.ub[2]),
                               "Z" = c( mod.tm.tsprox$zval[1]
                                        ,mod.tm.tsprox$zval[2]
                                        ,mod.tm.tsprox$zval[3]
                                        , mod.tm.roi$zval[1]
                                        , mod.tm.roi$zval[2]
                                       , mod.tm.pc$zval[1]
                                       , mod.tm.pc$zval[2]
                                       , mod.tm.cov$zval[1]
                                       , mod.tm.cov$zval[2]
                                       , mod.tm.cov$zval[3]
                                       , mod.tes.fert$zval[1]
                                       , mod.tes.fert$zval[2]
                                       , mod.tm.phylum$zval[1]
                                       , mod.tm.phylum$zval[2]
                                       , mod.tm.corr$zval[1]
                                       , mod.tm.corr$zval[2]),
                               "PZ" = c( mod.tm.tsprox$pval[1]
                                        ,mod.tm.tsprox$pval[2]
                                        ,mod.tm.tsprox$pval[3]
                                        , mod.tm.roi$pval[1]
                                        , mod.tm.roi$pval[2]
                                       , mod.tm.pc$pval[1]
                                       , mod.tm.pc$pval[2]
                                       , mod.tm.cov$pval[1]
                                       , mod.tm.cov$pval[2]
                                       , mod.tm.cov$pval[3]
                                       , mod.tes.fert$pval[1]
                                       , mod.tes.fert$pval[2]
                                       , mod.tm.phylum$pval[1]
                                       , mod.tm.phylum$pval[2]
                                       , mod.tm.corr$pval[1]
                                       , mod.tm.corr$pval[2]))

table_mods <- table_mods_testes %>% transmute(Moderator = Name,
                                             "R2(%)" = round(R2_Marginal * 100,2),
                                             Qm =round(Qm, 2),
                                             "P(Qm)" = cell_spec(round(P, 3),"html",  bold=ifelse(P <0.05, TRUE, FALSE)),
                                             k = ifelse(is.na(k), "", k),
                                             k_level = k_levels,
                                             Level = Level,
                                             beta = round(beta,2),
                                             ci.lb = round(ci.lb,2),
                                             ci.ub = round(ci.ub,2),
                                             "95%CI" = paste("[ ",ci.lb,"; ", ci.ub, " ]", sep=""),
                                             Z = round(Z,2),
                                             "P(Z)" = cell_spec(ifelse(PZ < 0.0001, "<0.0001", round(PZ,3) ), "html", bold = ifelse(PZ < 0.05, TRUE,FALSE)))

# names(table_mods)

colnames(table_mods)[2] <- "*R^2^(%)*"
colnames(table_mods)[3] <- "*Q<sub>m</sub>*"
colnames(table_mods)[4] <- "*P(Q<sub>m</sub>)*"
colnames(table_mods)[5] <- "*k<sub>total</sub>*"
colnames(table_mods)[6] <- "*k*"
colnames(table_mods)[8] <- "*&beta;*"
colnames(table_mods)[11] <- "*95 %CI*"
colnames(table_mods)[12] <- "*Z*"
colnames(table_mods)[13] <- "*P(Z)*"

table_mods %>% select(-ci.lb, -ci.ub) %>% kable(format="html", escape=F, caption="Summary Table Meta-Regressions Testes") %>% 
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1:5, valign = "top") %>% 
  add_header_above(c(" " = 1, "Moderator Effects" = 4, "Estimates Different From 0?" = 6)) %>%
  footnote("* Excluding studies with both internal and external fertilizers", title_format = "bold")
Table 3.11: Summary Table Meta-Regressions Testes
Moderator Effects
Estimates Different From 0?
Moderator R2(%) Qm P(Qm) ktotal k Level ? 95 %CI Z P(Z)
Testes Size Proxy 0.69 0.40 0.82 99 3 Testes length 0.81 [ 1.47; 1.47 ] 2.40 0.016
93 Testes mass 0.70 [ 0.58; 0.83 ] 11.05 <0.0001
3 Testes volume 0.54 [ -0.05; 1.13 ] 1.78 0.075
Sperm Competition 1.00 0.65 0.419 99 14 Intensity 0.81 [ 0.52; 1.1 ] 5.43 <0.0001
85 Risk 0.69 [ 0.57; 0.81 ] 11.51 <0.0001
Phylogenetic Control 10.04 5.80 0.016 99 46 No 0.81 [ 0.67; 0.96 ] 10.86 <0.0001
53 Yes 0.57 [ 0.42; 0.72 ] 7.46 <0.0001
Model Covariates 4.18 2.30 0.316 99 59 No covariates 0.46 [ 0.04; 0.87 ] 2.14 0.032
33 Body mass covariate 0.64 [ 0.42; 0.85 ] 5.84 <0.0001
7 More covariates 0.75 [ 0.61; 0.89 ] 10.55 <0.0001
Fertilization Mode* 6.68 4.09 0.043 90 12 External 0.45 [ 0.18; 0.72 ] 3.23 0.001
78 Internal 0.76 [ 0.63; 0.89 ] 11.49 <0.0001
Animal Phylum 5.51 2.97 0.085 99 8 Arthropoda 1.01 [ 0.63; 1.38 ] 5.28 <0.0001
91 Chordata 0.66 [ 0.54; 0.78 ] 10.76 <0.0001
Level of Correlation 1.23 0.53 0.468 99 9 Genus 0.84 [ 0.43; 1.26 ] 4.01 <0.0001
90 Species 0.69 [ 0.57; 0.81 ] 11.25 <0.0001
Note:
* Excluding studies with both internal and external fertilizers

4 Sperm meta-analysis


In studies using testes size as a proxy for sperm competition, testes size was most often quantified as mass, but some studies used other measures such as area, length, or volume. Before testing whether sperm competition metrics (behavioural estimates, genetic estimates, and testes size) differed among one another, we therefore explored whether the different testes size measurements could be pooled together. Focusing on studies with sperm total length as the response variable, testes length was significantly different from the other testes size measurements (see Proxies for Testes Size: Sperm). Testes length was therefore excluded when testing for differences among sperm competition metrics.

Furthermore, different metrics (e.g.?length, volume, area) were used to quantify sperm morphology among studies. We did not detect any differences in effect sizes among alternative metrics of sperm head and flagellum morphology (sperm head length vs.?area: Qm=4.62, k=30, P=0.10; sperm flagellum length vs.?principal + end piece length: Qm=0.01, k=34, P=0.92). However, effect sizes were significantly greater when sperm midpiece was quantified using midpiece volume compared with midpiece length (Qm=4.8, k=28, P=0.03), although we note that all four of the effect sizes examining midpiece volume came from a single study (see Effect of different sperm components).

We reran the overall analysis presented in the main text, this time without testes length as a sperm competition proxy and without sperm midpiece volume as a response variable, in order to test whether this would impact our results. We obtained qualitatively similar results when excluding these effect sizes (effect sizes for all sperm components did not differ from one another: Qm=6.9, k=173, P=0.08; all sperm components responded similarly and were significantly positively related with sperm competition level: sperm head: Z=2.34, P=0.02; sperm midpiece: Z=3.06, P=0.002; sperm flagellum: Z=495, P<0.001, sperm total length: Z=5.49, P<0.001) (see With sperm midpiece volume and testes length excluded from the dataset).

sp <- read.csv("Sperm-metaV2.csv")

# subset as factors
sp$UniqueBehav <- as.factor(sp$UniqueBehav)
sp$UniqueTMByTaxon <- as.factor(sp$UniqueTMByTaxon)
sp$UniqueTMLargest <- as.factor(sp$UniqueTMLargest)
sp$UniqueGenetic <- as.factor(sp$UniqueGenetic)

# Let's reorder the components in a logical fashion
sp$Response3 <- factor(sp$Response3, levels = c( "Sperm flagellum length", "Sperm midpiece length", "Sperm head length", "Sperm total length"))

sp <- sp %>%
  mutate(SpermComp2=case_when(
    SpermCompetition2 == 'Genetic estimate' ~ 'Genetic estimate',
    SpermCompetition2 == 'Behavioral estimate' ~ 'Behavioural estimate',
    SpermCompetition2 == 'Testes size' ~ 'Testes size',
    SpermCompetition2 == 'Testes length' ~ 'Testes length'
  ))

sp <- sp %>%
  mutate(SpermComp3=case_when(
    SpermCompetition3 == 'Genetic estimate' ~ 'Genetic estimate',
    SpermCompetition3 == 'Behavioral estimate' ~ 'Behavioural estimate',
    SpermCompetition3 == 'Testes size' ~ 'Testes size'
  ))

4.1 Sperm size in relation to sperm competition (overall effect)

sp %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) %>% select(-Mean,-Min,-Max) %>%
  kable(booktabs=TRUE, caption="Number of effect sizes, studies and mean (range) sample size of species for all data") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 4.1: Number of effect sizes, studies and mean (range) sample size of species for all data
EffectSizes Studies Sample Size
186 74 42.3 ( 2 - 232 )
# Model with intercept
mod.sp.all0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp)
summary(mod.sp.all0, digits=3)


# Model Results (includes a prediction interval)
orchard.sp.all <- orchaRd::mod_results(mod.sp.all0, mod="Intcpt")


# I2
I2.sp.all <- i2_ml(mod.sp.all0)

# R2
R2.sp.all <- r2_ml(mod.sp.all0)
# Forest Plot
mod <- mod.sp.all0 # Which model?
x_loc = -2 # Where does the summary statistic need to go?
col = '#f64949' # What color does the summary statistic need to be?
data = sp %>% 
  arrange(Z) %>% 
  mutate(EffectSizeKey = factor(EffectSizeKey, levels= EffectSizeKey)) # Which data and organise by Z

ggplot() +
  geom_hline(yintercept = 0, lty = 1, lwd = 1, colour = "black", alpha = 0.8) +
  geom_pointrange(data = data,aes(x = EffectSizeKey, y = Z, ymin = ci.lb, ymax = ci.ub), size=0.2) +
  geom_errorbar(aes(x=x_loc, ymin=pred$lowerPR, ymax = pred$upperPR), color='#ffcc00', width=1)+
  geom_point(aes(x=x_loc, y=mod$b),size=4, color=col, pch=18)+
  geom_errorbar(aes(x=x_loc, ymin=mod$ci.lb, ymax = mod$ci.ub), color=col, width=3)+
  coord_flip()+ 
  theme_classic() + 
  labs(x="Study", 
       y="Fisher's Z") +
  expand_limits(x=-5)+
  annotate(geom="text",x=10, y=2,label="k=186")
Forest plot of all estimates (Fisher's <i>Z</i>) of sperm size in relation to sperm competition (meta-analytic mean and 95% confidence interval in red, 95% prediction interval in yellow).

Figure 4.1: Forest plot of all estimates (Fisher?s Z) of sperm size in relation to sperm competition (meta-analytic mean and 95% confidence interval in red, 95% prediction interval in yellow).

# Orchard Plot
orchard_plot(orchard.sp.all, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b"))
Orchard plot showing the relation (correlation coefficient <i>r</i>) between sperm length and sperm competition for all data (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

Figure 4.2: Orchard plot showing the relation (correlation coefficient r) between sperm length and sperm competition for all data (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).


Taking all sperm components and all sperm competition proxies together, there is an overall positive relationship between sperm length and sperm competition (Fisher?s Z= 0.36 [0.24; 0.49]). The estimate is different from zero (Z=5.86, P<0.0001). Fisher?s Z translates into a correlation coefficient r of 0.35 between sperm length and sperm competition.

4.2 Assessing moderators

4.2.1 Effect of sperm competition type: Sperm

sp %>% filter(SpermComp2 != "Testes length" & Response == "Sperm total length") %>% group_by(SpermComp2) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) %>% select(-Mean,-Min,-Max) %>%
  kable(booktabs=TRUE, caption="Number of effect sizes, studies and mean (range) sample size of species grouped by sperm competition type, excluding 'testes length' and only for estimates of sperm total length") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 4.2: Number of effect sizes, studies and mean (range) sample size of species grouped by sperm competition type, excluding ?testes length? and only for estimates of sperm total length
SpermComp2 EffectSizes Studies Sample Size
Behavioural estimate 19 15 28.5 ( 2 - 130 )
Genetic estimate 8 6 29.1 ( 12 - 55 )
Testes size 61 45 43.3 ( 3 - 232 )
# Model with intercept
mod.stl.mod.sc0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(SpermComp2), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(SpermComp2 != "Testes length" & Response == "Sperm total length"))
summary(mod.stl.mod.sc0, digits=3)

# Model without intercept
mod.stl.mod.sc <- rma.mv(yi=Z, V=Var_Z,  mods = ~ SpermComp2 -1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(SpermComp2 != "Testes length" & Response == "Sperm total length"))
summary(mod.stl.mod.sc, digits=3)

# Model Results (includes a prediction interval)
orchard.stl.mod.sc <- orchaRd::mod_results(mod.stl.mod.sc, mod="SpermComp2")
pred <- orchard.stl.mod.sc$mod_table # Makes it easier to repeat same plot

# I2
I2.stl.mod.sc <- i2_ml(mod.stl.mod.sc)

# R2
R2.stl.mod.sc <- r2_ml(mod.stl.mod.sc)
# Forest Plot
mod <- mod.stl.mod.sc # Which model?
x_loc = -2 # Where does the summary statistic need to go?
x_loc2 = 21 # Where does the second summary statistic need to go?
x_loc3 = 33
col = '#b90702' # What color does the summary statistic need to be?

data = sp %>%
  filter(SpermCompetition2 != "Testes length" & Response == "Sperm total length") %>%
  arrange(SpermCompetition2, Z) %>% 
  add_row(EffectSizeKey="", Z=0, ci.lb=0, ci.ub=0, .before=20) %>%
  add_row(EffectSizeKey=" ", Z=0, ci.lb=0, ci.ub=0, .before=20) %>%
  add_row(EffectSizeKey="  ", Z=0, ci.lb=0, ci.ub=0, .before=20) %>%
  add_row(EffectSizeKey="   ", Z=0, ci.lb=0, ci.ub=0, .before=31) %>%
  add_row(EffectSizeKey="    ", Z=0, ci.lb=0, ci.ub=0, .before=31) %>%
  add_row(EffectSizeKey="     ", Z=0, ci.lb=0, ci.ub=0, .before=31) %>%
  mutate(EffectSizeKey = factor(EffectSizeKey, levels= EffectSizeKey)) # Which data and organise by Z. Adding empty rows to add the second summary stat.

#label = levels(pred$name)
label = c("Behavioural estimates k=19", "Genetic estimates k=8", "Testes size k=61")
x1 = (length(data[data$SpermCompetition2 == "Behavioral estimate",]$Z) / 2)
x2 = x1 + (length(data[data$SpermCompetition2 == "Genetic estimate",]$Z))
x3 = x2 + (length(data[data$SpermCompetition2 == "Testes mass",]$Z)) + 12
y = max(data$ci.ub) - 1.2

ggplot() +
  geom_hline(yintercept = 0, lty = 1, lwd = 2, colour = "black") +
  geom_pointrange(data = data,aes(x = EffectSizeKey, y = Z, ymin = ci.lb, ymax = ci.ub), size=0.1) +
  geom_errorbar(aes(x=x_loc, ymin=pred$lowerPR[1], ymax = pred$upperPR[1]), color='#ffcc00', width=1)+
  geom_point(aes(x=x_loc, y=mod$b[1]),size=4, color=col, pch=18)+
  geom_errorbar(aes(x=x_loc, ymin=mod$ci.lb[1], ymax = mod$ci.ub[1]), color=col, width=3)+
  geom_errorbar(aes(x=x_loc2, ymin=pred$lowerPR[2], ymax = pred$upperPR[2]), color='#ffcc00', width=1)+
  geom_point(aes(x=x_loc2, y=mod$b[2]),size=4, color=col, pch=18)+
  geom_errorbar(aes(x=x_loc2, ymin=mod$ci.lb[2], ymax = mod$ci.ub[2]), color=col, width=3)+
  geom_errorbar(aes(x=x_loc3, ymin=pred$lowerPR[3], ymax = pred$upperPR[3]), color='#ffcc00', width=1)+
  geom_point(aes(x=x_loc3, y=mod$b[3]),size=4, color=col, pch=18)+
  geom_errorbar(aes(x=x_loc3, ymin=mod$ci.lb[3], ymax = mod$ci.ub[3]), color=col, width=3)+
  coord_flip()+ 
  theme_classic() + 
  labs(x="Study", 
       y="Fisher's Z") +
  expand_limits(x= -5) +
  scale_x_discrete(drop=FALSE) +
  annotate("text", x = c(x1,x2,x3), y = c(y,y,y), label = label, size=4)
Forest plot showing the relationship between sperm length and sperm competition, separated by behavioural and genetic estimates, and testes size as sperm competition proxy (meta-analytic mean and 95% confidence interval in red, 95% prediction interval in yellow). Note that this analysis only includes estimates of sperm total length.

Figure 4.3: Forest plot showing the relationship between sperm length and sperm competition, separated by behavioural and genetic estimates, and testes size as sperm competition proxy (meta-analytic mean and 95% confidence interval in red, 95% prediction interval in yellow). Note that this analysis only includes estimates of sperm total length.

# Orchard Plot
orchard_plot(orchard.stl.mod.sc, 
             mod="SpermComp2", 
             xlab = "Correlation Coefficient (r)", 
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b"))
Orchard plot showing the relation (correlation coefficient <i>r</i>) between sperm length and sperm competition, separated for behavioural and genetic estimates, and testes size as proxy for sperm competition (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this only includes estimates of sperm total length.

Figure 4.4: Orchard plot showing the relation (correlation coefficient r) between sperm length and sperm competition, separated for behavioural and genetic estimates, and testes size as proxy for sperm competition (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this only includes estimates of sperm total length.

ggsave("Figure2-sperm-precision.tiff")

There is no difference in the estimates (Fisher?s Z) of the different sperm competition variables when considering sperm total length only (Qm=0.954, P=0.621). The estimates of the different sperm components are all different from zero and translate into correlation coefficients r of 0.25, 0.4 and 0.26 respectively.

Note: ?Testes length? was excluded from the testes size estimate because that estimate differed significantly from the other estimates of testes size (see Proxies for testes size: Sperm).



4.2.2 Length of different sperm components in relation to sperm competition

sp %>% group_by(Response3) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species of different sperm components") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 4.3: Number of effect sizes, studies and mean (range) sample size of species of different sperm components
Response3 EffectSizes Studies Sample Size
Sperm flagellum length 34 26 47.8 ( 2 - 232 )
Sperm midpiece length 28 21 45.6 ( 2 - 194 )
Sperm head length 30 23 47.2 ( 2 - 232 )
Sperm total length 94 64 37.8 ( 2 - 232 )
mod.sl.overall0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Response3), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp)
summary(mod.sl.overall0, digits=3)

mod.sl.overall <- rma.mv(yi=Z, V=Var_Z,  mods = ~ Response3 -1, random = list( ~1 |PrimaryKey, ~1|EffectSizeKey), method='REML', data=sp)
summary(mod.sl.overall, digits=3)

# Model Results (includes a prediction interval)
orchard.sl.overall <- orchaRd::mod_results(mod.sl.overall, mod="Response3")
pred <- orchard.sl.overall$mod_table # Makes it easier to repeat same plot

# I2
I2.sl.overall <- i2_ml(mod.sl.overall)

# R2
R2.sl.overall <- r2_ml(mod.sl.overall)
# Forest Plot
mod <- mod.sl.overall # Which model?
x_loc = -2 # Where does the summary statistic need to go?
x_loc2 = 36 # Where does the second summary statistic need to go?
x_loc3 = 67
x_loc4 = 100
col = '#b90702' # What color does the summary statistic need to be?

data = sp %>%
  arrange(Response3, Z) %>% 
  add_row(EffectSizeKey="", Z=0, ci.lb=0, ci.ub=0, .before=35) %>%
  add_row(EffectSizeKey=" ", Z=0, ci.lb=0, ci.ub=0, .before=35) %>%
  add_row(EffectSizeKey="  ", Z=0, ci.lb=0, ci.ub=0, .before=35) %>%
  add_row(EffectSizeKey="   ", Z=0, ci.lb=0, ci.ub=0, .before=66) %>%
  add_row(EffectSizeKey="    ", Z=0, ci.lb=0, ci.ub=0, .before=66) %>%
  add_row(EffectSizeKey="     ", Z=0, ci.lb=0, ci.ub=0, .before=66) %>%
  add_row(EffectSizeKey="      ", Z=0, ci.lb=0, ci.ub=0, .before=99) %>%
  add_row(EffectSizeKey="       ", Z=0, ci.lb=0, ci.ub=0, .before=99) %>%
  add_row(EffectSizeKey="        ", Z=0, ci.lb=0, ci.ub=0, .before=99) %>%
  mutate(EffectSizeKey = factor(EffectSizeKey, levels= EffectSizeKey)) # Which data and organise by Z. Adding empty rows to add the second summary stat.

#label = levels(pred$name)
label = c("Sperm flagellum length k=34", "Sperm midpiece length k=28", "Sperm head length k=30", "Sperm total length k=94")
x1 = (length(data[data$Response3 == "Sperm flagellum length",]$Z) / 2) 
x2 = 45
x3 = 75
x4 = 130
y = max(data$ci.ub) - 1.5

ggplot() +
  geom_hline(yintercept = 0, lty = 1, lwd = 2, colour = "black") +
  geom_pointrange(data = data,aes(x = EffectSizeKey, y = Z, ymin = ci.lb, ymax = ci.ub), size=0.1) +
  geom_errorbar(aes(x=x_loc, ymin=pred$lowerPR[1], ymax = pred$upperPR[1]), color='#ffcc00', width=1)+
  geom_point(aes(x=x_loc, y=mod$b[1]),size=4, color=col, pch=18)+
  geom_errorbar(aes(x=x_loc, ymin=mod$ci.lb[1], ymax = mod$ci.ub[1]), color=col, width=3)+
  geom_errorbar(aes(x=x_loc2, ymin=pred$lowerPR[2], ymax = pred$upperPR[2]), color='#ffcc00', width=1)+
  geom_point(aes(x=x_loc2, y=mod$b[2]),size=4, color=col, pch=18)+
  geom_errorbar(aes(x=x_loc2, ymin=mod$ci.lb[2], ymax = mod$ci.ub[2]), color=col, width=3)+
  geom_errorbar(aes(x=x_loc3, ymin=pred$lowerPR[3], ymax = pred$upperPR[3]), color='#ffcc00', width=1)+
  geom_point(aes(x=x_loc3, y=mod$b[3]),size=4, color=col, pch=18)+
  geom_errorbar(aes(x=x_loc3, ymin=mod$ci.lb[3], ymax = mod$ci.ub[3]), color=col, width=3)+
  geom_errorbar(aes(x=x_loc4, ymin=pred$lowerPR[4], ymax = pred$upperPR[4]), color='#ffcc00', width=1)+
  geom_point(aes(x=x_loc4, y=mod$b[4]),size=4, color=col, pch=18)+
  geom_errorbar(aes(x=x_loc4, ymin=mod$ci.lb[4], ymax = mod$ci.ub[4]), color=col, width=3)+
  coord_flip()+ 
  theme_classic() + 
  labs(x="Study", 
       y="Fisher's Z") +
  expand_limits(x= -5) +
  scale_x_discrete(drop=FALSE) +
  annotate("text", x = c(x1,x2,x3,x4), y = c(y,y,y,y), label = label, size=4)
Forest plot showing the relationship between sperm length and sperm competition (Fisher's <i>Z</i>), separated for different sperm components (meta-analytic mean and 95% confidence interval in red, 95% prediction interval in yellow).

Figure 4.5: Forest plot showing the relationship between sperm length and sperm competition (Fisher?s Z), separated for different sperm components (meta-analytic mean and 95% confidence interval in red, 95% prediction interval in yellow).

# Orchard Plot
orchard_plot(orchard.sl.overall, 
             mod="Response2", 
             xlab = "Correlation Coefficient (r)", 
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b"))
Orchard plot showing the relationship (correlation coefficient <i>r</i>) between sperm length and sperm competition, separated for different sperm length components (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

Figure 4.6: Orchard plot showing the relationship (correlation coefficient r) between sperm length and sperm competition, separated for different sperm length components (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey).

ggsave("Figure3-spermcomponents-precision.tiff")

There is a difference between the different sperm components (Qm=8.04, P=0.045). The estimates are all different from zero, and translate into correlation coefficients r of 0.39 for Sperm flagellum length, 0.3 for Sperm midpiece length, 0.22 for Sperm head length and 0.37 for Sperm total length. Thus, overall there is a positive relationship between sperm competition and sperm length.

NOTE: The same analysis was performed again without Sperm midpiece volume as response variable, and without Testes length as proxy for testes size (see Sensitivity analysis). The results did not change. The analysis was done again without those points because they are influential data points (see Effect of different sperm components and Proxies for testes size: Sperm).

4.2.3 Fertilization mode: Sperm

NOTE: Excluding studies with both internal and external fertilizers.

# Sample size
ss.s.fert <- sp %>% group_by(Fertilization) %>% filter(Response == "Sperm total length" & Fertilization != "Both") %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) 
ss.s.fert %>% select(-Mean, -Min, -Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species of internal and external fertilizing animals in the sperm meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 4.4: Number of effect sizes, studies and mean (range) sample size of species of internal and external fertilizing animals in the sperm meta-analysis
Fertilization EffectSizes Studies Sample Size
External 10 6 50.9 ( 7 - 130 )
Internal 82 57 36.5 ( 2 - 232 )
# model with intercept
mod.stl.fert0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Fertilization), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Fertilization != "Both" & Response == "Sperm total length"))
summary(mod.stl.fert0, digits=3)

# model without intercept
mod.stl.fert <- rma.mv(yi=Z, V=Var_Z,  mods = ~ Fertilization-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Fertilization != "Both" & Response == "Sperm total length"))
summary(mod.stl.fert, digits=3)

# I2
I2.stl.fert<- i2_ml(mod.stl.fert)

# R2
R2.stl.fert <- r2_ml(mod.stl.fert)

# Model Results (includes a prediction interval)
orchard.stl.fert <- orchaRd::mod_results(mod.stl.fert, mod="Fertilization")
pred <- orchard.stl.fert$mod_table # Makes it easier to repeat same plot
# Orchard Plot
orchard_plot(orchard.stl.fert, 
             mod="Fertilization", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00"))
Orchard plot showing the relationship (correlation coefficient <i>r</i>) between sperm length and sperm competition, separated for internally and externally fertilizing species (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as response variable.

Figure 4.7: Orchard plot showing the relationship (correlation coefficient r) between sperm length and sperm competition, separated for internally and externally fertilizing species (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as response variable.

There is no difference in the estimates of internally and externally fertilizing species (Qm=0.329, P=0.566). The estimates are not (all) different from zero. See Summary of moderators: Sperm.



4.2.4 Phylogenetic control: Sperm

# sample size
sp <- sp %>% mutate(PC = case_when(PhylogeneticControl == 0 ~ "No",
                                   PhylogeneticControl == 1 ~ "Yes"))

ss.s.pc <- sp  %>%  filter(Response == "Sperm total length") %>% group_by(PhylogeneticControl) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) 
ss.s.pc %>% select(-Mean,-Min,-Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species with (=1) and without (=0) phylogenetic control in the sperm meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 4.5: Number of effect sizes, studies and mean (range) sample size of species with (=1) and without (=0) phylogenetic control in the sperm meta-analysis
PhylogeneticControl EffectSizes Studies Sample Size
0 28 23 31 ( 2 - 232 )
1 66 44 40.7 ( 5 - 226 )
# model with intercept
mod.stl.pc0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(PhylogeneticControl), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response == "Sperm total length"))
summary(mod.stl.pc0, digits=3)

# model without intercept
mod.stl.pc <- rma.mv(yi=Z, V=Var_Z,  mods = ~ PC-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response == "Sperm total length"))
summary(mod.stl.pc, digits=3)

# I2
I2.stl.pc <- i2_ml(mod.stl.pc)

# R2
R2.stl.pc <- r2_ml(mod.stl.pc)

# Model Results (includes a prediction interval)
orchard.stl.pc <- orchaRd::mod_results(mod.stl.pc, mod="PC")
pred <- orchard.stl.pc$mod_table # Makes it easier to repeat same plot
# Orchard Plot
orchard_plot(orchard.stl.pc, 
             mod="PhylogeneticControl", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3","#ffcc00")) +
  scale_colour_manual(values=c("#007aa3","#ffcc00"))
Orchard plot showing the relation (correlation coefficient <i>r</i>) between sperm length and sperm competition, separated for estimates that were phylogenetically controlled or not (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as response variable.

Figure 4.8: Orchard plot showing the relation (correlation coefficient r) between sperm length and sperm competition, separated for estimates that were phylogenetically controlled or not (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as response variable.

There is a difference in the estimates between sperm length and sperm competition that were controlled for phylogenetic dependency and those that were not (Qm=9.331, P=0.002). The estimates are all different from zero. See Summary of moderators: Sperm.



4.2.5 Animal phylum: Sperm

samplesize.sp.animals <- sp %>% group_by(Phylum, Class, Order) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")"))
samplesize.sp.animals %>% select(-Mean,-Min,-Max) %>%
  kable(caption="Number of effect sizes, studies, and mean (range) sample size of species of different animal phyla, classes and orders in the sperm meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1:2, valign = "top") 
Table 4.6: Number of effect sizes, studies, and mean (range) sample size of species of different animal phyla, classes and orders in the sperm meta-analysis
Phylum Class Order EffectSizes Studies Sample Size
Arthropoda Arachnida Scorpiones 2 1 8 ( 8 - 8 )
Insecta 1 1 3 ( 3 - 3 )
Coleoptera 5 5 17.6 ( 10 - 30 )
Diptera 9 9 20.8 ( 11 - 55 )
Hemiptera 3 1 2 ( 2 - 2 )
Hymenoptera 3 2 20.3 ( 12 - 27 )
Lepidoptera 2 2 76 ( 25 - 127 )
Chordata Actinopterygii 3 2 32.3 ( 12 - 46 )
Cichliformes 6 3 12.8 ( 7 - 29 )
Amphibia Anura 16 4 56.2 ( 22 - 130 )
Aves 10 3 12 ( 3 - 42 )
Galliformes 6 3 24.5 ( 22 - 31 )
Passeriformes 37 11 62.8 ( 3 - 232 )
Psittaciformes 1 1 10 ( 10 - 10 )
Chondrichthyes 4 1 16.5 ( 16 - 18 )
Mammalia 24 7 94.5 ( 14 - 226 )
Artiodactyla 9 4 30.8 ( 3 - 53 )
Carnivora 1 1 19 ( 19 - 19 )
Insectivora 3 1 4 ( 4 - 4 )
Primates 15 6 26.9 ( 15 - 34 )
Rodentia 22 15 24.5 ( 2 - 106 )
Reptilia Squamata 4 1 25 ( 25 - 25 )
# Sample size
ss.s.phylum <- sp %>% filter(Response=="Sperm total length") %>% group_by(Phylum) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) 
ss.s.phylum %>% select(-Mean,-Min,-Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species of the different phyla included in the sperm meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 

# model with intercept
mod.stl.phylum0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Phylum), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response=="Sperm total length"))
summary(mod.stl.phylum0, digits=3)

# model with intercept
mod.stl.phylum <- rma.mv(yi=Z, V=Var_Z,  mods = ~ Phylum-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response=="Sperm total length"))
summary(mod.stl.phylum, digits=3)

# I2
I2.stl.phylum <- i2_ml(mod.stl.phylum)

# R2
R2.stl.phylum <- r2_ml(mod.stl.phylum)
# Model Results (includes a prediction interval)
orchard.stl.phylum <- orchaRd::mod_results(mod.stl.phylum, mod="Phylum")
pred <- orchard.stl.phylum$mod_table # Makes it easier to repeat same plot

# Orchard Plot
orchard_plot(orchard.stl.phylum, 
             mod="Phylum", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00"))
Orchard plot showing the relation (correlation coefficient <i>r</i>) between sperm length and sperm competition, separated for the different animal phyla included in the meta-analysis (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as response variable

Figure 4.9: Orchard plot showing the relation (correlation coefficient r) between sperm length and sperm competition, separated for the different animal phyla included in the meta-analysis (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as response variable

There is a difference in the correlation between sperm length and sperm competition for different animal phyla (Qm=8.687, P=0.003). The estimates are all different from zero. See Summary of moderators: Sperm.



4.2.6 Model covariates: Sperm

sp <- sp %>% mutate(MP = case_when(ModelPredictors == 0 ~ "No covariates",
                                     ModelPredictors == 1 ~ "Body size covariate",
                                     ModelPredictors == 2 ~ "Body size and other covariates"))      


ss.s.cov <- sp %>% filter(ModelPredictors != "NA" & Response == "Sperm total length") %>% group_by(ModelPredictors) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) 
ss.s.cov %>% select(-Mean,-Min,-Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species for estimates with no covariates (=0), only body mass (=1) or more covariates (=2) in the model in the sperm meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 4.7: Number of effect sizes, studies and mean (range) sample size of species for estimates with no covariates (=0), only body mass (=1) or more covariates (=2) in the model in the sperm meta-analysis
ModelPredictors EffectSizes Studies Sample Size
0 43 31 26.1 ( 2 - 127 )
1 39 24 54.7 ( 4 - 232 )
2 12 11 24.8 ( 10 - 67 )
# model with intercept
mod.stl.cov0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(ModelPredictors), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(ModelPredictors != "NA" & Response == "Sperm total length"))
summary(mod.stl.cov0, digits=3)

# model without intercept
mod.stl.cov <- rma.mv(yi=Z, V=Var_Z,  mods = ~ MP-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(ModelPredictors != "NA" & Response == "Sperm total length"))
summary(mod.stl.cov, digits=3)

# I2
I2.stl.cov <- i2_ml(mod.stl.cov)

# R2
R2.stl.cov <- r2_ml(mod.stl.cov)

# Model Results (includes a prediction interval)
orchard.stl.cov <- orchaRd::mod_results(mod.stl.cov, mod="MP")
pred <- orchard.stl.cov$mod_table # Makes it easier to repeat same plot
# Orchard Plot
orchard_plot(orchard.stl.cov, 
             mod="MP", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b"))
Orchard plot showing the relation (correlation coefficient <i>r</i>) between sperm length and sperm competition, separate for estimates that resulted from analyses without model covariates, with body size as a covariate or from more complex models (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as the response variable.

Figure 4.10: Orchard plot showing the relation (correlation coefficient r) between sperm length and sperm competition, separate for estimates that resulted from analyses without model covariates, with body size as a covariate or from more complex models (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as the response variable.

There is no difference in the estimates that resulted from analyses that have no covariates, body size as covariate or more covariates in the model (Qm=4.282, P=0.118). The estimates are not (all) different from zero. See Summary of moderators: Sperm.



4.2.7 Level of correlation: Sperm

# Sample size
sp <- sp %>%
  mutate(LC=case_when(
    LevelCorrelation == 'Group' ~ 'Species',
    LevelCorrelation == 'Species' ~ 'Species',
    LevelCorrelation == 'Genus' ~ 'Genus'
  ))


ss.s.corr <- sp %>%  filter(Response=="Sperm total length") %>% group_by(LC) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) 
ss.s.corr %>% select(-Mean,-Min,-Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species for estimates calculated at different analysis levels in the sperm meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 4.8: Number of effect sizes, studies and mean (range) sample size of species for estimates calculated at different analysis levels in the sperm meta-analysis
LC EffectSizes Studies Sample Size
Genus 4 2 50.2 ( 26 - 123 )
Species 90 63 37.2 ( 2 - 232 )
# Level of Correlation
mod.stl.corr0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(LC), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response=="Sperm total length"))
summary(mod.stl.corr0, digits=3)

# Level of Correlation no intercept
mod.stl.corr <- rma.mv(yi=Z, V=Var_Z,  mods = ~ LC-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response == "Sperm total length"))
summary(mod.stl.corr, digits=3)

# I2
I2.stl.corr <- i2_ml(mod.stl.corr)

# R2
R2.stl.corr <- r2_ml(mod.stl.corr)

# Model Results (includes a prediction interval)
orchard.stl.corr <- orchaRd::mod_results(mod.stl.corr, mod="LC")
pred <- orchard.stl.corr$mod_table # Makes it easier to repeat same plot
# Orchard Plot
orchard_plot(orchard.stl.corr, 
             mod="LC", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00","#00ff73")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73"))
Orchard plot showing the relation (correlation coefficient <i>r</i>) between sperm length and sperm competition, separate for estimates resulting from correlations on the genus or species level (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as the response variable.

Figure 4.11: Orchard plot showing the relation (correlation coefficient r) between sperm length and sperm competition, separate for estimates resulting from correlations on the genus or species level (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as the response variable.

There is no difference in estimates resulting from analyses on the genus or species level of correlation (Qm=0.062, P=0.803). The estimates are not (all) different from zero. See Summary of moderators: Sperm.



4.2.8 Effect of risk or intensity of sperm competition: Sperm

ss.s.roi <- sp %>% group_by(RiskOrIntensity) %>% filter(Response == "Sperm total length") %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) 
ss.s.roi %>% select(-Mean,-Min,-Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species for sperm competition risk and intensity estimates in the sperm meta-analysis (only sperm total length)") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 4.9: Number of effect sizes, studies and mean (range) sample size of species for sperm competition risk and intensity estimates in the sperm meta-analysis (only sperm total length)
RiskOrIntensity EffectSizes Studies Sample Size
Sperm competition intensity 3 2 19 ( 8 - 27 )
Sperm competition risk 91 63 38.4 ( 2 - 232 )
ss.s.roi.sc <- sp %>% group_by(SpermComp3, RiskOrIntensity) %>% filter(Response == "Sperm total length") %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) 
ss.s.roi.sc %>% select(-Mean, -Min,-Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species for sperm competition risk and intensity estimates in the sperm meta-analysis (only sperm total length), separated by testes size, behavioural and genetic estimates of sperm competition") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 4.10: Number of effect sizes, studies and mean (range) sample size of species for sperm competition risk and intensity estimates in the sperm meta-analysis (only sperm total length), separated by testes size, behavioural and genetic estimates of sperm competition
SpermComp3 RiskOrIntensity EffectSizes Studies Sample Size
Behavioural estimate Sperm competition intensity 1 1 8 ( 8 - 8 )
Sperm competition risk 18 14 29.6 ( 2 - 130 )
Genetic estimate Sperm competition intensity 2 1 24.5 ( 22 - 27 )
Sperm competition risk 6 5 30.7 ( 12 - 55 )
Testes size Sperm competition risk 67 51 41.5 ( 3 - 232 )
# Model with intercept
mod.stl.roi0 <- rma.mv(yi=Z, V=Var_Z, mods=~factor(RiskOrIntensity), random = list( ~1|PrimaryKey, ~1 | EffectSizeKey), slab=Reference, method='REML', data=sp %>% filter(Response == "Sperm total length"))
summary(mod.stl.roi0, digits=3)


# Model without intercept
mod.stl.roi <- rma.mv(yi=Z, V=Var_Z, mods=~RiskOrIntensity -1, random = list( ~1|PrimaryKey, ~1 | EffectSizeKey), slab=Reference, method='REML', data=sp %>% filter(Response == "Sperm total length"))
summary(mod.stl.roi, digits=3)


# Model Results (includes a prediction interval)
orchard.stl.roi <- orchaRd::mod_results(mod.stl.roi, mod="RiskOrIntensity")
pred <- orchard.stl.roi$mod_table # Makes it easier to repeat same plot

# I2
I2.stl.roi <- i2_ml(mod.stl.roi)

# R2
R2.stl.roi <- r2_ml(mod.stl.roi)
# Orchard Plot
orchard_plot(orchard.stl.roi, 
             mod="Int", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3","#ffcc00", "#00ff73")) +
  scale_colour_manual(values=c("#007aa3","#ffcc00", "#00ff73"))
Orchard plot showing the relation (correlation coefficient <i>r</i>) between sperm length and sperm competition, separated for estimates based on sperm competition risk and sperm competition intensity (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as response variable.

Figure 4.12: Orchard plot showing the relation (correlation coefficient r) between sperm length and sperm competition, separated for estimates based on sperm competition risk and sperm competition intensity (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Note that this analysis only includes sperm total length as response variable.

There is no difference in the correlation between sperm total length and sperm competition risk or sperm competition intensity (Qm=0.562, P=0.453). The estimates are not (all) different from zero. See Summary of moderators: Sperm.



4.2.9 Proxies for testes size: Sperm

sp  %>%  filter(SpermCompetition %in% c('Testes area', 'Testes length', 'Testes mass', 'Testes volume') & Response == "Sperm total length") %>% group_by(SpermCompetition) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) %>% select(-Mean,-Min,-Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species for different proxies of testes size for sperm total length only") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 4.11: Number of effect sizes, studies and mean (range) sample size of species for different proxies of testes size for sperm total length only
SpermCompetition EffectSizes Studies Sample Size
Testes area 1 1 20 ( 20 - 20 )
Testes length 6 6 22.5 ( 11 - 55 )
Testes mass 59 43 44.1 ( 3 - 232 )
Testes volume 1 1 20 ( 20 - 20 )
# model with intercept
mod.stl.tsprox0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ SpermCompetition, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(SpermCompetition %in% c('Testes area', 'Testes length', 'Testes mass', 'Testes volume') & Response == "Sperm total length"))
summary(mod.stl.tsprox0, digits=3)

# model without intercept
mod.stl.tsprox <- rma.mv(yi=Z, V=Var_Z,  mods = ~ SpermCompetition-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(SpermCompetition %in% c('Testes area', 'Testes length', 'Testes mass', 'Testes volume') & Response == "Sperm total length"))
summary(mod.stl.tsprox, digits=3)

# I2
I2.stl.tsprox <- i2_ml(mod.stl.tsprox)

# R2
R2.stl.tsprox <- r2_ml(mod.stl.tsprox)

# Model Results (includes a prediction interval)
orchard.stl.tsprox <- orchaRd::mod_results(mod.stl.tsprox, mod="SpermCompetition")
pred <- orchard.stl.tsprox$mod_table # Makes it easier to repeat same plot
# Orchard Plot
orchard_plot(orchard.stl.tsprox, 
             mod="SpermCompetition", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b"))
Orchard plot showing the relation (correlation coefficient <i>r</i>) between sperm length and testes size, separated for different proxies of testes size (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Testes length is different from other proxies of testes size.

Figure 4.13: Orchard plot showing the relation (correlation coefficient r) between sperm length and testes size, separated for different proxies of testes size (meta-analytic mean with 95% confidence interval in black and 95% prediction interval in grey). Testes length is different from other proxies of testes size.

# So we cannot say that sperm length is the same as testes mass. So we can either include it and test if the estimate changes, or exclude it.

There is a difference in the correlation between sperm length and different proxies of testes size (Qm=23.563, P<0.0001). The estimates are not (all) different from zero. Testes length is different from the other estimates.



4.2.10 Effect of different sperm components

sp %>% group_by(Response) %>% summarize(EffectSizes = sum(!is.na(EffectSizeKey)),  Studies = length(unique(PrimaryKey)), Mean = round(mean(SampleSizeSpecies),1), Min = min(SampleSizeSpecies), Max = max(SampleSizeSpecies)) %>% mutate("Sample Size" = paste(Mean," (" ,Min,"-", Max, ")")) %>% select(-Mean,-Min,-Max) %>%
  kable(caption="Number of effect sizes, studies and mean (range) sample size of species for different sperm components included in the sperm meta-analysis") %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1, valign = "top") 
Table 4.12: Number of effect sizes, studies and mean (range) sample size of species for different sperm components included in the sperm meta-analysis
Response EffectSizes Studies Sample Size
Sperm flagellum length 33 26 47.9 ( 2 - 232 )
Sperm head area 1 1 11 ( 11 - 11 )
Sperm head length 29 22 48.4 ( 2 - 232 )
Sperm midpiece length 24 20 48.1 ( 2 - 194 )
Sperm midpiece volume 4 1 31 ( 31 - 31 )
Sperm principal + end piece 1 1 45 ( 45 - 45 )
Sperm total length 94 64 37.8 ( 2 - 232 )
# Head area vs head length
# model with intercept
mod.sp.head0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Response), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response %in% c("Sperm head area", "Sperm head length")))
summary(mod.sp.head0, digits=3)

# model without intercept
mod.sp.head <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Response)-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response %in% c("Sperm head area", "Sperm head length")))
summary(mod.sp.head, digits=3)

# OK, doesn't differ so we can combine them



# Sperm flagellum length vs Sperm principal + end piece
# model with intercept
mod.sp.flagellum0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Response), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response %in% c("Sperm flagellum length", "Sperm principal + end piece")))
summary(mod.sp.flagellum0, digits=3)

# model without intercept
mod.sp.flagellum <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Response)-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response %in% c("Sperm flagellum length", "Sperm principal + end piece")))
summary(mod.sp.flagellum, digits=3)

# OK, doesn't differ so we can combine them



# Sperm midpiece length vs Sperm midpiece volume
# model with intercept
mod.sp.midpiece0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Response), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response %in% c("Sperm midpiece length", "Sperm midpiece volume")))
summary(mod.sp.midpiece0, digits=3)

mod.sp.midpiece <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Response)-1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response %in% c("Sperm midpiece length", "Sperm midpiece volume")))
summary(mod.sp.midpiece, digits=3)

# this differs. Sperm midpiece volume is heaps larger than sperm midpiece length.
  • There is no difference in the estimates (Fisher?s Z) of the different sperm head size estimates (Qm=2.433, P=0.119).

  • There is no difference in the estimates (Fisher?s Z) of the different sperm flagellum size estimates (Qm=0.011, P=0.916).

  • There is a difference in the estimates (Fisher?s Z) of the different sperm midpiece size estimates (Qm=4.805, P=0.028). The estimate for sperm midpiece length = 0.24, with confidence interval [0.06; 0.41], while that for sperm midpiece volume = 0.75 with confidence interval [0.33; 1.17].



4.2.11 Summary of moderators: Sperm

# Other moderators

table_moderators_sperm <- data.frame("name" = c( "Sperm Competition"
                                                 ,"Sperm Competition"
                                           , "Phylogenetic Control" 
                                          , "Phylogenetic Control"
                                          , "Model Covariates"
                                          , "Model Covariates"
                                          , "Model Covariates"
                                          , paste0("Fertilization Mode", 
                                footnote_marker_symbol(1))
                                          , paste0("Fertilization Mode", 
                                footnote_marker_symbol(1))
                                          , "Animal Phylum"
                                          , "Animal Phylum"
                                          , "Level of Correlation"
                                          , "Level of Correlation"),
                               "R2_Marginal" = c(rep(R2.stl.roi[1],2)
                                                 , rep(R2.stl.pc[1],2)
                                                 , rep(R2.stl.cov[1],3)
                                                 , rep(R2.stl.fert[1],2)
                                                 , rep(R2.stl.phylum[1],2)
                                                 , rep(R2.stl.corr[1],2)),
                               "Qm" = c(rep(mod.stl.roi0$QM,2)
                                        , rep(mod.stl.pc0$QM,2)
                                        , rep(mod.stl.cov0$QM,3)
                                        , rep(mod.stl.fert0$QM,2)
                                        , rep(mod.stl.phylum0$QM,2)
                                        , rep(mod.stl.corr0$QM,2)),
                               "P" = c(rep(mod.stl.roi0$QMp,2)
                                       , rep(mod.stl.pc0$QMp,2)
                                       , rep(mod.stl.cov0$QMp,3)
                                       , rep(mod.stl.fert0$QMp,2)
                                       , rep(mod.stl.phylum0$QMp,2)
                                       , rep(mod.stl.corr0$QMp,2)),
                               "k" = c(mod.stl.roi0$k, NA
                                       , mod.stl.pc0$k, NA
                                       , mod.stl.cov0$k, NA, NA
                                       , mod.stl.fert0$k, NA
                                       , mod.stl.phylum0$k, NA
                                       , mod.stl.corr0$k, NA),
                               "k_levels" = c(ss.s.roi$EffectSizes[1]
                                              ,ss.s.roi$EffectSizes[2]
                                              ,ss.s.pc$EffectSizes[1]
                                              ,ss.s.pc$EffectSizes[2]
                                              ,ss.s.cov$EffectSizes[1]
                                              ,ss.s.cov$EffectSizes[2]
                                              ,ss.s.cov$EffectSizes[3]
                                              ,ss.s.fert$EffectSizes[1]
                                              ,ss.s.fert$EffectSizes[2]
                                              ,ss.s.phylum$EffectSizes[1]
                                              ,ss.s.phylum$EffectSizes[2]
                                              ,ss.s.corr$EffectSizes[1]
                                              ,ss.s.corr$EffectSizes[2]),
                               "No_Levels" = c(length(mod.stl.roi$b), NA
                                       , length(mod.stl.pc$b), NA
                                       , length(mod.stl.cov$b), NA, NA
                                       , length(mod.stl.fert0$b), NA
                                       , length(mod.stl.phylum$b), NA
                                       , length(mod.stl.corr$b), NA),
                               "Level_mod" = c(levels(orchard.stl.roi$mod_table$name)[1]
                                               ,levels(orchard.stl.roi$mod_table$name)[2]
                                               ,levels(orchard.stl.pc$mod_table$name)[1]
                                               ,levels(orchard.stl.pc$mod_table$name)[2]
                                               ,levels(orchard.stl.cov$mod_table$name)[1]
                                               ,levels(orchard.stl.cov$mod_table$name)[2]
                                               ,levels(orchard.stl.cov$mod_table$name)[3]
                                               ,levels(orchard.stl.fert$mod_table$name)[1]
                                               ,levels(orchard.stl.fert$mod_table$name)[2]
                                               ,levels(orchard.stl.phylum$mod_table$name)[1]
                                               ,levels(orchard.stl.phylum$mod_table$name)[2]
                                               ,levels(orchard.stl.corr$mod_table$name)[1]
                                               ,levels(orchard.stl.corr$mod_table$name)[2]),
                               "Level_name" = c("Intensity"
                                               ,"Risk"
                                               ,"No"
                                               ,"Yes"
                                               ,"No covariates"
                                               ,"Body mass covariate"
                                               ,"More covariates"
                                               ,levels(orchard.stl.fert$mod_table$name)[1]
                                               ,levels(orchard.stl.fert$mod_table$name)[2]
                                               ,levels(orchard.stl.phylum$mod_table$name)[1]
                                               ,levels(orchard.stl.phylum$mod_table$name)[2]
                                               ,levels(orchard.stl.corr$mod_table$name)[1]
                                               ,levels(orchard.stl.corr$mod_table$name)[2]),
                               "Z" = c(mod.stl.roi$zval[1]
                                       ,mod.stl.roi$zval[2]
                                       , mod.stl.pc$zval[1]
                                       , mod.stl.pc$zval[2]
                                       , mod.stl.cov$zval[1]
                                       , mod.stl.cov$zval[2]
                                       , mod.stl.cov$zval[3]
                                       , mod.stl.fert$zval[1]
                                       , mod.stl.fert$zval[2]
                                       , mod.stl.phylum$zval[1]
                                       , mod.stl.phylum$zval[2]
                                       , mod.stl.corr$zval[1]
                                       , mod.stl.corr$zval[2]),
                               "PZ" = c(mod.stl.roi$pval[1]
                                       ,mod.stl.roi$pval[2]
                                       , mod.stl.pc$pval[1]
                                       , mod.stl.pc$pval[2]
                                       , mod.stl.cov$pval[1]
                                       , mod.stl.cov$pval[2]
                                       , mod.stl.cov$pval[3]
                                       , mod.stl.fert$pval[1]
                                       , mod.stl.fert$pval[2]
                                       , mod.stl.phylum$pval[1]
                                       , mod.stl.phylum$pval[2]
                                       , mod.stl.corr$pval[1]
                                       , mod.stl.corr$pval[2]),
                               "ci.lb" = c(mod.stl.roi$ci.lb[1]
                                       ,mod.stl.roi$ci.lb[2]
                                       , mod.stl.pc$ci.lb[1]
                                       , mod.stl.pc$ci.lb[2]
                                       , mod.stl.cov$ci.lb[1]
                                       , mod.stl.cov$ci.lb[2]
                                       , mod.stl.cov$ci.lb[3]
                                       , mod.stl.fert$ci.lb[1]
                                       , mod.stl.fert$ci.lb[2]
                                       , mod.stl.phylum$ci.lb[1]
                                       , mod.stl.phylum$ci.lb[2]
                                       , mod.stl.corr$ci.lb[1]
                                       , mod.stl.corr$ci.lb[2]),
                               "ci.ub" = c(mod.stl.roi$ci.ub[1]
                                       ,mod.stl.roi$ci.ub[2]
                                       , mod.stl.pc$ci.ub[1]
                                       , mod.stl.pc$ci.ub[2]
                                       , mod.stl.cov$ci.ub[1]
                                       , mod.stl.cov$ci.ub[2]
                                       , mod.stl.cov$ci.ub[3]
                                       , mod.stl.fert$ci.ub[1]
                                       , mod.stl.fert$ci.ub[2]
                                       , mod.stl.phylum$ci.ub[1]
                                       , mod.stl.phylum$ci.ub[2]
                                       , mod.stl.corr$ci.ub[1]
                                       , mod.stl.corr$ci.ub[2]),
                               "beta" = c(mod.stl.roi$beta[1]
                                       ,mod.stl.roi$beta[2]
                                       , mod.stl.pc$beta[1]
                                       , mod.stl.pc$beta[2]
                                       , mod.stl.cov$beta[1]
                                       , mod.stl.cov$beta[2]
                                       , mod.stl.cov$beta[3]
                                       , mod.stl.fert$beta[1]
                                       , mod.stl.fert$beta[2]
                                       , mod.stl.phylum$beta[1]
                                       , mod.stl.phylum$beta[2]
                                       , mod.stl.corr$beta[1]
                                       , mod.stl.corr$beta[2]))

table_mods <- table_moderators_sperm %>% transmute(Moderator = name,
                                             "R2(%)" = round(R2_Marginal * 100,2),
                                             Qm =round(Qm, 2),
                                             "P(Qm)" = cell_spec(ifelse(P < 0.001, "<0.001", round(P,3) ), "html", bold = ifelse(P < 0.05, TRUE,FALSE)),
                                             k = ifelse(is.na(k), "", k),
                                             k_level = k_levels,
                                             Level = Level_name,
                                             beta = round(beta,2),
                                             ci.lb = round(ci.lb,2),
                                             ci.ub = round(ci.ub,2),
                                             "95%CI" = paste("[",ci.lb,";", ci.ub, "]"),
                                             Z = round(Z,2),
                                             "P(Z)" = cell_spec(ifelse(PZ < 0.0001, "<0.0001", ifelse(PZ <0.001, "<0.001", round(PZ,3) )), "html", bold = ifelse(PZ < 0.05, TRUE,FALSE)))

# names(table_mods)
colnames(table_mods)[2] <- "*R^2^ (%)*"
colnames(table_mods)[3] <- "*Q<sub>m</sub>*"
colnames(table_mods)[4] <- "*P(Q<sub>m</sub>)*"
colnames(table_mods)[5] <- "*k<sub>total</sub>*"
colnames(table_mods)[6] <- "*k*"
colnames(table_mods)[8] <- "*&beta;*"
colnames(table_mods)[11] <- "*95% CI*"
colnames(table_mods)[12] <- "*Z*"
colnames(table_mods)[13] <- "*P(Z)*"

table_mods %>% select(-ci.lb, -ci.ub) %>% kable(format="html", escape=F, caption="Summary Table Meta-Regressions Sperm (Only Sperm Total Length)") %>% 
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T) %>%
  collapse_rows(columns = 1:5, valign = "top") %>%
  add_header_above(c(" " = 1, "Moderator Effects" = 4, "Estimates Different From 0?" = 6)) %>%
  footnote("* Excluding studies with both internal and external fertilizers", title_format = "bold")
Table 4.13: Summary Table Meta-Regressions Sperm (Only Sperm Total Length)
Moderator Effects
Estimates Different From 0?
Moderator R2 (%) Qm P(Qm) ktotal k Level ? 95% CI Z P(Z)
Sperm Competition 1.00 0.56 0.453 94 3 Intensity 0.08 [ -0.7; 0.86 ] 0.19 0.846
91 Risk 0.38 [ 0.23; 0.52 ] 5.14 <0.0001
Phylogenetic Control 11.80 9.33 0.002 94 28 No 0.66 [ 0.43; 0.89 ] 5.64 <0.0001
66 Yes 0.26 [ 0.11; 0.41 ] 3.31 <0.001
Model Covariates 6.92 4.28 0.118 94 43 No covariates 0.19 [ -0.12; 0.50 ] 1.20 0.23
39 Body mass covariate 0.27 [ 0.06; 0.48 ] 2.56 0.011
12 More covariates 0.52 [ 0.32; 0.72 ] 5.09 <0.0001
Fertilization Mode* 0.70 0.33 0.566 92 10 External 0.28 [ -0.16; 0.71 ] 1.25 0.21
82 Internal 0.41 [ 0.27; 0.55 ] 5.56 <0.0001
Animal Phylum 10.53 8.69 0.003 94 23 Arthropoda 0.65 [ 0.42; 0.88 ] 5.57 <0.0001
71 Chordata 0.26 [ 0.12; 0.41 ] 3.48 <0.001
Level of Correlation 0.06 0.06 0.803 94 4 Genus 0.43 [ -0.07; 0.94 ] 1.67 0.094
90 Species 0.37 [ 0.23; 0.51 ] 5.06 <0.0001
Note:
* Excluding studies with both internal and external fertilizers

5 Assessing and accounting for publication bias


Publication bias can be present when a disproportionate number of experimental results with strong effects are published. To test for publication biases in our dataset we first visually inspected funnel plots for asymmetries in the distribution of effect sizes. We did this by plotting effect sizes (Zr) against the inverse of their standard error (inverse of sampling variances). We then performed Egger?s regression on residuals of effect sizes from meta-analytic models (Egger, 1997; Nakagawa & Santos, 2012). We calculated the residuals using a Bayesian approach in the MCMCglmm package (v. 2.29; Hadfield, 2010). Residuals were calculated for the meta-analytic model (no-intercept model). When detected, we assessed the impact of publication bias using the trim-and-fill method, which estimates the number of studies that are needed to restore funnel symmetry. We also checked for publication bias over the years to assess time-lag bias (Jennions & M?ller, 2002) by constructing a multi-level meta-regression model with year of publication as a moderator and including the random effects described in the main text.

Testes meta-analysis
Visual inspection of the funnel plot from the testes meta-analysis revealed a publication bias by an asymmetric distribution of effect sizes, suggesting that studies with smaller sample sizes are more likely to be published if they show a positive correlation between testes size and sperm competition level (Funnel plots: Testes). We formally tested for funnel plot asymmetry and found statistical support for publication bias, with the intercept significantly different from zero (Egger?s regression on meta-analytic residuals: intercept=0.93, t=4.65, P<0.0001) (see Egger?s regression: Testes and Identifying publication bias in testes meta-analysis). When Assessing the impact of publication bias in the testes meta-analysis, the trim-and-fill analyses indicated that there were between 18 (R0 estimator) and 27 (L0 estimator) data points missing on the left side of the funnel plot, rejecting the null hypothesis that there were no missing studies on the left (P<0.0001) (Trim & fill analyses: Testes). However, we detect no Time-lag bias in the testes meta-analysis (estimate=-0.001, t=-0.30, P=0.77).

Sperm meta-analysis
Publication bias was not evident in the sperm meta-analysis (see Identifying publication bias in sperm meta-analysis), with no clear asymmetry in the funnel plot (Funnel plots: Sperm). There was no statistical evidence for funnel plot asymmetry (Eggers regression on meta-analytic residuals: intercept=0.22, t=0.78, P=0.43) (see Egger?s regression: Sperm). When Assessing the impact of publication bias in the sperm meta-analysis, the trim-and-fill analysis confirmed there were no (0 missing studies on the right with R0 estimator and 0 missing studies with L0 estimator) studies missing, and the null hypothesis of no missing studies was not rejected (P=0.5) (Trim & fill analyses: Sperm). There was no Time-lag bias in the sperm meta-analysis (F1,184=2.8, P=0.1).

5.1 Testes meta-analysis

5.1.1 Identifying publication bias in testes meta-analysis

5.1.1.1 Funnel plots: Testes

# removing na's
tespub <- tes[complete.cases(tes[ , 'Z']),]

# Raw funnel plot 
mod.tm.funnel <- rma.mv(yi=Z, V=Var_Z,  mods = ~ 1, random = list(~1 | PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tespub)

# Using contour-enhanced funnel plot in the metafor package.
# Note that the funnel is centered not at the model estimate (as is usually done when drawing funnel plots), but at 0 (i.e., at the value under the null hypothesis of no effect). Various levels of statistical significance of the points/studies are indicated by the shaded regions. In particular, the unshaded (i.e., white) region in the middle corresponds to p-values greater than .10, the dark gray-shaded region corresponds to p-values between .10 and .05, the medium gray-shaded region corresponds to p-values between .05 and .01, and the region outside of the funnel corresponds to p-values below .01. Funnel plots drawn in this way are more useful for detecting publication bias due to the suppression of non-significant findings. 
# Reference: metafor documentation.
funnel(mod.tm.funnel, level=c(90, 95, 99), shade=c("white", "gray55", "gray75"), yaxis="seinv", refline=0, legend=TRUE)
Contour-enhanced funnel plot. Note that the mean is at 0, reflecting if the hypothesis would be that there is no relation between testes mass and sperm competition.

Figure 5.1: Contour-enhanced funnel plot. Note that the mean is at 0, reflecting if the hypothesis would be that there is no relation between testes mass and sperm competition.

# For ecological and evolutionary data 1/SE precision on Y works better
# Precision of the estimates (inverse of the standard error, which is the square root of the sampling variance)
Z <- data.frame(x = tespub$Z)
invVarZ <- data.frame(y = 1/sqrt(tespub$Var_Z))
estZ <- as.numeric(mod.tm.funnel$b)

# note 1/y not y  
df <- data.frame(y = seq(0, max(invVarZ), 0.05)) %>% mutate(x1 = estZ + 1.96*(1/y), x2 = estZ - 1.96*(1/y))

ggplot() +
  geom_ribbon(data = df, aes(ymin = min(y), ymax = max(y), x = x1), fill = "#ededed") +
  geom_ribbon(data = df, aes(ymin = y, ymax = 0, x = x1), fill = "white") +  
  geom_ribbon(data = df, aes(ymin = min(y), ymax = max(y), x = x2), fill = "#ededed") +
  geom_ribbon(data = df, aes(ymin = y, ymax = 0, x = x2), fill = "white") +
  geom_line(data = df, aes(x = x1, y = y), lty = 2) +
  geom_line(data = df, aes(x = x2, y = y), lty = 2) +
    geom_segment(data = tespub, aes(x = estZ, xend = estZ,
                   y = max(invVarZ), yend = 0)) +
  geom_point(data = tespub, aes(x = Z, y = 1/sqrt(Var_Z)), shape = 21) +
  xlab("Effect size (Fisher's Z)") +
  ylab("Precision (1/SE)") +
  scale_x_continuous(lim = c(min(Z$x), max(Z$x))) +
  scale_y_continuous(lim = c(0, max(invVarZ$y))) +
  theme(panel.background = element_rect(fill = "white"),
        panel.grid = element_blank(),
        axis.line = element_line(size = 0.8),
        axis.ticks = element_line(size = 0.8),
        axis.text = element_text(size = 12),
        axis.title = element_text(size = 12))
Funnel plot showing the distribution of estimates with regards to precision of the estimates

Figure 5.2: Funnel plot showing the distribution of estimates with regards to precision of the estimates

ggsave("FigureS2B.tiff")

Seems to be asymmetric. There are more points on right in the bigger end of the funnel, meaning that small studies showing a positive correlation between testes mass and sperm competition may be more likely to have been published than those not showing a positive correlation.



5.1.1.2 Egger?s regression: Testes

# Egger's regression 
# To take into account random effects we need to use MCMC 

#Matrix for our data
Vmat_testes <- make_VCV_matrix(data = tespub, V = "Var_Z", cluster = "PrimaryKey", obs = "EffectSizeKey")

is.positive.definite(Vmat_testes)
isSymmetric(Vmat_testes)

# Inverted matrix neeeded to run the model 
invVC<- solve(Vmat_testes)
invVC<- as(invVC, "dgCMatrix")

# Setting MCMC parameters
nitt <- 55000
thin <- 50
burn <- 5000
prior1 = list(R = list(V = 0.002, nu = 1), G=list(G1= list(V=1, nu=1, alpha.mu = 0, alpha.V = 1000), G2=list(V=1, nu=1, alpha.mu = 0, alpha.V = 1000)))

# Model to calculate residuals
mod.MCMC.tes <- MCMCglmm(Z ~ 1, random = ~ PrimaryKey + EffectSizeKey, nitt=nitt, thin=thin, burnin=burn, prior=prior1, pr=TRUE, ginverse = list(EffectSizeKey = invVC), data=tespub)

Prediction <- predict(mod.MCMC.tes, marginal = ~EffectSizeKey)
Precision <- 1 / sqrt(tespub$Var_Z) # Precision = 1/sqrt(V)
MR.testes <- tespub$Z - Prediction # making meta-analytic residulas as in Nakagawa & Santos (2012)
zMR.testes <- MR.testes * Precision 
# Egger's regression on meta-analytic residuals 
Egger.testes <- lm(zMR.testes ~ Precision)
summary(Egger.testes)  
## 
## Call:
## lm(formula = zMR.testes ~ Precision)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2.8243 -0.6613  0.0128  0.5344  3.5560 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  0.92581    0.20063   4.614 1.21e-05 ***
## Precision   -0.12956    0.03438  -3.769 0.000282 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.081 on 97 degrees of freedom
## Multiple R-squared:  0.1277, Adjusted R-squared:  0.1187 
## F-statistic:  14.2 on 1 and 97 DF,  p-value: 0.0002817
## Slightly different way using results from MCMC
model.testes <- mod.MCMC.tes
Pred.testes <- predict(model.testes, marginal=~EffectSizeKey)
ES.testes <- tespub$Z
VES.testes <- tespub$Var_Z
Prec.testes <- 1/sqrt(VES.testes) # Precision = 1/sqrt(V)
es.testes <- ES.testes - Pred.testes # meta-analytic residuals sensu Nakagawa & Santos 2012
zes.testes <- es.testes * Prec.testes
sensitivity_Egger.testes <- MCMCglmm(zes.testes ~ Prec.testes,
                                  family = "gaussian", 
                                  data = data.frame(ES = ES.testes, Prec.testes = Prec.testes), 
                                  verbose=TRUE, 
                                  nitt=55000, 
                                  thin=50, 
                                  burnin=5000)
summary(sensitivity_Egger.testes)
## 
##  Iterations = 5001:54951
##  Thinning interval  = 50
##  Sample size  = 1000 
## 
##  DIC: 300.3009 
## 
##  R-structure:  ~units
## 
##       post.mean l-95% CI u-95% CI eff.samp
## units     1.195   0.8951    1.544     1000
## 
##  Location effects: zes.testes ~ Prec.testes 
## 
##             post.mean l-95% CI u-95% CI eff.samp  pMCMC    
## (Intercept)   0.91294  0.47545  1.27323     1000 <0.001 ***
## Prec.testes  -0.12816 -0.19555 -0.06493     1304  0.002 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Metafor with meta-analytical residuals
metaR.testes <- rma(yi= MR.testes, vi = tespub$Var_Z)
#summary(metaR.testes) #we can use this estmates and CI for our results

# Egger's regression using regtest
regtest(metaR.testes, model="lm")
## 
## Regression Test for Funnel Plot Asymmetry
## 
## model:     weighted regression with multiplicative dispersion
## predictor: standard error
## 
## test for funnel plot asymmetry: t = 4.6144, df = 97, p < .0001

The different Egger?s regressions confirm that there is publication bias. The intercept is significantly different from zero.



5.1.2 Assessing the impact of publication bias in the testes meta-analysis

5.1.2.1 Trim & fill analyses: Testes

There was a strong indication that there is publication bias (see Identifying publication bias in testes meta-analysis), with (small) studies showing a positive relationship between testes mass and sperm competition being more likely to be published. Let?s examine if this would impact our conclusions with trim and fill analyses. To account for heterogeneity we can use the meta-analytic residuals.



# Trim and fill

tesTF.lo <-trimfill(metaR.testes, estimator="L0") # estimator L0
tesTF.lo
## 
## Estimated number of missing studies on the left side: 27 (SE = 6.4524)
## 
## Random-Effects Model (k = 126; tau^2 estimator: REML)
## 
## tau^2 (estimated amount of total heterogeneity): 0.0369 (SE = 0.0108)
## tau (square root of estimated tau^2 value):      0.1920
## I^2 (total heterogeneity / total variability):   50.47%
## H^2 (total variability / sampling variability):  2.02
## 
## Test for Heterogeneity:
## Q(df = 125) = 241.0981, p-val < .0001
## 
## Model Results:
## 
## estimate      se     zval    pval    ci.lb   ci.ub 
##  -0.0387  0.0276  -1.4017  0.1610  -0.0927  0.0154    
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
funnel(tesTF.lo,yaxis="seinv")
Results for a trim-and-fill analysis for testes size in relation to sperm competition using the <i>L</i><sub>0</sub> estimator

Figure 5.3: Results for a trim-and-fill analysis for testes size in relation to sperm competition using the L0 estimator

tesTF.ro <-trimfill(metaR.testes, estimator="R0") # estimator R0
tesTF.ro
## 
## Estimated number of missing studies on the left side: 18 (SE = 6.1644)
## Test of H0: no missing studies on the left side:       p-val < .0001
## 
## Random-Effects Model (k = 117; tau^2 estimator: REML)
## 
## tau^2 (estimated amount of total heterogeneity): 0.0342 (SE = 0.0106)
## tau (square root of estimated tau^2 value):      0.1850
## I^2 (total heterogeneity / total variability):   49.67%
## H^2 (total variability / sampling variability):  1.99
## 
## Test for Heterogeneity:
## Q(df = 116) = 224.3760, p-val < .0001
## 
## Model Results:
## 
## estimate      se     zval    pval    ci.lb   ci.ub 
##  -0.0186  0.0278  -0.6678  0.5043  -0.0731  0.0360    
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
funnel(tesTF.ro,yaxis="seinv") # plot showing missing points
Results for a trim-and-fill analysis for testes size in relation to sperm competition using the <i>R</i><sub>0</sub> estimator

Figure 5.4: Results for a trim-and-fill analysis for testes size in relation to sperm competition using the R0 estimator

There are different estimators of the number of missing studies (L0, R0) that give slightly different results. It is clear that both find quite a number of ?missing? studies (L0=27 missing studies on the left side, R0=18 missing studies on the left side). R0 generally finds fewer missing studies, but even that one finds many missing studies, and rejects the H0 that there are no missing studies (P<0.0001).



5.1.2.2 Robustness of correlation testes size and sperm competition

# Collect the correction values from the trim and fill analyses
# I'm taking the LO because those give the largest effect.
b <- tesTF.lo$b
lb <- tesTF.lo$ci.lb
ub <- tesTF.lo$ci.ub

# Collect the estimates in a table

pubbiastes <- data.frame("name" = c("Overall", "Behavioural estimate", "Genetic estimate"),
                         "estimate" = round(c(mod.tm.overall$b, mod.tm.sc$b[1], mod.tm.sc$b[2]),3),
                         "ci.lb" = round(c(mod.tm.overall$ci.lb, mod.tm.sc$ci.lb[1], mod.tm.sc$ci.lb[2]),3),
                         "ci.ub" = round(c(mod.tm.overall$ci.ub, mod.tm.sc$ci.ub[1], mod.tm.sc$ci.ub[2]),3))

adjustedestimates <- pubbiastes %>% mutate("adjusted_estimate" = round((estimate + b),3),
                                    "adjusted_lb" = round((ci.lb + lb),3),
                                    "adjusted_ub" = round((ci.ub + ub),3),
                                    "stilldifffromzero?" = ifelse(adjusted_lb > 0 & adjusted_ub > 0, "Yes", "No"))


adjustedestimates %>%
  kable() %>%
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T)
name estimate ci.lb ci.ub adjusted_estimate adjusted_lb adjusted_ub stilldifffromzero?
Overall 0.698 0.580 0.816 0.659 0.487 0.831 Yes
Behavioural estimate 0.716 0.581 0.850 0.677 0.488 0.865 Yes
Genetic estimate 0.638 0.388 0.888 0.599 0.295 0.903 Yes

5.1.3 Time-lag bias in the testes meta-analysis

# Check for publication by year using a simple method 
Yearlm.tes <- lm(Z ~ Year, data = tespub)
summary(Yearlm.tes)
anova(Yearlm.tes)

# Publication by year using metafor
# Model with publication year as moderator - with intercept
mod.tm.pb.y <- rma.mv(yi=Z, V=Var_Z,  mods = ~  factor(Year), random = list(~1 | PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tespub)
summary(mod.tm.pb.y, digits=3)
# Plot based on Macartney et al. 2019 - Biol Reviews / with points
ggplot(tespub, aes(x = Year, y = Z, size = 1/(Var_Z))) + 
  geom_point(shape= 21, colour = "#000000", fill = "#8ba7c3") + 
 # scale_x_continuous(breaks = seq(1981, 2019, 5)) + 
#  scale_y_continuous(breaks = seq(-20, 10, 2)) +
  labs(x = "Publication year", y = "Effect size (Fisher's Z)", size = "N=") +
  scale_size_area(max_size = 10) + 
  theme_bw() + 
  theme(legend.position = "bottom", legend.direction = "horizontal") +
  theme(panel.grid.major = element_blank()) + 
  theme(panel.grid.minor = element_blank()) + 
  theme(text =element_text(size = 15)) +
  geom_hline(yintercept=0, lty=2, size = 1) + #adds dotted line at y intercept
  geom_smooth(method = "lm", size = 1, colour = "#000000") 
Plot showing individual study effect sizes scaled by precision, with regard to publication year. There is no clear evidence of time-lag bias in the testes meta-analysis.

Figure 5.5: Plot showing individual study effect sizes scaled by precision, with regard to publication year. There is no clear evidence of time-lag bias in the testes meta-analysis.

There is no evidence of time-lag bias in the testes meta-analysis.



5.2 Sperm meta-analysis

5.2.1 Identifying publication bias in sperm meta-analysis

5.2.1.1 Funnel plots: Sperm

# removing na's
sppub <- sp[complete.cases(sp[ , 'Z']),]

# Raw funnel plot 
mod.sp.funnel <- rma.mv(yi=Z, V=Var_Z,  mods = ~ 1, random = list(~1 | PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sppub)

# Using contour-enhanced funnel plot in the metafor package.
funnel(mod.sp.funnel, level=c(90, 95, 99), shade=c("white", "gray55", "gray75"), yaxis="seinv",refline=0, legend=TRUE)
Contour-enhanced funnel plot. Note that the mean is at 0, reflecting if the hypothesis would be that there is no relation between sperm length and sperm competition.

Figure 5.6: Contour-enhanced funnel plot. Note that the mean is at 0, reflecting if the hypothesis would be that there is no relation between sperm length and sperm competition.

# For ecological and evolutionary data 1/SE precision on Y works better
# Precision of the estimates (inverse of the standard error, which is the square root of the sampling variance)
Z <- data.frame(x = sppub$Z)
invVarZ <- data.frame(y = 1/sqrt(sppub$Var_Z))
estZ <- as.numeric(mod.sp.funnel$b)

# note 1/y not y  
df <- data.frame(y = seq(0, max(invVarZ), 0.05)) %>% mutate(x1 = estZ + 1.96*(1/y), x2 = estZ - 1.96*(1/y))

ggplot() +
  geom_ribbon(data = df, aes(ymin = min(y), ymax = max(y), x = x1), fill = "#ededed") +
  geom_ribbon(data = df, aes(ymin = y, ymax = 0, x = x1), fill = "white") +  
  geom_ribbon(data = df, aes(ymin = min(y), ymax = max(y), x = x2), fill = "#ededed") +
  geom_ribbon(data = df, aes(ymin = y, ymax = 0, x = x2), fill = "white") +
  geom_line(data = df, aes(x = x1, y = y), lty = 2) +
  geom_line(data = df, aes(x = x2, y = y), lty = 2) +
    geom_segment(data = sp, aes(x = estZ, xend = estZ,
                   y = max(invVarZ), yend = 0)) +
  geom_point(data = sppub, aes(x = Z, y = 1/sqrt(Var_Z)), shape = 21) +
  xlab("Effect size (Fisher's Z)") +
  ylab("Precision (1/SE)") +
  scale_x_continuous(lim = c(min(Z$x), max(Z$x))) +
  scale_y_continuous(lim = c(0, max(invVarZ$y))) +
  theme(panel.background = element_rect(fill = "white"),
        panel.grid = element_blank(),
        axis.line = element_line(size = 0.8),
        axis.ticks = element_line(size = 0.8),
        axis.text = element_text(size = 12),
        axis.title = element_text(size = 12))
Funnel plot showing the distribution of estimates with regards to precision of the estimates

Figure 5.7: Funnel plot showing the distribution of estimates with regards to precision of the estimates

ggsave("FigureS5B.tiff")

5.2.1.2 Egger?s regression: Sperm

# Egger's regression 
# To take into account random effects we need to use MCMC 

#Matrix for our data
Vmat_sperm <- make_VCV_matrix(data = sppub, V = "Var_Z", cluster = "PrimaryKey", obs = "EffectSizeKey")

is.positive.definite(Vmat_sperm)
isSymmetric(Vmat_sperm)

# Inverted matrix neeeded to run the model 
invVC<- solve(Vmat_sperm)
invVC<- as(invVC, "dgCMatrix")

# Setting MCMC parameters
nitt<-55000
thin<-50
burn<-5000
prior1=list(R=list(V=0.002, nu=1), G=list(G1= list(V=1, nu=1, alpha.mu = 0, alpha.V = 1000), G2=list(V=1, nu=1, alpha.mu = 0, alpha.V = 1000)))

# Model to calculate residuals
mod.MCMC.sp <- MCMCglmm(Z ~ 1, random = ~ PrimaryKey + EffectSizeKey, nitt=nitt, thin=thin, burnin=burn, prior=prior1, pr=TRUE, ginverse = list(EffectSizeKey = invVC), data=sppub)

Prediction <- predict(mod.MCMC.sp, marginal = ~EffectSizeKey)
Precision <- 1 / sqrt(sppub$Var_Z) # Precision = 1/sqrt(V)
MR.sperm <- sppub$Z - Prediction # making meta-analytic residuals as in Nakagawa & Santos (2012)
zMR.sperm <- MR.sperm * Precision 
# Egger's regression on meta-analytic residuals 
Egger.sperm <- lm(zMR.sperm ~ Precision)
summary(Egger.sperm)  
## 
## Call:
## lm(formula = zMR.sperm ~ Precision)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -7.2505 -0.9408  0.2624  1.1130  8.6815 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)
## (Intercept)  0.21324    0.28961   0.736    0.462
## Precision   -0.05665    0.04692  -1.207    0.229
## 
## Residual standard error: 2.007 on 184 degrees of freedom
## Multiple R-squared:  0.007861,   Adjusted R-squared:  0.002469 
## F-statistic: 1.458 on 1 and 184 DF,  p-value: 0.2288
## Slightly different way using results from MCMC
model.sperm <- mod.MCMC.sp
Pred.sperm <- predict(model.sperm, marginal=~EffectSizeKey)
ES.sperm <- sppub$Z
VES.sperm <- sppub$Var_Z
Prec.sperm <- 1/sqrt(VES.sperm) # Precision = 1/sqrt(V)
es.sperm <- ES.sperm-Pred.sperm # meta-analytic residuals sensu Nakagawa & Santos 2012
zes.sperm <- es.sperm*Prec.sperm
sensitivity_Egger.sperm <- MCMCglmm(zes.sperm ~ Prec.sperm,
                                  family = "gaussian", 
                                  data = data.frame(ES = ES.sperm, Prec.sperm = Prec.sperm), 
                                  verbose=TRUE, 
                                  nitt=55000, 
                                  thin=50, 
                                  burnin=5000)
summary(sensitivity_Egger.sperm)
## 
##  Iterations = 5001:54951
##  Thinning interval  = 50
##  Sample size  = 1000 
## 
##  DIC: 791.0248 
## 
##  R-structure:  ~units
## 
##       post.mean l-95% CI u-95% CI eff.samp
## units     4.071    3.263     4.88     1000
## 
##  Location effects: zes.sperm ~ Prec.sperm 
## 
##             post.mean l-95% CI u-95% CI eff.samp pMCMC
## (Intercept)   0.21612 -0.32412  0.78240   1000.0 0.466
## Prec.sperm   -0.05695 -0.14727  0.03746    667.2 0.224
# Metafor with meta-analytical residuals
metaR.sperm <- rma(yi= MR.sperm, vi = sppub$Var_Z)
# summary(metaR.sperm) #we can use this estmates and CI for our results

# Egger's regression using regtest
regtest(metaR.sperm, model="lm")
## 
## Regression Test for Funnel Plot Asymmetry
## 
## model:     weighted regression with multiplicative dispersion
## predictor: standard error
## 
## test for funnel plot asymmetry: t = 0.7363, df = 184, p = 0.4625

Egger?s regression shows no significant asymmetry. This means there is no evidence of publication bias in the relation between sperm length and sperm competition.

5.2.2 Assessing the impact of publication bias in the sperm meta-analysis

5.2.2.1 Trim & fill analyses: Sperm

The trim-and-fill method is a way to assess the impact of publication bias. Although there was no evidence of publication bias (see Identifying publication bias in sperm meta-analysis), The trim-and-fill method restores funnel asymmetry by imputing missing studies. To account for heterogeneity we can use the meta-analytic residuals.



# Trim and fill

spermTF.lo <-trimfill(metaR.sperm, estimator="L0") # estimator L0
spermTF.lo
## 
## Estimated number of missing studies on the right side: 0 (SE = 7.7491)
## 
## Random-Effects Model (k = 186; tau^2 estimator: REML)
## 
## tau^2 (estimated amount of total heterogeneity): 0.1367 (SE = 0.0196)
## tau (square root of estimated tau^2 value):      0.3698
## I^2 (total heterogeneity / total variability):   83.78%
## H^2 (total variability / sampling variability):  6.17
## 
## Test for Heterogeneity:
## Q(df = 185) = 743.3598, p-val < .0001
## 
## Model Results:
## 
## estimate      se     zval    pval    ci.lb   ci.ub 
##  -0.0093  0.0326  -0.2849  0.7758  -0.0732  0.0546    
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
funnel(spermTF.lo,yaxis="seinv")
Results for a trim-and-fill analysis for sperm length in relation to sperm competition using the <i>L</i><sub>0</sub> estimator

Figure 5.8: Results for a trim-and-fill analysis for sperm length in relation to sperm competition using the L0 estimator

spermTF.ro <-trimfill(metaR.sperm, estimator="R0") # estimator R0
spermTF.ro
## 
## Estimated number of missing studies on the right side: 0 (SE = 1.4142)
## Test of H0: no missing studies on the right side:      p-val = 0.5000
## 
## Random-Effects Model (k = 186; tau^2 estimator: REML)
## 
## tau^2 (estimated amount of total heterogeneity): 0.1367 (SE = 0.0196)
## tau (square root of estimated tau^2 value):      0.3698
## I^2 (total heterogeneity / total variability):   83.78%
## H^2 (total variability / sampling variability):  6.17
## 
## Test for Heterogeneity:
## Q(df = 185) = 743.3598, p-val < .0001
## 
## Model Results:
## 
## estimate      se     zval    pval    ci.lb   ci.ub 
##  -0.0093  0.0326  -0.2849  0.7758  -0.0732  0.0546    
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
funnel(spermTF.ro,yaxis="seinv") # plot showing missing points
Results for a trim-and-fill analysis for sperm length in relation to sperm competition using the <i>R</i><sub>0</sub> estimator

Figure 5.9: Results for a trim-and-fill analysis for sperm length in relation to sperm competition using the R0 estimator

There are different estimators of the number of missing studies (L0, R0) that give slightly different results. As expected given the lack of asymmetry in the funnel plots, there are not so many studies missing (L0=0 missing studies on the right side, R0=0 missing studies on the right side). R0 generally finds less missing studies, and accepts the H0 that there are no missing studies (P=0.5).



5.2.3 Time-lag bias in the sperm meta-analysis

# Check for publication by year using a simple method 
Yearlm.sp <- lm(Z ~ Year, data = sppub)
summary(Yearlm.sp)
anova(Yearlm.sp)

# Publication by year using metafor
# Model with publication year as moderator - with intercept
mod.sp.pb.y <- rma.mv(yi=Z, V=Var_Z,  mods = ~  factor(Year), random = list(~1 | PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sppub)
summary(mod.sp.pb.y, digits=3)
# Plot based on Macartney et al. 2019 - Biol Reviews / with points
ggplot(sppub, aes(x = Year, y = Z, size = 1/(Var_Z))) + 
  geom_point(shape= 21, colour = "#000000", fill = "#a6f6ea") + 
 # scale_x_continuous(breaks = seq(1981, 2019, 5)) + 
#  scale_y_continuous(breaks = seq(-20, 10, 2)) +
  labs(x = "Publication year", y = "Effect size (Fisher's Z)", size = "N=") +
  scale_size_area(max_size = 10) + 
  theme_bw() + 
  theme(legend.position = "bottom", legend.direction = "horizontal") +
  theme(panel.grid.major = element_blank()) + 
  theme(panel.grid.minor = element_blank()) + 
  theme(text =element_text(size = 15)) +
  geom_hline(yintercept=0, lty=2, size = 1) + #adds dotted line at y intercept
  geom_smooth(method = "lm", size = 1, colour = "#000000") 
Plot showing estimates of the relation between sperm length and sperm competition with regards to publication year

Figure 5.10: Plot showing estimates of the relation between sperm length and sperm competition with regards to publication year

There is no time-lag bias in the sperm meta-analysis.


6 Sensitivity analysis


Since both the testes and sperm meta-analyses comprised studies that shared species (primarily among mammals and passerine birds), thereby violating the assumption of non-independence of studies, we conducted two different sensitivity analyses for each meta-analysis. In the first analysis, we used the largest dataset of each major taxon where at least one species occurred in two or more datasets, such as the class Mammalia or the order Passeriformes within the birds, omitting any smaller dataset with any overlapping species. Studies within these taxonomic groups that shared no species with these largest datasets were still included, such as the Metatheria being independent of the Eutheria that formed the largest mammalian dataset. In the second analysis, we repeated this approach at a lower taxonomic level to combine the multiple independent datasets at the order or family level within mammals and passerine birds, respectively, instead of using one overarching dataset each. We chose these two approaches because larger datasets (in first approach) are usually preferred from a meta-analytical standpoint because the effect sizes are more robust, but there are a priori expectations from a biological standpoint that effect sizes vary considerably among different mammalian or avian taxa. This latter point is exemplified for sperm length in Gomendio et al.?s (2011) study on mammals (i.e.?strong effect for rodents, but not for larger-bodied mammals; also see L?pold & Fitzpatrick, 2015) and in Immler & Birkhead?s (2007) study on passerines (i.e.?positive effect for Fringillidae but negative effect for Sylviidae; also see Immler et al., 2011).

6.1 Testes meta-analysis

6.1.1 Behavioural estimates of sperm competition

# model with intercept, all behavioural effect sizes
sens.tm0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes %>% filter(SpermCompetition == "Behavioral estimate"))

summary(sens.tm0, digits=3)

# model with intercept, behavioural effect sizes one study per taxon
sens.taxon.tm0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes %>% filter(SpermCompetition == "Behavioral estimate" & UniqueByTaxonBehav == 1))

summary(sens.taxon.tm0, digits=3)

# model with intercept, behavioural effect sizes unique
sens.unique.tm0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes %>% filter(SpermCompetition == "Behavioral estimate" & UniqueBehav == 1))

summary(sens.unique.tm0, digits=3)
# Model Results (includes a prediction interval)
orchard.tm.sens <- orchaRd::mod_results(sens.tm0, mod="Intcpt")

# Model Results (includes a prediction interval)
orchard.tm.sens.taxon <- orchaRd::mod_results(sens.taxon.tm0, mod="Intcpt")

# Model Results (includes a prediction interval)
orchard.tm.sens.unique <- orchaRd::mod_results(sens.unique.tm0, mod="Intcpt")


# I2
I2.tm.sens <- i2_ml(sens.tm0)

# I2
I2.tm.sens.taxon <- i2_ml(sens.taxon.tm0)

# I2
I2.tm.sens.unique <- i2_ml(sens.unique.tm0)

# R2
R2.tm.sens <- r2_ml(sens.tm0)

# R2
R2.tm.sens.taxon <- r2_ml(sens.taxon.tm0)

# R2
R2.tm.sens.unique <- r2_ml(sens.unique.tm0)
# Orchard Plot with precision
p1 <- orchard_plot(orchard.tm.sens, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3","#ffcc00", "#00ff73")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73")) +
  ggtitle("All data")

# Orchard Plot with precision
p2 <- orchard_plot(orchard.tm.sens.unique, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#00ff73")) +
  scale_colour_manual(values=c("#00ff73"))+
  ggtitle("Subset w/ only largest studies for each animal class")

# Orchard Plot with precision
p3 <- orchard_plot(orchard.tm.sens.taxon, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#ffcc00", "#00ff73")) +
  scale_colour_manual(values=c("#ffcc00","#00ff73")) +
  ggtitle("Subset w/ only largest studies for each animal order")



plot_grid(p1,p2,p3, nrow=3)
Plot showing how the estimates change when subsets of data are taken with only the largest study included on the animal class and animal order level.

Figure 6.1: Plot showing how the estimates change when subsets of data are taken with only the largest study included on the animal class and animal order level.

# Table

sens <- data.frame("Data" = c("All data", "Subset Class", "Subset Order"),
                   "N" = c(sens.tm0$k, sens.unique.tm0$k, sens.taxon.tm0$k),
                   "Beta" = c(sens.tm0$beta, sens.unique.tm0$beta, sens.taxon.tm0$beta),
                   "cilb" = c(sens.tm0$ci.lb, sens.unique.tm0$ci.lb, sens.taxon.tm0$ci.lb),
                   "ciub" = c(sens.tm0$ci.ub, sens.unique.tm0$ci.ub, sens.taxon.tm0$ci.ub),
                   "Z" = c(sens.tm0$zval, sens.unique.tm0$zval, sens.taxon.tm0$zval),
                   "P" = c(sens.tm0$pval, sens.unique.tm0$pval, sens.taxon.tm0$pval))

senstable <- sens %>% transmute(Data = Data,
                                N = N,
                                             beta = round(Beta,2),
                                             ci.lb = round(cilb,2),
                                             ci.ub = round(ciub,2),
                                             "95%CI" = paste("[",ci.lb,";", ci.ub, "]"),
                                             Z = round(Z,2),
                                             "P(Z)" = cell_spec(ifelse(P < 0.001, "<0.001", round(P,3) ), "html", bold = ifelse(P < 0.05, TRUE,FALSE)))

colnames(senstable)[2] <- "*k*"
colnames(senstable)[3] <- "*&beta;*"
colnames(senstable)[6] <- "*95% CI*"
colnames(senstable)[7] <- "*Z*"
colnames(senstable)[8] <- "*P(Z)*"

# add heterogeneity

table_I2 <- data.frame(I2.tm.sens,
                       I2.tm.sens.unique,
                       I2.tm.sens.taxon)

table_I2_perc <- as.data.frame(round(t(table_I2) * 100, 2))
row.names(table_I2_perc) <- NULL

colnames(table_I2_perc)[1] <- "*I^2^<sub>total</sub>*"  
colnames(table_I2_perc)[2] <- "*I^2^<sub>between</sub>*"
colnames(table_I2_perc)[3] <- "*I^2^<sub>within</sub>*"

senstable2 <- cbind(senstable,table_I2_perc)


senstable2 %>% select(-ci.lb, -ci.ub) %>% kable(format="html", escape=F, caption="Summary Table Sensitivity Analysis Behavioural Estimates of Sperm Competition") %>% 
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T)
Table 6.1: Summary Table Sensitivity Analysis Behavioural Estimates of Sperm Competition
Data k ? 95% CI Z P(Z) I2total I2between I2within
All data 66 0.72 [ 0.58; 0.86 ] 10.01 <0.001 87.82 68.82 19.00
Subset Class 18 0.50 [ 0.32; 0.69 ] 5.36 <0.001 84.72 71.54 13.18
Subset Order 26 0.59 [ 0.42; 0.76 ] 6.77 <0.001 79.94 72.83 7.11

6.1.2 Genetic estimates of sperm competition

# model with intercept, all behavioural effect sizes
sens2.tm0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes %>% filter(SpermCompetition == "Genetic estimate"))

summary(sens2.tm0, digits=3)

# model with intercept, genetic effect sizes one study per taxon
sens2.taxon.tm0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes %>% filter(SpermCompetition == "Genetic estimate" & UniqueByTaxonGenetic == 1))

summary(sens2.taxon.tm0, digits=3)

# model with intercept, genetic effect sizes unique
sens2.unique.tm0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=tes %>% filter(SpermCompetition == "Genetic estimate" & UniqueGenetic == 1))

summary(sens2.unique.tm0, digits=3)
# Model Results (includes a prediction interval)
orchard.tm.sens2 <- orchaRd::mod_results(sens2.tm0, mod="Intcpt")

# Model Results (includes a prediction interval)
orchard.tm.sens2.taxon <- orchaRd::mod_results(sens2.taxon.tm0, mod="Intcpt")

# Model Results (includes a prediction interval)
orchard.tm.sens2.unique <- orchaRd::mod_results(sens2.unique.tm0, mod="Intcpt")


# I2
I2.tm.sens2 <- i2_ml(sens2.tm0)

# I2
I2.tm.sens2.taxon <- i2_ml(sens2.taxon.tm0)

# I2
I2.tm.sens2.unique <- i2_ml(sens2.unique.tm0)

# R2
R2.tm.sens2 <- r2_ml(sens2.tm0)

# R2
R2.tm.sens2.taxon <- r2_ml(sens2.taxon.tm0)

# R2
R2.tm.sens2.unique <- r2_ml(sens2.unique.tm0)
# Orchard Plot with precision
p21 <- orchard_plot(orchard.tm.sens2, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3","#ffcc00", "#00ff73")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73")) +
  ggtitle("All data")

# Orchard Plot with precision
p22 <- orchard_plot(orchard.tm.sens2.unique, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#00ff73")) +
  scale_colour_manual(values=c("#00ff73"))+
  ggtitle("Subset w/ only largest studies for each animal class")

# Orchard Plot with precision
p23 <- orchard_plot(orchard.tm.sens2.taxon, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#ffcc00", "#00ff73")) +
  scale_colour_manual(values=c("#ffcc00","#00ff73")) +
  ggtitle("Subset w/ only largest studies for each animal order")



plot_grid(p21,p22,p23, nrow=3)
Plot showing how the estimates for genetic estimates of sperm competition change when subsets of data are taken with only the largest study included on the animal class and animal order level.

Figure 6.2: Plot showing how the estimates for genetic estimates of sperm competition change when subsets of data are taken with only the largest study included on the animal class and animal order level.

# Table

sens2 <- data.frame("Data" = c("All data", "Subset Class", "Subset Order"),
                   "N" = c(sens2.tm0$k, sens2.unique.tm0$k, sens2.taxon.tm0$k),
                   "Beta" = c(sens2.tm0$beta, sens2.unique.tm0$beta, sens2.taxon.tm0$beta),
                   "cilb" = c(sens2.tm0$ci.lb, sens2.unique.tm0$ci.lb, sens2.taxon.tm0$ci.lb),
                   "ciub" = c(sens2.tm0$ci.ub, sens2.unique.tm0$ci.ub, sens2.taxon.tm0$ci.ub),
                   "Z" = c(sens2.tm0$zval, sens2.unique.tm0$zval, sens2.taxon.tm0$zval),
                   "P" = c(sens2.tm0$pval, sens2.unique.tm0$pval, sens2.taxon.tm0$pval))

sens2table <- sens2 %>% transmute(Data = Data,
                                N = N,
                                             beta = round(Beta,2),
                                             ci.lb = round(cilb,2),
                                             ci.ub = round(ciub,2),
                                             "95%CI" = paste("[",ci.lb,";", ci.ub, "]"),
                                             Z = round(Z,2),
                                             "P(Z)" = cell_spec(ifelse(P < 0.001, "<0.001", round(P,3) ), "html", bold = ifelse(P < 0.05, TRUE,FALSE)))

colnames(sens2table)[2] <- "*k*"
colnames(sens2table)[3] <- "*&beta;*"
colnames(sens2table)[6] <- "*95% CI*"
colnames(sens2table)[7] <- "*Z*"
colnames(sens2table)[8] <- "*P(Z)*"

# add heterogeneity

table_I2 <- data.frame(I2.tm.sens2,
                       I2.tm.sens2.unique,
                       I2.tm.sens2.taxon)

table_I2_perc <- as.data.frame(round(t(table_I2) * 100, 2))
row.names(table_I2_perc) <- NULL

colnames(table_I2_perc)[1] <- "*I^2^<sub>total</sub>*"  
colnames(table_I2_perc)[2] <- "*I^2^<sub>between</sub>*"
colnames(table_I2_perc)[3] <- "*I^2^<sub>within</sub>*"

sens2table2 <- cbind(sens2table,table_I2_perc)


sens2table2 %>% select(-ci.lb, -ci.ub) %>% kable(format="html", escape=F, caption="Summary Table Sensitivity Analysis Genetic Estimates of Sperm Competition") %>% 
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T)
Table 6.2: Summary Table Sensitivity Analysis Genetic Estimates of Sperm Competition
Data k ? 95% CI Z P(Z) I2total I2between I2within
All data 33 0.61 [ 0.42; 0.8 ] 6.28 <0.001 60.92 60.92 0.00
Subset Class 3 0.70 [ 0.49; 0.91 ] 6.49 <0.001 33.19 16.59 16.59
Subset Order 6 0.84 [ 0.49; 1.2 ] 4.61 <0.001 47.45 47.45 0.00

6.2 Sperm meta-analysis

6.2.1 With sperm midpiece volume and testes length excluded from the dataset

mod.sl.overall.sens0 <- rma.mv(yi=Z, V=Var_Z,  mods = ~ factor(Response2), random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response2 != 'Sperm midpiece volume' & SpermComp2 != "Testes length"))
summary(mod.sl.overall.sens0, digits=3)
## 
## Multivariate Meta-Analysis Model (k = 173; method: REML)
## 
##   logLik  Deviance       AIC       BIC      AICc 
## -116.132   232.265   244.265   263.044   244.784   
## 
## Variance Components:
## 
##            estim   sqrt  nlvls  fixed         factor 
## sigma^2.1  0.112  0.334     68     no     PrimaryKey 
## sigma^2.2  0.035  0.188    173     no  EffectSizeKey 
## 
## Test for Residual Heterogeneity:
## QE(df = 169) = 662.898, p-val < .001
## 
## Test of Moderators (coefficients 2:4):
## QM(df = 3) = 6.903, p-val = 0.075
## 
## Model Results:
## 
##                                         estimate     se    zval   pval   ci.lb 
## intrcpt                                    0.358  0.072   4.951  <.001   0.216 
## factor(Response2)Sperm head length        -0.181  0.072  -2.519  0.012  -0.322 
## factor(Response2)Sperm midpiece length    -0.112  0.077  -1.448  0.148  -0.264 
## factor(Response2)Sperm total length       -0.057  0.069  -0.820  0.412  -0.193 
##                                          ci.ub 
## intrcpt                                  0.500  *** 
## factor(Response2)Sperm head length      -0.040    * 
## factor(Response2)Sperm midpiece length   0.040      
## factor(Response2)Sperm total length      0.079      
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
mod.sl.overall.sens <- rma.mv(yi=Z, V=Var_Z,  mods = ~ Response2 -1, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(Response2 != 'Sperm midpiece volume' & SpermComp2 != "Testes length"))
summary(mod.sl.overall.sens, digits=3)
## 
## Multivariate Meta-Analysis Model (k = 173; method: REML)
## 
##   logLik  Deviance       AIC       BIC      AICc 
## -116.132   232.265   244.265   263.044   244.784   
## 
## Variance Components:
## 
##            estim   sqrt  nlvls  fixed         factor 
## sigma^2.1  0.112  0.334     68     no     PrimaryKey 
## sigma^2.2  0.035  0.188    173     no  EffectSizeKey 
## 
## Test for Residual Heterogeneity:
## QE(df = 169) = 662.898, p-val < .001
## 
## Test of Moderators (coefficients 1:4):
## QM(df = 4) = 39.813, p-val < .001
## 
## Model Results:
## 
##                                  estimate     se   zval   pval  ci.lb  ci.ub 
## Response2Sperm flagellum length     0.358  0.072  4.951  <.001  0.216  0.500 
## Response2Sperm head length          0.177  0.076  2.335  0.020  0.028  0.325 
## Response2Sperm midpiece length      0.246  0.080  3.062  0.002  0.089  0.403 
## Response2Sperm total length         0.301  0.055  5.448  <.001  0.193  0.410 
##  
## Response2Sperm flagellum length  *** 
## Response2Sperm head length         * 
## Response2Sperm midpiece length    ** 
## Response2Sperm total length      *** 
## 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Model Results (includes a prediction interval)
orchard.sl.overall.sens <- orchaRd::mod_results(mod.sl.overall.sens, mod="Response2")
pred <- orchard.sl.overall.sens$mod_table # Makes it easier to repeat same plot

# I2
I2.sl.overall.sens <- i2_ml(mod.sl.overall.sens)

# R2
R2.sl.overall.sens <- r2_ml(mod.sl.overall.sens)
# Orchard Plot
orchard_plot(orchard.sl.overall.sens, 
             mod="Response2", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSize,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73","#7a469b"))
Orchard plot showing the correlation between sperm length and sperm competition, excluding influential data points

Figure 6.3: Orchard plot showing the correlation between sperm length and sperm competition, excluding influential data points

6.2.2 Testes mass as sperm competition variable

# Model with intercept
sens.sp0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(SpermComp2 == "Testes size" & Response == "Sperm total length"))
summary(sens.sp0, digits=3)

# Model with intercept, class
sens.taxon.sp0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(SpermComp2 == "Testes size" & Response == "Sperm total length" & UniqueTMByTaxon == 1))
summary(sens.taxon.sp0, digits=3)

# Model with intercept, order
sens.unique.sp0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(SpermComp2 == "Testes size" & Response == "Sperm total length" & UniqueTMLargest == 1))
summary(sens.unique.sp0, digits=3)
# Model Results (includes a prediction interval)
orchard.sp.sens <- orchaRd::mod_results(sens.sp0, mod="Intcpt")

# Model Results (includes a prediction interval)
orchard.sp.sens.taxon <- orchaRd::mod_results(sens.taxon.sp0, mod="Intcpt")

# Model Results (includes a prediction interval)
orchard.sp.sens.unique <- orchaRd::mod_results(sens.unique.sp0, mod="Intcpt")


# I2
I2.sp.sens <- i2_ml(sens.sp0)

# I2
I2.sp.sens.taxon <- i2_ml(sens.taxon.sp0)

# I2
I2.sp.sens.unique <- i2_ml(sens.unique.sp0)

# R2
R2.sp.sens <- r2_ml(sens.sp0)

# R2
R2.sp.sens.taxon <- r2_ml(sens.taxon.sp0)

# R2
R2.sp.sens.unique <- r2_ml(sens.unique.sp0)
# Orchard Plot with precision
t1 <- orchard_plot(orchard.sp.sens, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3","#ffcc00", "#00ff73")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73")) +
  ggtitle("All data")

# Orchard Plot with precision
t2 <- orchard_plot(orchard.sp.sens.unique, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#00ff73")) +
  scale_colour_manual(values=c("#00ff73"))+
  ggtitle("Subset with only largest studies for each animal class")

# Orchard Plot with precision
t3 <- orchard_plot(orchard.sp.sens.taxon, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#ffcc00", "#00ff73")) +
  scale_colour_manual(values=c("#ffcc00","#00ff73")) +
  ggtitle("Subset with only largest studies for each animal order")



plot_grid(t1,t2,t3, nrow=3)
Plot showing how the estimates for total sperm length in relation to testes mass change when subsets of data are taken with only the largest study included on the animal class and animal order level.

Figure 6.4: Plot showing how the estimates for total sperm length in relation to testes mass change when subsets of data are taken with only the largest study included on the animal class and animal order level.

# Table

senssp <- data.frame("Data" = c("All data", "Subset Class", "Subset Order"),
                   "N" = c(sens.sp0$k, sens.unique.sp0$k, sens.taxon.sp0$k),
                   "Beta" = c(sens.sp0$beta, sens.unique.sp0$beta, sens.taxon.sp0$beta),
                   "cilb" = c(sens.sp0$ci.lb, sens.unique.sp0$ci.lb, sens.taxon.sp0$ci.lb),
                   "ciub" = c(sens.sp0$ci.ub, sens.unique.sp0$ci.ub, sens.taxon.sp0$ci.ub),
                   "Z" = c(sens.sp0$zval, sens.unique.sp0$zval, sens.taxon.sp0$zval),
                   "P" = c(sens.sp0$pval, sens.unique.sp0$pval, sens.taxon.sp0$pval))

senstablesp <- senssp %>% transmute(Data = Data,
                                N = N,
                                             beta = round(Beta,2),
                                             ci.lb = round(cilb,2),
                                             ci.ub = round(ciub,2),
                                             "95%CI" = paste("[",ci.lb,";", ci.ub, "]"),
                                             Z = round(Z,2),
                                             "P(Z)" = cell_spec(ifelse(P < 0.001, "<0.001", round(P,3) ), "html", bold = ifelse(P < 0.05, TRUE,FALSE)))

colnames(senstablesp)[2] <- "*k*"
colnames(senstablesp)[3] <- "*&beta;*"
colnames(senstablesp)[6] <- "*95% CI*"
colnames(senstablesp)[7] <- "*Z*"
colnames(senstablesp)[8] <- "*P(Z)*"

# add heterogeneity

table_I2 <- data.frame(I2.sp.sens,
                       I2.sp.sens.unique,
                       I2.sp.sens.taxon)

table_I2_perc <- as.data.frame(round(t(table_I2) * 100, 2))
row.names(table_I2_perc) <- NULL

colnames(table_I2_perc)[1] <- "*I^2^<sub>total</sub>*"  
colnames(table_I2_perc)[2] <- "*I^2^<sub>between</sub>*"
colnames(table_I2_perc)[3] <- "*I^2^<sub>within</sub>*"

senstable2sp <- cbind(senstablesp,table_I2_perc)


senstable2sp %>% select(-ci.lb, -ci.ub) %>% kable(format="html", escape=F, caption="Summary Table Sensitivity Analysis Sperm Total Length ~ Testes Mass") %>% 
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T)
Table 6.3: Summary Table Sensitivity Analysis Sperm Total Length ~ Testes Mass
Data k ? 95% CI Z P(Z) I2total I2between I2within
All data 61 0.25 [ 0.14; 0.35 ] 4.69 <0.001 75.88 43.56 32.32
Subset Class 16 0.29 [ 0.14; 0.45 ] 3.70 <0.001 72.95 0.00 72.95
Subset Order 27 0.22 [ 0.04; 0.40 ] 2.41 0.016 77.32 0.00 77.32

6.2.3 Genetic estimates of sperm competition

# Model with intercept
sens2.sp0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(SpermComp2 == "Genetic estimate" & Response == "Sperm total length"))
summary(sens2.sp0, digits=3)

# Model with intercept, class
sens2.unique.sp0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(SpermComp2 == "Genetic estimate" & Response == "Sperm total length" & UniqueGenetic == 1))
summary(sens2.unique.sp0, digits=3)
# Model Results (includes a prediction interval)
orchard.sp.sens2 <- orchaRd::mod_results(sens2.sp0, mod="Intcpt")

# Model Results (includes a prediction interval)
orchard.sp.sens2.unique <- orchaRd::mod_results(sens2.unique.sp0, mod="Intcpt")


# I2
I2.sp.sens2 <- i2_ml(sens2.sp0)

# I2
I2.sp.sens2.unique <- i2_ml(sens2.unique.sp0)

# R2
R2.sp.sens2 <- r2_ml(sens2.sp0)

# R2
R2.sp.sens2.unique <- r2_ml(sens2.unique.sp0)
# Orchard Plot with precision
t21 <- orchard_plot(orchard.sp.sens2, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3","#ffcc00", "#00ff73")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73")) +
  ggtitle("All data")

# Orchard Plot with precision
t22 <- orchard_plot(orchard.sp.sens2.unique, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#00ff73")) +
  scale_colour_manual(values=c("#00ff73"))+
  ggtitle("Subset with only largest studies for each animal class")


plot_grid(t21,t22, nrow=2)
Plot showing how the estimates for total sperm length in relation to genetic estimates change when subsets of data are taken with only the largest study included on the animal class level.

Figure 6.5: Plot showing how the estimates for total sperm length in relation to genetic estimates change when subsets of data are taken with only the largest study included on the animal class level.

# Table

senssp2 <- data.frame("Data" = c("All data", "Subset Class"),
                   "N" = c(sens2.sp0$k, sens2.unique.sp0$k),
                   "Beta" = c(sens2.sp0$beta, sens2.unique.sp0$beta),
                   "cilb" = c(sens2.sp0$ci.lb, sens2.unique.sp0$ci.lb),
                   "ciub" = c(sens2.sp0$ci.ub, sens2.unique.sp0$ci.ub),
                   "Z" = c(sens2.sp0$zval, sens2.unique.sp0$zval),
                   "P" = c(sens2.sp0$pval, sens2.unique.sp0$pval))

sens2tablesp <- senssp2 %>% transmute(Data = Data,
                                N = N,
                                             beta = round(Beta,2),
                                             ci.lb = round(cilb,2),
                                             ci.ub = round(ciub,2),
                                             "95%CI" = paste("[",ci.lb,";", ci.ub, "]"),
                                             Z = round(Z,2),
                                             "P(Z)" = cell_spec(ifelse(P < 0.001, "<0.001", round(P,3) ), "html", bold = ifelse(P < 0.05, TRUE,FALSE)))

colnames(sens2tablesp)[2] <- "*k*"
colnames(sens2tablesp)[3] <- "*&beta;*"
colnames(sens2tablesp)[6] <- "*95% CI*"
colnames(sens2tablesp)[7] <- "*Z*"
colnames(sens2tablesp)[8] <- "*P(Z)*"

# add heterogeneity

table_I2 <- data.frame(I2.sp.sens2,
                       I2.sp.sens2.unique)

table_I2_perc <- as.data.frame(round(t(table_I2) * 100, 2))
row.names(table_I2_perc) <- NULL

colnames(table_I2_perc)[1] <- "*I^2^<sub>total</sub>*"  
colnames(table_I2_perc)[2] <- "*I^2^<sub>between</sub>*"
colnames(table_I2_perc)[3] <- "*I^2^<sub>within</sub>*"

sens2table2sp <- cbind(sens2tablesp,table_I2_perc)


sens2table2sp %>% select(-ci.lb, -ci.ub) %>% kable(format="html", escape=F, caption="Summary Table Sensitivity Analysis Sperm Total Length ~ Genetic estimates") %>% 
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T)
Table 6.4: Summary Table Sensitivity Analysis Sperm Total Length ~ Genetic estimates
Data k ? 95% CI Z P(Z) I2total I2between I2within
All data 8 0.42 [ 0.27; 0.56 ] 5.67 <0.001 10.01 0 10.01
Subset Class 6 0.42 [ 0.21; 0.63 ] 3.96 <0.001 35.56 0 35.56

6.2.4 Behavioural estimates of sperm competition

# Model with intercept
sens3.sp0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(SpermComp2 == "Behavioural estimate" & Response == "Sperm total length"))
summary(sens3.sp0, digits=3)

# Model with intercept, class
sens3.unique.sp0 <- rma.mv(yi=Z, V=Var_Z, random = list( ~1 |PrimaryKey, ~1 | EffectSizeKey), method='REML', data=sp %>% filter(SpermComp2 == "Behavioural estimate" & Response == "Sperm total length" & UniqueBehav == 1))
summary(sens3.unique.sp0, digits=3)
# Model Results (includes a prediction interval)
orchard.sp.sens3 <- orchaRd::mod_results(sens3.sp0, mod="Intcpt")

# Model Results (includes a prediction interval)
orchard.sp.sens3.unique <- orchaRd::mod_results(sens3.unique.sp0, mod="Intcpt")


# I2
I2.sp.sens3 <- i2_ml(sens3.sp0)

# I2
I2.sp.sens3.unique <- i2_ml(sens3.unique.sp0)

# R2
R2.sp.sens3 <- r2_ml(sens3.sp0)

# R2
R2.sp.sens3.unique <- r2_ml(sens3.unique.sp0)
# Orchard Plot with precision
t31 <- orchard_plot(orchard.sp.sens3, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#007aa3","#ffcc00", "#00ff73")) +
  scale_colour_manual(values=c("#007aa3", "#ffcc00","#00ff73")) +
  ggtitle("All data")

# Orchard Plot with precision
t32 <- orchard_plot(orchard.sp.sens3.unique, 
             mod="Intcpt", 
             xlab = "Correlation Coefficient (r)", 
             # N=tes$SampleSizeSpecies,
             angle=45,  
             transfm='tanh') + 
  scale_fill_manual(values=c("#00ff73")) +
  scale_colour_manual(values=c("#00ff73"))+
  ggtitle("Subset with only largest studies for each animal class")


plot_grid(t31,t32, nrow=2)
Plot showing how the estimates for total sperm length in relation to genetic estimates change when subsets of data are taken with only the largest study included on the animal class level.

Figure 6.6: Plot showing how the estimates for total sperm length in relation to genetic estimates change when subsets of data are taken with only the largest study included on the animal class level.

# Table

senssp3 <- data.frame("Data" = c("All data", "Subset Class"),
                   "N" = c(sens3.sp0$k, sens3.unique.sp0$k),
                   "Beta" = c(sens3.sp0$beta, sens3.unique.sp0$beta),
                   "cilb" = c(sens3.sp0$ci.lb, sens3.unique.sp0$ci.lb),
                   "ciub" = c(sens3.sp0$ci.ub, sens3.unique.sp0$ci.ub),
                   "Z" = c(sens3.sp0$zval, sens3.unique.sp0$zval),
                   "P" = c(sens3.sp0$pval, sens3.unique.sp0$pval))

sens3tablesp <- senssp3 %>% transmute(Data = Data,
                                N = N,
                                             beta = round(Beta,2),
                                             ci.lb = round(cilb,2),
                                             ci.ub = round(ciub,2),
                                             "95%CI" = paste("[",ci.lb,";", ci.ub, "]"),
                                             Z = round(Z,2),
                                             "P(Z)" = cell_spec(ifelse(P < 0.001, "<0.001", round(P,3) ), "html", bold = ifelse(P < 0.05, TRUE,FALSE)))

colnames(sens3tablesp)[2] <- "*k*"
colnames(sens3tablesp)[3] <- "*&beta;*"
colnames(sens3tablesp)[6] <- "*95% CI*"
colnames(sens3tablesp)[7] <- "*Z*"
colnames(sens3tablesp)[8] <- "*P(Z)*"

# add heterogeneity

table_I2 <- data.frame(I2.sp.sens3,
                       I2.sp.sens3.unique)

table_I2_perc <- as.data.frame(round(t(table_I2) * 100, 2))
row.names(table_I2_perc) <- NULL

colnames(table_I2_perc)[1] <- "*I^2^<sub>total</sub>*"  
colnames(table_I2_perc)[2] <- "*I^2^<sub>between</sub>*"
colnames(table_I2_perc)[3] <- "*I^2^<sub>within</sub>*"

sens3table2sp <- cbind(sens3tablesp,table_I2_perc)


sens3table2sp %>% select(-ci.lb, -ci.ub) %>% kable(format="html", escape=F, caption="Summary Table Sensitivity Analysis Sperm Total Length ~ Behavioural estimates") %>% 
  kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T)
Table 6.5: Summary Table Sensitivity Analysis Sperm Total Length ~ Behavioural estimates
Data k ? 95% CI Z P(Z) I2total I2between I2within
All data 19 0.33 [ -0.03; 0.7 ] 1.77 0.076 90.91 90.91 0.00
Subset Class 10 0.38 [ -0.22; 0.98 ] 1.26 0.209 93.92 46.96 46.96

7 Heterogeneity


table_I2 <- data.frame(I2.tm.overall,
                       I2.sp.all)

table_I2_perc <- round(table_I2 * 100, 2)
colnames(table_I2_perc) <- c("Testes Overall", "Sperm Overall")
rownames(table_I2_perc)[1] <- "*I^2^<sub>total</sub>*"  
rownames(table_I2_perc)[2] <- "*I^2^<sub>between</sub>*"
rownames(table_I2_perc)[3] <- "*I^2^<sub>within</sub>*"
  
t(table_I2_perc) %>% kable(booktabs=TRUE, caption="Heterogeneity of Main Models") %>% kable_styling(c("hover", "condensed"), full_width = F) %>%
  column_spec(1, bold = T)
Table 7.1: Heterogeneity of Main Models
I2total I2between I2within
Testes Overall 84.00 79.24 4.76
Sperm Overall 90.47 76.79 13.68

8 References


Egger M, Smith GD, Schneider M & Minder C (1997) Bias in meta-analysis detected by a simple, graphical test. BMJ 315: 629.

Gomendio M, Tourmente M & Roldan ERS (2011) Why mammalian lineages respond differently to sexual selection: metabolic rate constrains the evolution of sperm size. Proceedings of the Royal Society B 278: 3135?3141.

Hadfield JD (2010) MCMC Methods for Multi-Response Generalized Linear Mixed Models: The MCMCglmm R Package. Journal of Statistical Software 33: 1-22. URL http://www.jstatsoft.org/v33/i02/.

Immler S & Birkhead TR (2007) Sperm competition and sperm midpiece size: no consistent pattern in passerine birds. Proceedings of the Royal Society of London B 274: 561?568.

Immler S, Pitnick S, Parker GA, Durrant KL, L?pold S, Calhim S & Birkhead TR (2011) Resolving variation in the reproductive tradeoff between sperm size and number. Proceedings of the National Academy of Sciences of the United States of America 108: 5325?5330.

Jennions MD & M?ller AP (2002) Relationships fade with time: a meta-analysis of temporal trends in publication in ecology and evolution. Proceedings of the Royal Society of London B 269: 43?48.

Lajeunesse MJ (2013) Recovering Missing or Partial Data from Studies: A survey of conversions and imputations for meta-analysis, in Koricheva J, Gurevitch J & Mengersen K (ed) The Handbook of Meta-Analysis in Ecology and Evolution.

L?pold S & Fitzpatrick JL (2015) Sperm number trumps sperm size in mammalian ejaculate evolution. Proceedings of the Royal Society of London B 282: 20152122.

Moher D, Liberati A, Tetzlaff J & Altman DG (2009) Preferred reporting items for systematic reviews and meta-analyses: the PRISMA statement. Annals of Internal Medicine 151: 264-269.

Nakagawa S, Lagisz M, O'Dea RE, Rutkowska J, Yang Y, Noble DWA & Senior AM (2020) The orchard plot: Cultivating a forest plot for use in ecology, evolution, and beyond. Research Synthesis Methods, DOI: https://doi.org/10.1002/jrsm.1424.

Nakagawa S & Santos ESA (2012) Methodological issues and advances in biological meta-analysis. Evolutionary Ecology 26: 1253-1274.

Ouzzani M, Hammady H, Fedorowicz Z & Elmagarmid, A (2016) Rayyan: a web and mobile app for systematic reviews. Systematic Reviews 5: 210.

Pick JL, Nakagawa S & Noble DWA (2019) Reproducible, flexible and high?throughput data extraction from primary literature: The metaDigitise R package. Methods in Ecology and Evolution 10: 426-431.

Re ACD (2013) compute.es: Compute effect sizes. https://cran.r-project.org/package=compute.es.

Rosenberg MS, Rothstein HR & Gurevitch J (2013) Effect sizes: conventional choices and calculations, In Koricheva J, Gurevitch J & Mengersen K (ed) The Handbook of Meta-Analysis in Ecology and Evolution.