Nuisance heterogeneity

Introduction

In the previous tutorial we over-viewed a few of the common effect size statistics likely to be used in comparative physiology. However, studies can vary in ways that can make the interpretation of these statistics challenging.

Nuisance heterogeneity – known methodological or design-level variables that drive effect size magnitude but are not themselves the biological question of interest, such as the dose, exposure duration, or temperature difference applied across treatments – are common in comparative physiology meta-analyses (Borenstein, 2019; Noble et al., 2022). Nuisance heterogeneity can be a big driver of effect size magnitude. For example, a contrast-based effect size, such as log response ratio, calculated from a study that has manipulated treatments to have a 10\(^{\circ}\)C temperature difference between treatments is likely going to give you a much larger effect size than a study that manipulated a treatment temperature difference of 2\(^{\circ}\)C. Amalgamating such effects within a meta-analysis will make the interpretation of effect magnitude complicated because it’s difficult to know what magnitude of, say temperature, our effect size should be interpreted over.

There are two main ways to deal with nuisance heterogeneity. The most common approach is to include a moderator in a meta-regression model that controls for, e.g., the temperature difference between treatments (Noble et al., 2022). You can re-scale this continuous moderator (centre the variable on the mean so ‘0’ equates to the average difference) so that intercepts can be interpreted more easily (Noble et al., 2022). Alternatively, we can ‘correct’ our effect sizes to account for the nuisance variable before fitting any model. The two approaches differ in what they assume: a meta-regression moderator estimates the functional form of the nuisance relationship from the data, while effect-size correction assumes a particular functional form (e.g., the exponential temperature scaling implied by \(Q_{10}\)) and bakes it into every effect size at the outset. When the functional form is well-established from theory or physiology, effect-size correction is usually cleaner because it simplifies modelling and gives every effect size a common interpretation up front. In this tutorial, we’ll overview the effect-size correction approach.

Effect Sizes Corrected for Nuisance Heterogeneity

Temperature Coefficient, \(Q_{10}\)

One common and well known effect size that is used in comparative physiology is the temperature coefficient, \(Q_{10}\). As discussed, effect sizes need to be: 1) comparable across studies and 2) we need to know, or be able to approximate, the sampling variance in order to make use of meta-analytic models. While \(Q_{10}\) satisfies 1), we do not know what the sampling variance should be for this effect size. Noble et al. (2022) fixes that issue by deriving its sampling variance.

To begin, recall that \(Q_{10}\) is defined as:

\[ Q_{10} = \left( \frac{R_{2}}{R_{1}} \right)^{ \left(\ \frac{10^{\circ}C}{T_{2}-T_{1}} \right) } \tag{4.1}\]

Here, \(R_{1}\) and \(R_{2}\) are mean physiological rates and \(T_{1}\) and \(T_{2}\) are the temperatures at which these rates are measured. Natural log transformation of Equation 4.1 leads to the following log transformed \(Q_{10}\):

\[ lnRR_{Q_{10}} = ln\left( \frac{R_{2}}{R_{1}} \right){ \left(\ \frac{10^{\circ}C}{T_{2}-T_{1}} \right) } \tag{4.2}\]

Noble et al. (2022) call this transformed effect size \(LnRR_{Q_{10}}\) because of its similarities with the log response ratio. Equation 4.2 is essentially a temperature-corrected equivalent of lnRR when the numerator and denominator are measured at different temperatures. \(lnRR_{Q_{10}}\) is more likely to satisfy the assumption of residual normality than \(Q_{10}\) and given its similarities to lnRR we can now approximate its sampling variance (see Hedges et al., 1999). The recognition of this equivalence means that we can calculate the sampling variance for Equation 4.2 as follows:

\[ s^2_{lnRR_{Q_{10}}} = \left( \frac{SD_{2}^2}{R^2_{2}N_{2}} + \frac{SD_{1}^2}{R^2_{1}N_{1}} \right){ \left(\ \frac{10^{\circ}C}{T_{2}-T_{1}} \right) }^2 \tag{4.3}\]

\(lnRR_{Q_{10}}\): Diving vertebrates and climate change

We will demonstrate how to apply \(lnRR_{Q_{10}}\) to a data set on diving vertebrates by Rodgers et al. (2021). Rodgers et al. (2021) already analysed \(Q_{10}\), but at the time they did not have \(lnRR_{Q_{10}}\), meaning it was not possible to analyse these data using meta-analytic models – they resorted to meta-regression approaches with standard effect sizes, which are an equally valid alternative. Here, we will show you how to calculate \(lnRR_{Q_{10}}\) and interpret it.

Download Data and Functions for \(lnRR_{Q_{10}}\)

We’ll download the data set used to analyse \(Q_{10}\) and load a bunch of packages that are necessary.

Code
# Note: This downloads data from GitHub raw content
q10_dat <- read.csv("https://raw.githubusercontent.com/essierodgers/diving-meta-analysis/master/data/contrast_lab_dataset.csv") 

#install.packages("pacman")
pacman::p_load(devtools, pander, tidyverse, metafor)

We’ll now need a function for calculating \(lnRR_{Q_{10}}\) because this effect size is not part of the metafor package.

Code
#' @title lnRR_Q10
#' @description Calculates the log Q10 response ratio.  Note that temperature 2 is placed in the numerator and temperature 1 is in the denominator
#' @param t1  Lowest of the two treatment temperatures
#' @param t2  Highest of the two treatment temperatures
#' @param r1  Mean physiological rate for temperature 1
#' @param r2  Mean physiological rate for temperature 2
#' @param sd1 Standard deviation for physiological rates at temperature 1
#' @param sd2 Standard deviation for physiological rates at temperature 2
#' @param n1  Sample size at temperature 1
#' @param n2  Sample size at temperature 2
#' @param name Character string for column name
#' @example
#' lnRR_Q10(20, 30, 10, 5, 1, 1, 30, 30)
#' lnRR_Q10(20, 30, 10, 5, 1, 1, 30, 30, name = "acclim")
#' @export

lnRR_Q10 <- function(t1, t2, r1, r2, sd1, sd2, n1, n2, name ="acute"){
        
    lnRR_Q10 <- (10 / (t2 - t1))   * log(r2 / r1)
  V_lnRR_Q10 <- (10 / (t2 - t1))^2 * ((sd1^2 / (n1*r1^2)) + (sd2^2 / (n2*r2^2)))
  
              dat <- data.frame(lnRR_Q10, V_lnRR_Q10)
    colnames(dat) <- c(paste0("lnRR_Q10", name),  
                       paste0("V_lnRR_Q10", name))
  return(dat)
}

Calculating and Interpreting \(lnRR_{Q_{10}}\)

We can now use the function above to calculate \(lnRR_{Q_{10}}\).

Code
library(tidyverse)

# Calculate lnRRQ10 and it's associated sampling variance
q10_dat <- cbind(q10_dat, with(q10_dat, lnRR_Q10(t1 = t1, t2 = t2, r1 = mean_t1, r2 = mean_t2, sd1 = sd_t1, sd2 = sd_t2, n1 = n_t1, n2 = n_t2, name = "")))
head(q10_dat)
  study_ID            study_name year           species     order  life_stage
1      119 119_Udyawer_etal_2016 2016  Hydrophis curtus serpentes unspecified
2      119 119_Udyawer_etal_2016 2016  Hydrophis curtus serpentes unspecified
3      119 119_Udyawer_etal_2016 2016  Hydrophis curtus serpentes unspecified
4      119 119_Udyawer_etal_2016 2016 Hydrophis elegans serpentes unspecified
5      119 119_Udyawer_etal_2016 2016 Hydrophis elegans serpentes unspecified
6      119 119_Udyawer_etal_2016 2016 Hydrophis elegans serpentes unspecified
  animal_source body_mass respiration_mode replication_level dive.type
1          wild       160          bimodal        individual voluntary
2          wild       160          bimodal        individual voluntary
3          wild       160          bimodal        individual voluntary
4          wild      1035          bimodal        individual voluntary
5          wild      1035          bimodal        individual voluntary
6          wild      1035          bimodal        individual voluntary
  summary_stat acclimation_temp t1 t2 mean_t delta_t t_magnitude mean_t1 sd_t1
1         mean               27 21 24     22       3       plus3      40  16.1
2         mean               27 24 27     26       3       plus3      28  15.4
3         mean               27 27 30     28       3       plus3      16   4.9
4         mean               27 21 24     22       3       plus3      27  13.3
5         mean               27 24 27     26       3       plus3      22  10.0
6         mean               27 27 30     28       3       plus3      14   4.7
  n_t1 se_t1 mean_t2 sd_t2 n_t2 se_t2 shared_control  Q10 source lnRR_Q10
1   11   4.8      28  15.4   11  4.63              1 0.33  Fig1B    -1.12
2   11   4.6      16   4.9   11  1.47              2 0.14  Fig1B    -1.96
3   11   1.5      11   3.5   11  1.05              3 0.31  Fig1B    -1.16
4   10   4.2      22  10.0   10  3.16              1 0.46  Fig1B    -0.78
5   10   3.2      14   4.7   10  1.47              2 0.24  Fig1B    -1.43
6   10   1.5      11   2.0   10  0.63              3 0.43  Fig1B    -0.84
  V_lnRR_Q10
1       0.46
2       0.39
3       0.20
4       0.50
5       0.36
6       0.16
Code
# Now we can back-calculate to put on the original Q10 scale. We can than check that this matches the Q10 already in the data
head(q10_dat %>% mutate(exp_lnRR_Q10 = exp(lnRR_Q10)) %>% select(exp_lnRR_Q10, Q10))
  exp_lnRR_Q10  Q10
1         0.33 0.33
2         0.14 0.14
3         0.31 0.31
4         0.46 0.46
5         0.24 0.24
6         0.43 0.43

Now that we have our \(lnRR_{Q_{10}}\) effect size estimates which we back-transformed how do we interpret them?

How do we interpret \(lnRR_{Q_{10}}\)?

Given these are simply \(Q_{10}\)’s we can interpret these normally. A value \(<1\) means the physiological rate decreases with a 10\(^{\circ}\)C increase in temperature; a value \(>1\) means it increases. For the first row of our data, \(Q_{10} \approx\) 0.33, meaning dive duration at the higher temperature is about 33% of dive duration 10\(^{\circ}\)C lower – i.e., a decrease of roughly 67% per 10\(^{\circ}\)C warming.


Acclimation Response Ratio, ARR

Pottier et al. (2021) used the acclimation response ratio, ARR, to investigate variation in the relationship between acclimation temperature and thermal tolerance (i.e. variation in slope). Because heat tolerance is consistently measured in degrees Celsius (CTmax) in the studies compiled, the slope between acclimation temperature and heat tolerance can be calculated, which is termed as the acclimation response ratio (ARR) in the literature. It is defined as the difference in the trait mean between the higher and lower acclimation temperature, divided by the difference in acclimation temperature:

\[ \text{ARR} = \frac{M_{\text{high}} - M_{\text{low}}}{T_{\text{high}} - T_{\text{low}}}, \tag{4.4}\] where \(M_{\text{high}}\) and \(M_{\text{low}}\) are the mean trait values (e.g. CTmax) at the higher and lower acclimation temperatures, and \(T_{\text{high}}\) and \(T_{\text{low}}\) are those acclimation temperatures. Because \(T_{\text{high}} > T_{\text{low}}\), the sign of ARR simply tracks the sign of \(M_{\text{high}} - M_{\text{low}}\): a positive ARR means the trait increases with acclimation temperature.

When the two groups are independent, the sampling variance for \(ARR\) follows from applying the variance of a linear combination and dividing by the (fixed) squared temperature difference:

\[ \sigma^2_{ARR} = \left( \frac{1}{T_{\text{high}} - T_{\text{low}}} \right)^2 \left( \frac{SD^2_{\text{high}}}{N_{\text{high}}} + \frac{SD^2_{\text{low}}}{N_{\text{low}}} \right) \tag{4.5}\]

In this example, we will use a simplified data set from Pottier et al. (2021), and demonstrate how to investigate the mean effect of acclimation temperature on heat tolerance. This effect size is calculated as the difference between the heat tolerance at the higher (mean_high) and the lower (mean_low) acclimation temperatures, divided by the difference between acclimation temperatures (acc_temp_high - acc_temp_low).

Download Data and Functions for \(ARR\)

Code
asr_dat <- read.csv("https://osf.io/qn2af/download")

We’ll also need a function for calculating ARR and its sampling variance because these don’t exist in any current packages.

Code
#' @title arr
#' @description Calculates the acclimation response ratio (ARR) and its sampling variance.
#' @param x1_h  Mean trait value at the higher acclimation temperature
#' @param x2_l  Mean trait value at the lower acclimation temperature
#' @param sd1_h Standard deviation of the trait at the higher acclimation temperature
#' @param sd2_l Standard deviation of the trait at the lower acclimation temperature
#' @param n1_h  Sample size at the higher acclimation temperature
#' @param n2_l  Sample size at the lower acclimation temperature
#' @param t1_h  Higher of the two acclimation temperatures
#' @param t2_l  Lower of the two acclimation temperatures

arr <- function(x1_h, x2_l, sd1_h, sd2_l, n1_h, n2_l, t1_h, t2_l){
        ARR <- (x1_h - x2_l)/(t1_h - t2_l)
      V_ARR <- ((1/(t1_h - t2_l))^2*(sd2_l^2/n2_l + sd1_h^2/n1_h))
return(data.frame(ARR, V_ARR))
}

Calculating and Interpreting \(ARR\)

Using the arr function above we can now calculate the acclimation response ratio (ARR)

Code
# Calculate the effect sizes
asr_dat<-asr_dat %>% 
              mutate(ARR= arr(x1_h = mean_high, x2_l = mean_low, t1_h = acc_temp_high, t2_l = acc_temp_low, 
                              sd1_h = sd_high, sd2_l = sd_low, n1_h = n_high_adj, n2_l = n_low_adj)[,1], 
                     V_ARR = arr(x1_h =  mean_high, x2_l = mean_low, t1_h = acc_temp_high, t2_l = acc_temp_low, 
                              sd1_h = sd_high, sd2_l = sd_low, n1_h = n_high_adj, n2_l = n_low_adj)[,2])
head(asr_dat %>% select(ARR, V_ARR))
    ARR   V_ARR
1 0.060 1.6e-04
2 0.089 1.1e-04
3 0.086 1.8e-04
4 0.090 9.3e-05
5 0.082 1.0e-04
6 0.062 7.8e-05

Now try to interpret \(ARR\) effect size estimates

How do we interpret \(ARR\)? for the first row of the data

If we look at the first row of data, we can see that for each degree increase in acclimation temperature, the heat tolerance of the animals included in this data set increases by 0.06\(^{\circ}\)C.


References

Borenstein, M. (2019). Heterogenity in meta-analysis. In (ed. Cooper, H.), Hedges, L. V.), and Valentine, J. C.), pp. 454–466. New York: Russell Sage Foundation.
Hedges, L. V., Gurevitch, J. and Curtis, P. S. (1999). The meta-analysis of response ratios in experimental ecology. Ecology 80, 1150–1156.
Noble, D. W. A., Pottier, P., Lagisz, M., Burke, S., Drobniak, S. M., O’Dea, R. E. and Nakagawa, S. (2022). Meta-analytic approaches and effect sizes to account for “nuisance heterogeneity” in comparative physiology. Journal of Experimental Biology 225, jeb243225.
Pottier, P., Burke, S., Drobniak, S. M., Lagisz, M. and Nakagawa, S. (2021). Sexual (in) equality? A meta‐analysis of sex differences in thermal acclimation capacity across ectotherms. Functional Ecology 35, 2663–2678, https://doi.org/10.1111/1365–2435.13899.
Rodgers, E. M., Franklin, C. E. and Noble, D. W. A. (2021). Diving in hot water: A meta-analytic review of how diving vertebrate ectotherms will fare in a warmer world. Journal of Experimental Biology 224, 1–12.


Session Information

R version 4.5.3 (2026-03-11)

Platform: aarch64-apple-darwin20

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: lubridate(v.1.9.5), forcats(v.1.0.1), stringr(v.1.6.0), dplyr(v.1.2.1), purrr(v.1.2.2), readr(v.2.2.0), tidyr(v.1.3.2), tibble(v.3.3.1), ggplot2(v.4.0.3) and tidyverse(v.2.0.0)

loaded via a namespace (and not attached): gtable(v.0.3.6), jsonlite(v.2.0.0), compiler(v.4.5.3), Rcpp(v.1.1.1-1.1), tidyselect(v.1.2.1), scales(v.1.4.0), yaml(v.2.3.12), fastmap(v.1.2.0), R6(v.2.6.1), generics(v.0.1.4), knitr(v.1.51), htmlwidgets(v.1.6.4), pander(v.0.6.6), pillar(v.1.11.1), RColorBrewer(v.1.1-3), tzdb(v.0.5.0), rlang(v.1.2.0), stringi(v.1.8.7), xfun(v.0.57), S7(v.0.2.2), otel(v.0.2.0), timechange(v.0.4.0), cli(v.3.6.6), withr(v.3.0.2), magrittr(v.2.0.5), digest(v.0.6.39), grid(v.4.5.3), hms(v.1.1.4), lifecycle(v.1.0.5), vctrs(v.0.7.3), evaluate(v.1.0.5), glue(v.1.8.1), farver(v.2.1.2), rmarkdown(v.2.31), tools(v.4.5.3), pkgconfig(v.2.0.3) and htmltools(v.0.5.9)