GitHub Repository
The Rmarkdown file can be downloaded from the Code drop down menu (top right).2
This supplementary file contains the R workflow for processing and analysing the raw data, and creating figures for the manuscript ID: GEB-2022-0268 titled “Open habitats increase vulnerability of amphibian tadpoles to climate warming across latitude”.
Water temperature is computed based on a heat budget considering longwave radiation, solar heating, and standard bulk aerodynamic flux parameterizations for sensible and latent heat (Mitchell et al., 2012). The budget is driven by fundamental meteorological conditions provided in the microclimate model of NicheMapR (Kearney and Porter, 2017), specific to each site, with the Equation (1.1).
\[\begin{equation} (Lp_w\ c_p)\ \ \frac{dT_w}{dt}=p_w\ c_p\ (I\ T_i-O\ T_w+R\ T_{sky}A_L\ )+(H-E-S+\phi_{LW} +\phi_{SW})\ A_L \tag{1.1} \end{equation}\]
where \(T_w\) is the lake temperature, \(T_i\) is the inflow temperature, \(T_{sky}\) is the air temperature (all in °K), \(p_w\) is the density of water (kg m-3), \(c_p\) is the specific heat capacity of water (J kg-1 K-1), \(L\) is the lake volume (m-3) and \(I\), \(O\), and (\(A_L\ R\)) are the inflow, outflow and rainfall volume fluxes respectively (m-3 d-1), where \(A_L\) is the lake surface area (m-2) used to multiply the rainfall depth (m d-1). \(H\) (1.2), \(E\) (1.3), \(S\) (1.4) are heat fluxes (W m-2) for sensible heat, evaporative and soil heat conduction, respectively, calculated according to:
\[\begin{equation} H=p_a\ c_p\ C_H\ u_2 (T_{sky}-T_w) \tag{1.2} \end{equation}\]
\[\begin{equation} E=p_a\ \lambda\ C_E\ u_2\ (e_s-e_a) \tag{1.3} \end{equation}\]
\[\begin{equation} S=\frac{C_S}{z_s}(T_s-T_w) \tag{1.4} \end{equation}\]
where \(C_H\) and \(C_E\) are bulk transfer coefficients for sensible and latent heat respectively (-), \(\lambda\) is the latent heat of vaporization (J kg-1), \(p_a\) is the density of air (kg m-3), and \(C_S\) is the diffusivity of heat into the soil below the water (W m-1 K-1), and \(z_s\) is the active soil depth over which heat diffusion occurs. \(\phi_{LW}\) (1.5) is the new longwave radiation (W m-2) and \(\phi_{SW}\) (1.6) is the solar insolation (W m-2), calculated from:
\[\begin{equation} \phi_{LW}=\varepsilon_a\ \sigma(T_{sky})^4-\varepsilon_w\ \sigma(T_w)^4 \tag{1.5} \end{equation}\]
\[\begin{equation} \phi_{SW}=(1-\alpha)\ {\hat{\phi}}_{SW}\bigg[\frac{A_L}{A_{MAX}}\ k_s \bigg] \tag{1.6} \end{equation}\]
where \(\varepsilon\) is the emissivity of air or water, \(\sigma\) is the Stefan-Boltzmann constant, \(\alpha\) is the shortwave radiation albedo, \({\hat{\phi}}_{SW}\) is the incident solar radiation above vegetation (W m-2). The last term (1.6) accounts for the effect of wetland vegetation shading on the incident solar intensity, with \(k_s\) defined as a constant to increase the shading effect, and \(A_{MAX}\) is the maximum area of inundation extent (m-2). In NicheMapR, assumed values for \(C_S\), \(C_H\), \(C_E\), \(\varepsilon_a\), \(k_s\) were 0.5, 0.0013, 0.0013, 0.99 and 0.25, respectively.
The raw data for analysis is available on GitHub. This section is the import and clean the raw data for analysis.
# Clean raw data
<- read.csv("https://raw.githubusercontent.com/nicholaswunz/tadpole-thermal-tolerance/main/data/raw_data.csv", na.strings = c("" , "NA" ), stringsAsFactors = TRUE) %>%
clean_dat ::mutate(WT = CTmax - Tmax,
dplyrregion = factor(region, levels = c('Subtropics', 'Temperate')),
country = as.factor(country),
habitat = as.factor(collection_habitat),
species_tree = gsub(" ", "_", species))
# Summarise data by group
<- as.data.frame(clean_dat %>%
summary_dat ::group_by(region, country, habitat, family, species, sp_abbr, species_tree, breeding_habitat, citation) %>%
dplyr::summarise(lon = mean(lon),
dplyrlat = mean(lat),
CTmax_mean = mean(CTmax),
CTmax_SD = sd(CTmax),
Tmax = mean(Tmax),
WT_mean = mean(WT),
WT_SD = sd(WT),
n = n(),
month_start = mean(month_start),
month_end = mean(month_end))) %>%
::relocate(c(breeding_habitat, citation), .after = last_col()) dplyr
Table S1. List of species included in the study with their sample size (n), mean ± s.d. critical thermal maxima (CTmax), maximum environmental water temperature (Tmax), habitat type based on collection site, and spatial coordinates (latitude and longitude as decimal degree).
Species (abbreviation) | n | CTmax ± s.d. (°C) | Tmax (°C) | Collection habitat | Latitude | Longitude |
---|---|---|---|---|---|---|
Bufo bankorensis (BB) | 15 | 37.54±0.40 | 18.79 | Forest | 23.919 | 120.883 |
Microhyla heymonsi (MH) | 15 | 37.44±0.58 | 23.90 | Forest | 23.919 | 120.883 |
Odorrana swinhoana (OS) | 30 | 35.85±0.51 | 23.55 | Forest | 23.988 | 121.129 |
Kurixalus berylliniris (KBE) | 16 | 33.54±0.73 | 24.74 | Forest | 22.803 | 121.051 |
Kurixalus eiffingeri (KE) | 15 | 31.05±1.60 | 25.01 | Forest | 23.690 | 120.791 |
Polypedates braueri (PB) | 12 | 40.17±0.32 | 26.77 | Forest | 23.889 | 120.891 |
Zhangixalus moltrechti (ZM) | 15 | 37.36±0.52 | 24.17 | Forest | 23.889 | 120.891 |
Duttaphrynus melanostictus (DM) | 15 | 41.41±0.22 | 35.12 | Open | 24.181 | 120.609 |
Fejervarya limnocharis (FL) | 20 | 41.50±0.93 | 30.12 | Open | 24.863 | 121.550 |
Hyla chinensis (HC) | 12 | 38.23±0.39 | 29.14 | Open | 24.594 | 120.999 |
Microhyla fissipes (MF) | 19 | 39.71±0.77 | 29.34 | Open | 24.890 | 121.567 |
Micryletta steinegeri (MS) | 12 | 37.35±0.45 | 33.03 | Open | 23.836 | 120.748 |
Hylarana latouchii (HL) | 12 | 37.52±0.37 | 21.34 | Open | 23.891 | 120.884 |
Rana longicrus (RL) | 10 | 35.79±0.51 | 19.75 | Open | 25.191 | 121.590 |
Rana sauteri (RS) | 14 | 32.44±1.14 | 24.89 | Open | 23.902 | 120.891 |
Buergeria choui (BC) | 20 | 41.40±1.03 | 30.12 | Open | 24.863 | 121.550 |
Buergeria robusta (BR) | 13 | 38.48±1.21 | 25.28 | Open | 23.879 | 120.887 |
Kurixalus idiootocus (KI) | 10 | 37.40±1.35 | 30.00 | Open | 23.914 | 120.896 |
Rana pirica (RP) | 8 | 33.91±1.48 | 14.50 | Forest | 42.595 | 141.281 |
Bufo japonicus formosus (BJF) | 7 | 40.10±0.48 | 32.50 | Open | 43.143 | 141.204 |
Glandirana rugosa (GR) | 10 | 39.15±0.35 | 32.50 | Open | 43.002 | 141.181 |
Bombina orientalis (BO) | 30 | 39.93±0.67 | 23.29 | Forest | 36.813 | 128.054 |
Bufo gargarizans (BG) | 48 | 38.04±0.61 | 17.95 | Forest | 36.491 | 127.197 |
Rana coreana (RC) | 42 | 36.02±1.63 | 16.99 | Forest | 36.718 | 126.618 |
Rana uenoi (RU) | 12 | 38.23±0.68 | 21.95 | Forest | 36.812 | 128.052 |
Dryophytes japonicus (DJ) | 36 | 40.91±1.52 | 32.50 | Open | 37.599 | 126.892 |
Kaloula borealis (KBO) | 6 | 42.65±0.26 | 36.84 | Open | 37.521 | 126.880 |
Pelophylax nigromaculatus (PN) | 8 | 39.50±3.61 | 32.50 | Open | 36.887 | 126.936 |
Glandirana emeljanovi (GE) | 30 | 38.10±1.07 | 29.05 | Open | 37.832 | 127.558 |
Table S1. Continuation of species summary with additional information on Family, and notes on the species typical breeding habitat based on the associated references. Species grouped as forest primarily breed in forest habitats. Species grouped as forest edge typically breed at the edges of forests (more exposure to sunlight). Species grouped as open primarily breed in open habitats. Species grouped as generalist typically breed in both forest and open habitats.
Family | Species | Breeding habitat | Citation |
---|---|---|---|
Bufonidae | Bufo bankorensis | Generalist | Huang et al. 1996 |
Microhylidae | Microhyla heymonsi | Generalist | Chuang pers. comm. |
Ranidae | Odorrana swinhoana | Forest | Lai et al. 2007 |
Rhacophoridae | Kurixalus berylliniris | Forest | Wu et al. 2016 |
Rhacophoridae | Kurixalus eiffingeri | Forest | Lin et al. 2008 |
Rhacophoridae | Polypedates braueri | Forest | Hsu et al. 2012 |
Rhacophoridae | Zhangixalus moltrechti | Forest edge | Chang et al. 2014 |
Bufonidae | Duttaphrynus melanostictus | Open | Huang et al. 1997 |
Dicroglossidae | Fejervarya limnocharis | Open | Kuan et al. 2011 |
Hylidae | Hyla chinensis | Generalist | Chuang pers. comm. |
Microhylidae | Microhyla fissipes | Open | Chuang pers. comm. |
Microhylidae | Micryletta steinegeri | Open | Chuang pers. comm. |
Ranidae | Hylarana latouchii | Generalist | Huang et al. 2004 |
Ranidae | Rana longicrus | Open | Kam et al. 1995 |
Ranidae | Rana sauteri | Generalist | Jang-Liaw et al. 2009 |
Rhacophoridae | Buergeria choui | Generalist | Tominaga et al. 2015 |
Rhacophoridae | Buergeria robusta | Generalist | Lin et al. 2012 |
Rhacophoridae | Kurixalus idiootocus | Generalist | Hou et al. 2008 |
Ranidae | Rana pirica | Forest | Matsui et al. 2018; Haramura pers. comm. |
Bufonidae | Bufo japonicus formosus | Open | Matsui et al. 2018; Haramura pers. comm. |
Ranidae | Glandirana rugosa | Open | Matsui et al. 2018; Haramura pers. comm. |
Bombinatoridae | Bombina orientalis | Forest edge | Yang et al. 2001 |
Bufonidae | Bufo gargarizans | Forest edge | Yang et al. 2001; Ambu et al. 2022 |
Ranidae | Rana coreana | Generalist | Yang et al. 2001; Ambu et al. 2022 |
Ranidae | Rana uenoi | Generalist | Yang et al. 2001; Ambu et al. 2022 |
Hylidae | Dryophytes japonicus | Generalist | Yang et al. 2001; Roh et al. 2014 |
Microhylidae | Kaloula borealis | Open | Yang et al. 2001; Jung et al. 2013 |
Microhylidae | Pelophylax nigromaculatus | Open | Yang et al. 2001; Yoo et al. 2019 |
Ranidae | Glandirana emeljanovi | Generalist | Yang et al. 2001 |
Table S2. Accession number of genes of all species (ingroups and outgroups) in the analysis from the National Center for Biotechnology Information (NCBI).
Species | 12S | 16S | COI | cytb |
---|---|---|---|---|
Ingroup | ||||
Bufo gargarizans | DQ275350 | DQ275350 | DQ275350 | DQ275350 |
Bufo japonicus formosus | LC061223 | LC061223 | AB713498 | |
Bombina orientalis | AY585338 | AY585338 | AY585338 | AY585338 |
Buergeria choui | DQ283055 | DQ283055 | MH034165 | KC151119 |
Buergeria robusta | AB530075 | AF026370 | GU244379 | JF802879 |
Bufo bankorensis | AF160768 | AF160786 | HQ650558 | AB159260 |
Dryophytes japonicus | AB303949 | AB303949 | AB303949 | AB303949 |
Duttaphrynus melanostictus | AY458592 | AY458592 | AY458592 | AY458592 |
Fejervarya limnocharis | AY158705 | AY158705 | AY158705 | AY158705 |
Glandirana emeljanovi | NC_030211 | NC_030211 | NC_030211 | NC_030211 |
Glandirana rugosa | KF771341 | KF771341 | JQ844517 | KF771341 |
Hyla chinensis | AY458593 | AY458593 | AY458593 | AY458593 |
Hylarana latouchii | KF771284 | AB058880 | JN700815 | EU034751 |
Kaloula borealis | NC_020044 | NC_020044 | NC_020044 | NC_020044 |
Kurixalus berylliniris | DQ468669 | DQ468677 | ||
Kurixalus eiffingeri | AB933305 | AF026363 | DQ468680 | |
Kurixalus idiootocus | AB933306 | DQ468674 | DQ468682 | GQ204503 |
Microhyla fissipes | AB201175 | AB201185 | KR087802 | AB201219 |
Microhyla heymonsi | AY458596 | AY458596 | AY458596 | AY458596 |
Micryletta steinegeri | AB634638 | AB634696 | ||
Odorrana swinhoana | AB200929 | KF185045 | HQ650557 | |
Pelophylax nigromaculatus | KT878718 | KT878718 | KT878718 | KT878718 |
Polypedates braueri | AB728016 | AB728003 | KR087860 | |
Rana coreana | NC_024548 | NC_024548 | NC_024548 | NC_024548 |
Rana longicrus | AB058881 | JF939130 | ||
Rana pirica | KX269184 | KX269184 | KX024946 | KX269331 |
Rana sauteri | AB685767 | AB211495 | EU034956 | |
Rana uenoi | KX269177 | KX024885 | KX024945 | KX024969 |
Zhangixalus moltrechti | AF458145 | DQ468676 | HQ650556 | U00710 |
Outgroup | ||||
Ascaphus truei | X86225 | DQ283116 | AJ871087 | AF277330 |
Batrachuperus pinchonii | AY916007 | DQ283340 | KM201393 | AY593142 |
Gyrinophilus porphyriticus | EU336432 | DQ283255 | NC_006341 | NC_006341 |
This section is the import the phylogenetic tree (see phylogenetic reconstruction in main text) comprising of 29 species, match names with the data set, and create a correlation matrix for subsequent analysis.
# Load phylogeny data
<- ape::read.tree("https://raw.githubusercontent.com/nicholaswunz/tadpole-thermal-tolerance/main/data/tree2021_12.nwk")
phylo_tree
<- phylo_tree$tip.label # extract tree tip names
tree_tip_label <- unique(clean_dat$species_tree) # extract species name from main dataset
species_list <- as.data.frame(setdiff(tree_tip_label, species_list)) # check what names from the dataset not found in phylo_tree
missing_sp # Three outgroups in tree
<- ape::drop.tip(phylo_tree, setdiff(phylo_tree$tip.label, species_list)) # prune phylo_tree to keep species from the main dataset
pruned_tree
# check if lengths match for both data and tree
<- length(unique(pruned_tree$tip.label)) # 29
sp_n #length(unique(clean_dat$species_tree)) # 29
# Check for polytomies
#ape::is.binary(pruned_tree) # TRUE
# Compute branch lengths
<- ape::compute.brlen(pruned_tree, method = "Grafen", power = 1)
pruned_tree_cal #ape::is.ultrametric(pruned_tree_cal) # TRUE
# Create correlation matrix for analysis
<- vcv(pruned_tree_cal, cor = T) phylo_cor
Fig. S1. Phylogenetic reconstruction of all 29 amphibian species used in this study. Species that were collected from closed-forest habitats shown with filled triangles, while species that were collected from open habitats shown with open circles.
Table S3. Parameter values used to estimate pond temperature using NicheMapR. Parameters for which settings differ from default values are shown in bold. Default values for other parameters in the model remained.
ID | Value | Variable name | Variable unit |
---|---|---|---|
latitude | Provided in table S1 | latitude coordinate | \(^{\circ}\) |
longitude | Provided in table S1 | latitude coordinate | \(^{\circ}\) |
nyears | 2 | number of years to run | # |
soiltype | clay (modified*) | soil type | - |
REFL | 0.15 | soil solar reflectance | decimal % |
slope | 0 | slope | \(^{\circ}\) |
aspect | 0 | aspect | \(^{\circ}\) |
DEP | 0, 2, 5, 10, 15, 20, 30, 45, 90, 200 | soil depth | cm |
minshade | 0 (unshaded) or 90 (shaded) | minimum shade level | % |
maxshade | 10 (unshaded) 100 (shaded) | maximum shade level | % |
runshade | TRUE | run model with shade? | - |
clearsky | FALSE | run with clear sky? | - |
SLE | 0.95 | substrate longwave IR emissivity | decimal % |
Thcond | 2.5 | soil mineral thermal conductivity | W m\(\\^{-1}\) K\(\\^{-1}\) |
Density | 2.56 | soil mineral density | kg m\(\\^{-3}\) |
SpecHeat | 870 | soil mineral heat capacity | J kg\(\\^{-1}\) K\(\\^{-1}\) |
BulkDensity | 1.4 | soil bulk density | kg m\(\\^{-3}\) |
hori | 0 | horizon angles | \(^{\circ}\) |
cap | FALSE | organic surface layer? | - |
PE | -2.731491 | air entry potential | J kg\(\\^{-1}\) |
KS | 6.41E-05 | saturated conductivity | kg s m\(\\^{-3}\) |
BB | 16.1914 | Campbell\('\)s soil \('\)b\('\) parameter | - |
BD | 1.4 | soil bulk density | mg m\(\\^{-3}\) |
DD | 2.56 | soil density | mg m\(\\^{-3}\) |
maxpool | 500 | maximum pool depth | mm |
rainmult | 10 | rainfall multiplier | - |
LAI | 0 | leaf area index | - |
snowmodel | FALSE | run snow model? | - |
soilgrids | FALSE | query soilgrids? | - |
windfac | TRUE | wind multiplier | - |
warm | 0 (current) or 4 (warming) | warming offset vector | \(^{\circ}\)C |
* textural soil properties for clay: depth (2.5, 7.5, 22.5, 45, 80, 150), bulk density 1.4 mg m\(\\^3\), 90% clay, 0% silt, 10% sand.
Define soil parameters to enable construction of hypothetical water body in NicheMapR. Parameters modified presented in Table S3.
# Define textural soil properties for clay
<- matrix(data = 0, nrow = 6, ncol = 5)
soilpro colnames(soilpro) <- c('depth', 'blkdens', 'clay', 'silt', 'sand')
<- as.data.frame(soilpro) %>%
soilpro ::mutate(depth = c(2.5, 7.5, 22.5, 45, 80, 150),
dplyrblkdens = 1.4, # bulk density (Mg/m3)
clay = 90, # % clay
silt = 0.0, # % silt
sand = 10) # % sand
<- c(0, 2, 5, 10, 15, 20, 30, 40, 50, 100) # Soil nodes (cm)
DEP
# Get hydraulic properties for given soil
<- NicheMapR::pedotransfer(soilpro = soilpro, DEP = DEP)
soil.hydro <- soil.hydro$PE
PE <- soil.hydro$BB
BB <- soil.hydro$BD
BD <- soil.hydro$KS
KS <- BD[seq(1, 19, 2)]
BulkDensity
<- 10 # Rainfall multiplier to reflect catchment (1 will result in unadjusted rainfall)
rainmult <- 500 # maximium pooling depth (mm), i.e. wetland depth
maxpool <- 0 # leaf area index (zero so no transpiration)
LAI <- 0 # do not simulate the organic cap layer
cap <- 0 # don't use SoilGrids soil database for thermal properties soilgrids
Run NichemapR to simulate pond temperatures under four hypothetical scenarios: (a) current climate with open habitat, (b) current climate with shaded habitat, (c) warming climate with open habitat, and (d) warming climate with shaded habitat.
# Simulate dates for 2 years
<- NicheMapR::micro_global(nyear = 2)$dates
dates
# Create loop for each coordinates
<- NULL
est_Tmax_open for( i in 1:nrow(summary_dat)){
<- data.frame(
result ::micro_global(loc = c(summary_dat$lon[i], summary_dat$lat[i]),
NicheMapRrunshade = 0, minshade = 0, maxshade = 10, # shade parameters
PCTWET = 100, # model surface soil wetness (%),
PE = PE, BB = BB, BD = BD, KS = KS, rainmult = rainmult,
maxpool = maxpool, LAI = LAI, cap = cap, soilgrids = soilgrids, # soil parameters to simulate pool
warm = 0, # current climate
nyear = 2,)$soil) %>% # extract soil parameters
::mutate(dates = dates) %>%
dplyr::filter(dates >= summary_dat$month_start[i] & dates <= summary_dat$month_end[i]) %>%
dplyr::summarise(est_Tmax_open = max(D0cm))
dplyrprint(result)
<- cbind(summary_dat$species[i], result)
results_2 <- rbind(est_Tmax_open, results_2)
est_Tmax_open
}
<- NULL
est_Tmax_shade for( i in 1:nrow(summary_dat)){
<- data.frame(
result ::micro_global(loc = c(summary_dat$lon[i], summary_dat$lat[i]),
NicheMapRrunshade = 0, minshade = 95, maxshade = 100, # shade parameters
PCTWET = 100, # model surface soil wetness (%),
PE = PE, BB = BB, BD = BD, KS = KS, rainmult = rainmult, maxpool = maxpool, LAI = LAI, cap = cap, soilgrids = soilgrids, # soil parameters to simulate pool
warm = 0, # current climate
nyear = 2)$soil) %>% # Extract soil parameters
::mutate(dates = dates) %>%
dplyr::filter(dates >= summary_dat$month_start[i] & dates <= summary_dat$month_end[i]) %>%
dplyr::summarise(est_Tmax_shade = max(D0cm))
dplyrprint(result)
<- rbind(est_Tmax_shade, result)
est_Tmax_shade
}
<- NULL
est_Tmax_open_4C for( i in 1:nrow(summary_dat)){
<- data.frame(
result ::micro_global(loc = c(summary_dat$lon[i], summary_dat$lat[i]),
NicheMapRrunshade = 0, minshade = 0, maxshade = 10, # shade parameters
PCTWET = 100, # model surface soil wetness (%),
PE = PE, BB = BB, BD = BD, KS = KS, rainmult = rainmult, maxpool = maxpool, LAI = LAI, cap = cap, soilgrids = soilgrids, # soil parameters to simulate pool
warm = 4, # future climate
nyear = 2,)$soil) %>% # extract soil parameters
::mutate(dates = dates) %>%
dplyr::filter(dates >= summary_dat$month_start[i] & dates <= summary_dat$month_end[i]) %>%
dplyr::summarise(est_Tmax_open_4C = max(D0cm))
dplyrprint(result)
<- rbind(est_Tmax_open_4C, result)
est_Tmax_open_4C
}
<- NULL
est_Tmax_shade_4C for( i in 1:nrow(summary_dat)){
<- data.frame(
result ::micro_global(loc = c(summary_dat$lon[i], summary_dat$lat[i]),
NicheMapRrunshade = 0, minshade = 95, maxshade = 100, # shade parameters
PCTWET = 100, # model surface soil wetness (%),
PE = PE, BB = BB, BD = BD, KS = KS, rainmult = rainmult, maxpool = maxpool, LAI = LAI, cap = cap, soilgrids = soilgrids, # soil parameters to simulate pool
warm = 4, # future climate
nyear = 2)$soil) %>% # extract soil parameters
::mutate(dates = dates) %>%
dplyr::filter(dates >= summary_dat$month_start[i] & dates <= summary_dat$month_end[i]) %>%
dplyr::summarise(est_Tmax_shade_4C = max(D0cm))
dplyrprint(result)
<- rbind(est_Tmax_shade_4C, result)
est_Tmax_shade_4C
}
<- cbind(summary_dat, est_Tmax_shade, est_Tmax_open[,2], est_Tmax_shade_4C, est_Tmax_open_4C) %>%
proj_data ::rename(est_Tmax_open = "est_Tmax_open[, 2]") dplyr
Predicted Tmax from the heat budget models were validated with a linear model (below) and visually in Fig. S2e.
<- lm(Tmax ~ est_Tmax_shade + habitat, data = proj_data)
predict_obs_model
<- summary(predict_obs_model)$r.squared
verify <- Metrics::mae(proj_data$Tmax, predict(predict_obs_model)) model_mae
Fig. S2 Maximum water temperature (Tmax as degree Celsius) output from the microclimate model. Example pond temperature output over a one year period for (a) Bombina orientalis, a temperate species in Korea (36.813 °N, 128.054 °E), (b) Pelophylax nigromaculatus, a temperate species in Korea (36.887 °N, 126.936 °E), (c) Kurixalus eiffingeri, a subtropics species in Taiwan (23.914 °N, 120.896 °E), and (d) Duttaphrynus melanostictus, a subtropics species in Taiwan (24.181 °N, 120.608 °E). The solid and dashed line represents the estimated water temperature under shaded conditions (95–100% vegetation shade) and under open conditions (1–10% vegetation shade), respectively. The filled area was the environmental data collection period, and the single dashed horizontal grey line is the observed Tmax from the study. (e) The observed and estimated Tmax for each species, matching the study location and time. Observed temperatures were recorded by HOBO Water Temperature loggers while the estimated Tmax was estimated from NicheMapR under open (filled triangles) and shaded habitats (open circles). Dashed line represents 1:1 scale, and R² = 0.7137031, with a mean absolute error of 2.3863238.
Run analysis looking at the relationship between (a) CTmax and Tmax (CTmax–Tmax model), (b) warming tolerance (WT) and Tmax (WT–Tmax model), and (c) WT and CTmax (WT–CTmax model).
set.seed(10)
# Set priors
<- c(
prior ::prior(normal(0, 5), "b"), # mean of 0 and SD of 10 (wide distribution)
brms::prior(student_t(3, 0, 10), "sd"), # class of random effect deviation to calculate - has to be positive (no negative SD)
brms::prior(student_t(3, 0, 10), "sigma")) # residual SD parameter
brms
# Run CTmax_Tmax_model
<- brms::brm(CTmax ~ Tmax + habitat + lat + (1 | species) + (1 | gr(species_tree, cov = phylo)),
CTmax_Tmax_model data = clean_dat,
family = gaussian,
data2 = list(phylo = phylo_cor),
prior = prior,
iter = 1e4, warmup = 5e3, cores = 4, chains = 4,
control = list(adapt_delta = 0.99, max_treedepth = 18))
# Run WT_Tmax_model
<- brms::brm(WT ~ Tmax + habitat + lat + (1 | species) + (1 | gr(species_tree, cov = phylo)),
WT_Tmax_model data = clean_dat,
family = gaussian,
data2 = list(phylo = phylo_cor),
prior = prior,
iter = 1e4, warmup = 5e3, cores = 4, chains = 4,
control = list(adapt_delta = 0.99, max_treedepth = 18))
# Run WT_CTmax_model (grouped by species because of co-correlation of Ctmax and WT with Tmax)
<- brms::brm(WT_mean ~ CTmax_mean + habitat + lat + (1 | gr(species_tree, cov = phylo)),
WT_CTmax_model data = summary_dat,
family = gaussian,
prior = prior,
data2 = list(phylo = phylo_cor),
iter = 1e4, warmup = 5e3, cores = 4, chains = 4,
control = list(adapt_delta = 0.99, max_treedepth = 18))
Fig. S3. Scatterplots of the observed data (y) vs the average simulated data (yrep) from the posterior predictive distribution for the (a) CTmax–Tmax model, (b) WT–Tmax model, and (c) WT–CTmax model. Dashed line represents a slope of 1.
Table S4. Point estimates and 95% credible intervals (as determined using Bayesian methods) for fitted parameters estimated for the correlation between CTmax and Tmax, which includes fixed-effect parameters for \(\beta_0\), the average across-species intercept; \(\beta_1\), the average across-species slope of Tmax; habitat (closed and open habitat); and latitude. Group-level effects include the standard deviations (sd) for species-level variation in the intercept (\(\Delta_{\beta_0[\zeta]}\)), and phylogenetic variation in the intercept (\(\Delta_{\beta_0[\phi]}\)). Phylogenetic signal was calculated as \(\lambda = \sigma_\phi^2 / (\sigma_\phi^2 + \sigma^2)\), where \(\sigma_\phi^2\) is the estimated phylogenetic variance (i.e. sd\((\Delta_{\beta_0[\phi]})^2\)).
Parameter | Estimate | Est.Error | Q2.5 | Q97.5 |
---|---|---|---|---|
Fixed effects | ||||
\(\beta_0\) | 29.388 | 3.241 | 23.026 | 35.762 |
Tmax, \(\beta_1\) | 0.241 | 0.117 | 0.009 | 0.471 |
Habitat - Open | 0.268 | 1.220 | -2.146 | 2.644 |
Latitude | 0.081 | 0.065 | -0.048 | 0.210 |
Group-level effects | ||||
sd\((\Delta_{\beta_0[\zeta]})\) | 2.086 | 0.504 | 1.011 | 3.064 |
sd\((\Delta_{\beta_0[\phi]})\) | 1.812 | 1.409 | 0.066 | 5.277 |
Phylogenetic signal | ||||
\(\lambda\) | 0.580 | 0.311 | 0.004 | 0.961 |
Table S5. Point estimates and 95% credible intervals (as determined using Bayesian methods) for fitted parameters estimated for the correlation between warming tolerance and Tmax, which includes fixed-effect parameters for \(\beta_0\), the average across-species intercept; \(\beta_1\), the average across-species slope of Tmax; habitat (closed and open habitat); and latitude. Group-level effects include the standard deviations (sd) for species-level variation in the intercept (\(\Delta_{\beta_0[\zeta]}\)), and phylogenetic variation in the intercept (\(\Delta_{\beta_0[\phi]}\)). Phylogenetic signal was calculated as \(\lambda = \sigma_\phi^2 / (\sigma_\phi^2 + \sigma^2)\), where \(\sigma_\phi^2\) is the estimated phylogenetic variance (i.e. sd\((\Delta_{\beta_0[\phi]})^2\)).
Parameter | Estimate | Est.Error | Q2.5 | Q97.5 |
---|---|---|---|---|
Fixed effects | ||||
\(\beta_0\) | 29.445 | 3.334 | 22.853 | 36.016 |
Tmax, \(\beta_1\) | -0.761 | 0.117 | -0.992 | -0.531 |
Habitat - Open | 0.303 | 1.236 | -2.140 | 2.752 |
Latitude | 0.081 | 0.065 | -0.050 | 0.209 |
Group-level effects | ||||
sd\((\Delta_{\beta_0[\zeta]})\) | 2.088 | 0.500 | 1.029 | 3.071 |
sd\((\Delta_{\beta_0[\phi]})\) | 1.863 | 1.429 | 0.081 | 5.334 |
Phylogenetic signal | ||||
\(\lambda\) | 0.589 | 0.310 | 0.006 | 0.963 |
Table S6. Point estimates and 95% credible intervals (as determined using Bayesian methods) for fitted parameters estimated for the correlation between warming tolerance and CTmax at the species level, which includes fixed-effect parameters for \(\beta_0\), the average across-species intercept; \(\beta_1\), the average across-species slope of CTmax; habitat (closed and open habitat); and latitude. Group-level effects include the standard deviations (sd) for phylogenetic variation in the intercept (\(\Delta_{\beta_0[\phi]}\)). Phylogenetic signal was calculated as \(\lambda = \sigma_\phi^2 / (\sigma_\phi^2 + \sigma^2)\), where \(\sigma_\phi^2\) is the estimated phylogenetic variance (i.e. sd\((\Delta_{\beta_0[\phi]})^2\)).
Parameter | Estimate | Est.Error | Q2.5 | Q97.5 |
---|---|---|---|---|
Fixed effects | ||||
\(\beta_0\) | 4.957 | 12.022 | -18.649 | 28.594 |
CTmax, \(\beta_1\) | 0.278 | 0.336 | -0.384 | 0.933 |
Habitat - Open | -5.589 | 1.611 | -8.700 | -2.343 |
Latitude | -0.028 | 0.120 | -0.262 | 0.213 |
Group-level effect | ||||
sd\((\Delta_{\beta_0[\phi]})\) | 3.240 | 2.162 | 0.175 | 8.526 |
Phylogenetic signal | ||||
\(\lambda\) | 0.416 | 0.289 | 0.002 | 0.947 |
Run analysis looking at the relationship between (a) CTmax and (b) warming tolerance (WT) between habitat (closed-forest and open) and region (subtropic and temperate).
<- brms::brm(CTmax ~ habitat + region + (1 | species) + (1 | gr(species_tree, cov = phylo)),
CTmax_model data = clean_dat,
family = gaussian,
data2 = list(phylo = phylo_cor),
prior = prior,
iter = 1e4, warmup = 5e3, cores = 4, chains = 4,
control = list(adapt_delta = 0.99, max_treedepth = 18))
<- brms::brm(WT ~ habitat * region + (1 | species) + (1 | gr(species_tree, cov = phylo)),
WT_model data = clean_dat,
family = gaussian,
data2 = list(phylo = phylo_cor),
prior = prior,
iter = 1e4, warmup = 5e3, cores = 4, chains = 4,
control = list(adapt_delta = 0.99, max_treedepth = 18))
<- brms::brm(WT ~ lat * habitat + (1 | species) + (1 | gr(species_tree, cov = phylo)),
WT_lat_model data = clean_dat,
family = gaussian,
data2 = list(phylo = phylo_cor),
prior = prior,
iter = 1e4, warmup = 5e3, cores = 4, chains = 4,
control = list(adapt_delta = 0.99, max_treedepth = 18))
Fig. S4. Scatterplots of the observed data (y) vs the average simulated data (yrep) from the posterior predictive distribution for the (a) CTmax model, (b) WT model, and (c) WT–latitude model. Dashed line represents a slope of 1.
Table S7. Point estimates and 95% credible intervals (as determined using Bayesian methods) for fitted parameters estimated for the relationship between CTmax with habitat and region, which includes fixed-effect parameters for \(\beta_0\), the average across-species intercept; habitat (closed and open habitat); and region (subtropics, temperate). Group-level effects include the standard deviations (sd) for species-level variation in the intercept (\(\Delta_{\beta_0[\zeta]}\)), and phylogenetic variation in the intercept (\(\Delta_{\beta_0[\phi]}\)). Phylogenetic signal was calculated as \(\lambda = \sigma_\phi^2 / (\sigma_\phi^2 + \sigma^2)\), where \(\sigma_\phi^2\) is the estimated phylogenetic variance (i.e. sd\((\Delta_{\beta_0[\phi]})^2\)).
Parameter | Estimate | Est.Error | Q2.5 | Q97.5 |
---|---|---|---|---|
Fixed effects | ||||
\(\beta_0\) | 36.548 | 1.378 | 33.888 | 39.434 |
Habitat - Open | 2.133 | 0.928 | 0.321 | 3.963 |
Region - Temperate | 1.688 | 0.987 | -0.272 | 3.611 |
Group-level effects | ||||
sd\((\Delta_{\beta_0[\zeta]})\) | 2.105 | 0.519 | 1.075 | 3.141 |
sd\((\Delta_{\beta_0[\phi]})\) | 2.264 | 1.394 | 0.203 | 5.527 |
Phylogenetic signal | ||||
\(\lambda\) | 0.697 | 0.258 | 0.036 | 0.965 |
Table S8. Point estimates and 95% credible intervals (as determined using Bayesian methods) for fitted parameters estimated for the correlation between warming tolerance and Tmax, which includes fixed-effect parameters for \(\beta_0\), the average across-species intercept; \(\beta_1\), the average across-species slope of Tmax; habitat (closed and open habitat); and latitude. Group-level effects include the standard deviations (sd) for species-level variation in the intercept (\(\Delta_{\beta_0[\zeta]}\)), and phylogenetic variation in the intercept (\(\Delta_{\beta_0[\phi]}\)). Phylogenetic signal was calculated as \(\lambda = \sigma_\phi^2 / (\sigma_\phi^2 + \sigma^2)\), where \(\sigma_\phi^2\) is the estimated phylogenetic variance (i.e. sd\((\Delta_{\beta_0[\phi]})^2\)).
Parameter | Estimate | Est.Error | Q2.5 | Q97.5 |
---|---|---|---|---|
Fixed effects | ||||
\(\beta_0\) | 13.087 | 1.773 | 9.685 | 16.783 |
Habitat - Open | -3.005 | 1.524 | -6.064 | -0.011 |
Region - Temperate | 3.756 | 1.920 | -0.142 | 7.410 |
Habitat - Open: Region - Temperate | -6.241 | 2.349 | -10.699 | -1.529 |
Group-level effects | ||||
sd\((\Delta_{\beta_0[\zeta]})\) | 3.184 | 0.603 | 2.072 | 4.453 |
sd\((\Delta_{\beta_0[\phi]})\) | 2.102 | 1.644 | 0.083 | 6.297 |
Phylogenetic signal | ||||
\(\lambda\) | 0.625 | 0.307 | 0.006 | 0.973 |
Run analysis looking at the relationship between climate (current and warming), with the interaction between category (open and shaded simulated habitat), habitat (closed and open habitat - breeding) and region (subtropics, temperate) on warming tolerance.
# Calculate WT
<- proj_data %>%
proj_data ::mutate(WT_shade_cur = CTmax_mean - est_Tmax_shade,
dplyrWT_open_cur = CTmax_mean - est_Tmax_open,
WT_shade_4C = CTmax_mean - est_Tmax_shade_4C,
WT_open_4C = CTmax_mean - est_Tmax_open_4C)
# Convert wide to long format
<- proj_data %>%
proj_long ::select(region, species, CTmax_mean, habitat, lat, WT_shade_cur, WT_open_cur, WT_shade_4C, WT_open_4C) %>%
dplyr::pivot_longer(!c(region, species, CTmax_mean, habitat, lat), names_to = "category", values_to = "values") %>%
tidyr::mutate(climate = case_when(endsWith(category, "cur") ~ "Current",
dplyrendsWith(category, "4C")~ "Warming"),
category = dplyr::recode(category,
WT_open_cur = "Open habitat",
WT_shade_cur = "Shaded habitat",
WT_open_4C = "Open habitat",
WT_shade_4C = "Shaded habitat"))
# Add phylogeny to dataset
$species_tree <- summary_dat$species_tree[match(proj_long$species, summary_dat$species)]
proj_long
# Run brms model
<- brms::brm(values ~ climate + category * habitat * region + (1 | species) + (1 | gr(species_tree, cov = phylo)),
proj_model data = proj_long,
family = gaussian,
data2 = list(phylo = phylo_cor),
iter = 1e4, warmup = 5e3, cores = 4, chains = 4,
control = list(adapt_delta = 0.99, max_treedepth = 18))
Fig. S5. Scatterplot of the observed data (y) vs the average simulated data (yrep) from the posterior predictive distribution for the climate and deforestation projection model. Dashed line represents a slope of 1.
Table S9. Point estimates and 95% credible intervals (as determined using Bayesian methods) for fitted parameters estimated for the relationship between warming tolerance with climate change and deforestation, which includes fixed-effect parameters for \(\beta_0\), the average across-species intercept; climate (current, warming); and the three-way interaction with shaded (open and shaded simulated habitat), habitat (closed and open habitat - breeding) and region (subtropics, temperate). Group-level effects include the standard deviations (sd) for species-level variation in the intercept (\(\Delta_{\beta_0[\zeta]}\)), and phylogenetic variation in the intercept (\(\Delta_{\beta_0[\phi]}\)). Phylogenetic signal was calculated as \(\lambda = \sigma_\phi^2 / (\sigma_\phi^2 + \sigma^2)\), where \(\sigma_\phi^2\) is the estimated phylogenetic variance (i.e. sd\((\Delta_{\beta_0[\phi]})^2\)).
Parameter | Estimate | Est.Error | Q2.5 | Q97.5 |
---|---|---|---|---|
Fixed effects | ||||
\(\beta_0\) | 9.097 | 2.239 | 4.688 | 13.798 |
Climate - Warming | -3.266 | 0.145 | -3.554 | -2.983 |
Shaded | 6.845 | 0.292 | 6.266 | 7.412 |
Habitat - Open | -0.072 | 1.863 | -3.681 | 3.610 |
Region - Temperate | -3.538 | 2.552 | -8.637 | 1.472 |
Shaded: Habitat - Open | 0.068 | 0.375 | -0.656 | 0.803 |
Shaded: Region - Temperate | 4.977 | 0.452 | 4.098 | 5.856 |
Habitat - Open: Region - Temperate | 2.713 | 3.232 | -3.559 | 9.076 |
Shaded: Habitat - Open: Region - Temperate | -2.206 | 0.597 | -3.376 | -1.036 |
Group-level effects | ||||
sd\((\Delta_{\beta_0[\zeta]})\) | 3.333 | 0.855 | 1.286 | 4.901 |
sd\((\Delta_{\beta_0[\phi]})\) | 2.793 | 2.390 | 0.091 | 8.739 |
Phylogenetic signal | ||||
\(\lambda\) | 0.735 | 0.302 | 0.014 | 0.992 |
Raw figures produced were modified in Adobe Illustrator for publication.
# Extract marginal effects
<- as.data.frame(ggeffects::ggpredict(CTmax_Tmax_model, terms = c("Tmax[sample = 25]")))
CTmax_Tmax_me <- as.data.frame(ggeffects::ggpredict(WT_Tmax_model, terms = c("Tmax[sample = 25]")))
WT_Tmax_me
# Fig 2
<- summary_dat %>%
ctmax_tmax_plot ggplot() +
geom_ribbon(data = CTmax_Tmax_me, aes(x = x, ymin = conf.low, ymax = conf.high), fill = "#FE945C",alpha = 0.1) +
geom_line(data = CTmax_Tmax_me, aes(x = x, y = conf.low), colour = "#FE945C", linetype = "dashed") +
geom_line(data = CTmax_Tmax_me, aes(x = x, y = conf.high), colour = "#FE945C", linetype = "dashed") +
geom_line(data = CTmax_Tmax_me, aes(x = x, y = predicted), colour = "#DD3B24", size = 1) +
geom_point(aes(x = Tmax, y = CTmax_mean, colour = region, shape = habitat), size = 2, fill = "white") +
scale_shape_manual(values = c(17, 21)) +
scale_colour_manual(values = c("#DD3B24", "#FE945C")) +
xlab(expression(T["max"]~"(°C)")) +
ylab(expression("CT"["max"]~"(°C)")) +
mytheme()
<- summary_dat %>%
wt_tmax_plot ggplot() +
geom_ribbon(data = WT_Tmax_me, aes(x = x, ymin = conf.low, ymax = conf.high), fill = "#FE945C",alpha = 0.1) +
geom_line(data = WT_Tmax_me, aes(x = x, y = conf.low), colour = "#FE945C", linetype = "dashed") +
geom_line(data = WT_Tmax_me, aes(x = x, y = conf.high), colour = "#FE945C", linetype = "dashed") +
geom_line(data = WT_Tmax_me, aes(x = x, y = predicted), colour = "#DD3B24", size = 1) +
geom_point(aes(x = Tmax, y = WT_mean, colour = region, shape = habitat), size = 2, fill = "white") +
scale_shape_manual(values = c(17, 21)) +
scale_colour_manual(values = c("#DD3B24", "#FE945C")) +
xlab(expression(T['max']~"(°C)")) +
ylab("Warming tolerance") +
mytheme()
<- summary_dat %>%
wt_ctmax_plot ggplot() +
geom_point(aes(x = CTmax_mean, y = WT_mean, colour = region, shape = habitat), size = 2, fill = "white") +
scale_shape_manual(values = c(17, 21)) +
scale_colour_manual(values = c("#DD3B24", "#FE945C")) +
xlab(expression(CT['max']~"(°C)")) +
ylab("Warming tolerance") +
mytheme()
::plot_grid(ctmax_tmax_plot + theme(legend.position = "none"),
cowplot+ theme(legend.position = "none"),
wt_tmax_plot + theme(legend.position = "none"),
wt_ctmax_plot ncol = 3, align = "hv", axis = "tblr", labels = c("a", "b", "c"))
Latitude as category (Fig. 3a and 3b)
# Fig 3 production
<- summary_dat %>%
CTmax_plot # regrouping
::group_by(region) %>%
dplyr::arrange(habitat, CTmax_mean) %>%
dplyrmutate(x = row_number()) %>% # change to number to order by habitat and CTmax
ungroup() %>%
# plotting
ggplot(aes(x = x, y = CTmax_mean, colour = region, shape = habitat, label = sp_abbr)) +
stat_mean_line(aes(linetype = habitat), alpha = 0.5) +
geom_pointrange(aes(ymin = CTmax_mean - CTmax_SD, ymax = CTmax_mean + CTmax_SD, linetype = habitat)) +
geom_point(size = 3, fill = "white") +
scale_shape_manual(values = c(17, 21)) +
scale_colour_manual(values = c("#DD3B24", "#FE945C")) +
geom_text(nudge_y = 1.5, size = 3, show.legend = FALSE) +
xlab(NULL) +
ylab(expression("CT"["max"]~"(°C)")) +
facet_grid(. ~ region, scales = 'free_x') +
mytheme() +
theme(axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank())
<- summary_dat %>%
WT_plot # regrouping
::group_by(region) %>%
dplyr::arrange(habitat, WT_mean) %>%
dplyrmutate(x = row_number()) %>% # change to number to order by habitat and WT
ungroup() %>%
# plotting
ggplot(aes(x = x, y = WT_mean, colour = region, shape = habitat, label = sp_abbr)) +
stat_mean_line(aes(linetype = habitat), alpha = 0.5) +
geom_pointrange(aes(ymin = WT_mean - WT_SD, ymax = WT_mean + WT_SD, linetype = habitat)) +
geom_point(size = 3, fill = "white") +
scale_shape_manual(values = c(17, 21)) +
scale_colour_manual(values = c("#DD3B24", "#FE945C")) +
geom_text(nudge_y = 2, size = 3, show.legend = FALSE) +
ylim(0, 25) +
xlab("Species") +
ylab("Warming tolerance") +
facet_grid(. ~ region, scales = 'free_x') +
mytheme() +
theme(axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank())
::plot_grid(CTmax_plot, WT_plot, nrow = 2, align = "hv", axis = "tblr", labels = c("a", "b")) cowplot
Latitude as continuous (Fig. 3c)
<- as.data.frame(ggeffects::ggpredict(WT_lat_model, terms = c("lat [sample = 26]", "habitat")))
WT_lat_me
%>%
summary_dat ggplot() +
geom_ribbon(data = WT_lat_me, aes(x = x, ymin = conf.low, ymax = conf.high, fill = group), alpha = 0.1) +
geom_line(data = WT_lat_me, aes(x = x, y = conf.low, group = group), colour = "#DD3B24", linetype = "dashed") +
geom_line(data = WT_lat_me, aes(x = x, y = conf.high, group = group), colour = "#DD3B24", linetype = "dashed") +
geom_line(data = WT_lat_me, aes(x = x, y = predicted, linetype = group), colour = "#DD3B24", size = 1) +
geom_point(aes(x = lat, y = WT_mean, shape = habitat), colour = "#DD3B24", size = 2, fill = "white") +
scale_shape_manual(values = c(17, 21)) +
scale_fill_manual(values = c("#FE945C", "white")) +
xlab("Latitude (°)") +
ylab("Warming tolerance") +
mytheme()
# Extract estimate +/- 95% CI
<- make_conditions(proj_model, c("climate", "region"))
conditions <- brms::conditional_effects(proj_model, "category:habitat", conditions = conditions)
predict_me <- as.data.frame(predict_me[[1]]) %>% dplyr::rename(estimate = estimate__, ci.lb = lower__, ci.ub = upper__)
predict_dat
%>%
proj_long ::mutate(category = forcats::fct_relevel(as.factor(category),"Shaded habitat", "Open habitat")) %>%
dplyrggplot() +
geom_hline(yintercept = 0, linetype = "dashed", alpha = 0.5) +
geom_point(aes(x = category, y = values, colour = region, shape = habitat), size = 2, position = position_dodge(0.6), fill = "grey", alpha = 0.5) +
geom_pointrange(data = predict_dat, aes(x = category, y = estimate, ymin = ci.lb, ymax = ci.ub, colour = region, shape = habitat, linetype = habitat),
position = position_dodge(0.6), size = 0.7, fill = "white") +
ylab("Warming tolerance") + xlab(NULL) +
scale_shape_manual(values = c(17, 21)) +
scale_colour_manual(values = c("#DD3B24", "#FE945C")) +
scale_fill_manual(values = c("#DD3B24", "#FE945C")) +
ylim(-10, max(proj_long$values)) +
facet_grid(. ~ climate) +
mytheme() +
theme(legend.position = "bottom")
The micro_global
function did not have the soil moisture function on by default. After consultation with the NicheMapR developer Michael Kearney, we re-estimated the pond temperatures using the micro_era5
function which provides fine-scale resolution (~1 km weather model forecast.
The model does not confirm that pond drying will ‘not occur’ as stated in the main text. However, the higher rain multiplier (rainmult
) reduces the likelihood of pond drying.
The equations from the Pond thermodynamic model do not apply to the NicheMapR models. We followed the methods from Enriquez-Urzelai et al. (2019) to estimate pond temperature.
Download the mcera5
microclimate data to a local directory to run the micro_era5
function faster.
# get ERA5 data with package mcera5
# assign your credentials (register here: https://cds.climate.copernicus.eu/user/register)
<- "$$$$$$"
uid <- "$$$$$$$$-$$$$-$$$$-$$$$-$$$$$$$$$$$$"
cds_api_key ::wf_set_key(user = uid, key = cds_api_key, service = "cds")
ecmwfr
# bounding coordinates (in WGS84 / EPSG:4326)
<- min(summary_dat$lon) - 1
xmn <- max(summary_dat$lon) + 1
xmx <- min(summary_dat$lat) - 1
ymn <- max(summary_dat$lat) + 1
ymx
# temporal extent
<- lubridate::ymd("2013:01:01") # earliest sampling date
st_time <- lubridate::ymd("2020:12:31") # latest sampling date
en_time
# filename and location for downloaded .nc files
<- "era5"
file_prefix <- "YOUR DIRECTORY"
op
# build a request (covering multiple years)
<- mcera5::build_era5_request(xmin = xmn, xmax = xmx,
req ymin = ymn, ymax = ymx,
start_time = st_time,
end_time = en_time,
outfile_name = file_prefix)
::request_era5(request = req, uid = uid, out_path = op) mcera5
Run NichemapR to simulate pond temperatures under four hypothetical scenarios: (a) current climate with open habitat, (b) current climate with shaded habitat, (c) warming climate with open habitat, and (d) warming climate with shaded habitat. To ensure the pond does not dry up during the sampling period, we increased rainmult
to 20.
<- as.data.frame(clean_dat %>%
sum_dat ::group_by(region, country, habitat, family, species) %>%
dplyr::summarise(lon = mean(lon),
dplyrlat = mean(lat),
Tmax = mean(Tmax),
year_start = min(year_start),
year_end = min(year_finish),
month_start = mean(month_start),
month_end = mean(month_end)))
# Create loop for each coordinates
<- NULL
est_Tmax for( i in 1:nrow(sum_dat)){
<-
micro_out ::micro_era5(loc = c(sum_dat$lon[i], sum_dat$lat[i]),
NicheMapRrunshade = 1, minshade = 0, # shade parameters
PE = PE, BB = BB, BD = BD, KS = KS, rainmult = 20,
maxpool = maxpool, LAI = LAI, cap = cap, soilgrids = soilgrids, # soil parameters to simulate pool
warm = 0, # current climate
DEP = DEP,
dstart = paste("01/01/", sum_dat$year_start[i], sep =""),
dfinish = paste("31/12/", sum_dat$year_end[i], sep =""),
runmoist = 1,
spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/NicheMapR/era5', # change to your location
save = 0)
<- data.frame(micro_out$metout) %>% # extract soil parameters
metout ::mutate(dates = row_number() / 730) %>% # hours to month
dplyr::filter(dates >= sum_dat$month_start[i] & dates <= sum_dat$month_end[i])
dplyr
# extract water temp in open habitat
<- data.frame(micro_out$soil) %>% # extract soil parameters
open ::mutate(dates = row_number() / 730) %>% # hours to month
dplyrmerge(metout, by = "dates") %>%
::filter(dates >= sum_dat$month_start[i] & dates <= sum_dat$month_end[i] & POOLDEP > 400) %>%
dplyr::summarise(est_Tmax_open = max(D50cm))
dplyrprint(open)
# extract water temp in shaded habitat
<- data.frame(micro_out$shadsoil) %>% # extract soil parameters
closed ::mutate(dates = row_number() / 730) %>% # hours to month
dplyrmerge(metout, by = "dates") %>%
::filter(dates >= sum_dat$month_start[i] & dates <= sum_dat$month_end[i] & POOLDEP > 400) %>%
dplyr::summarise(est_Tmax_shade = max(D50cm))
dplyrprint(closed)
<- cbind(sum_dat$species[i], open, closed)
results <- rbind(est_Tmax, results)
est_Tmax
}
<- NULL
est_Tmax_4C for( i in 1:nrow(sum_dat)){
<-
micro_out ::micro_era5(loc = c(sum_dat$lon[i], sum_dat$lat[i]),
NicheMapRrunshade = 1, minshade = 0, # shade parameters
PE = PE, BB = BB, BD = BD, KS = KS, rainmult = 20,
maxpool = maxpool, LAI = LAI, cap = cap, soilgrids = soilgrids, # soil parameters to simulate pool
warm = 4, # future climate
DEP = DEP,
dstart = paste("01/01/", sum_dat$year_start[i], sep =""),
dfinish = paste("31/12/", sum_dat$year_end[i], sep =""),
runmoist = 1,
spatial = '/Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/NicheMapR/era5', # change to your location
save = 0)
<- data.frame(micro_out$metout) %>% # extract soil parameters
metout ::mutate(dates = row_number() / 730) %>% # hours to month
dplyr::filter(dates >= sum_dat$month_start[i] & dates <= sum_dat$month_end[i])
dplyr
# extract water temp in open habitat
<- data.frame(micro_out$soil) %>% # extract soil parameters
open ::mutate(dates = row_number() / 730) %>% # hours to month
dplyrmerge(metout, by = "dates") %>%
::filter(dates >= sum_dat$month_start[i] & dates <= sum_dat$month_end[i] & POOLDEP > 400) %>%
dplyr::summarise(est_Tmax_open_4C = max(D50cm))
dplyrprint(open)
# extract water temp in shaded habitat
<- data.frame(micro_out$shadsoil) %>% # extract soil parameters
closed ::mutate(dates = row_number() / 730) %>% # hours to month
dplyrmerge(metout, by = "dates") %>%
::filter(dates >= sum_dat$month_start[i] & dates <= sum_dat$month_end[i] & POOLDEP > 400) %>%
dplyr::summarise(est_Tmax_shade_4C = max(D50cm))
dplyrprint(closed)
<- cbind(sum_dat$species[i], open, closed)
results <- rbind(est_Tmax_4C, results)
est_Tmax_4C
}
<- cbind(summary_dat, est_Tmax[,2], est_Tmax[,3], est_Tmax_4C[,2], est_Tmax_4C[,3]) %>%
proj_data ::rename(est_Tmax_open = "est_Tmax[, 2]",
dplyrest_Tmax_shade = "est_Tmax[, 3]",
est_Tmax_open_4C = "est_Tmax_4C[, 2]",
est_Tmax_shade_4C = "est_Tmax_4C[, 3]")
Predicted Tmax from the heat budget models were validated with a linear model (below) and visually in Updated Fig. S2.
<- proj_data %>%
proj_test mutate(est_Tmax_test = ifelse(habitat == "Forest", est_Tmax_shade, est_Tmax_open)) %>%
filter_all(all_vars(!is.infinite(.)))
<- lm(Tmax ~ est_Tmax_test, data = proj_test)
predict_obs_model
<- summary(predict_obs_model)$r.squared
verify2 <- Metrics::mae(proj_test$Tmax, predict(predict_obs_model)) model_mae2
## downloading DEM via package elevatr
## extracting weather data locally from /Users/nicholaswu/Library/CloudStorage/OneDrive-WesternSydneyUniversity/NicheMapR/era5
## computing radiation and elevation effects with package microclima
## Downscaling radiation and wind speed
## Calculating meso-scale terrain effects
## running microclimate model for 365 days from 2014-01-01 to 2014-12-31 23:00:00 at site long 121.1295 lat 23.98788
## Note: the output column `SOLR` in metout and shadmet is for unshaded solar radiation adjusted for slope, aspect and horizon angle
## user system elapsed
## 5.642 0.075 5.777
Updated Fig. S2 The observed and estimated Tmax for each species, matching the study location and time. Observed temperatures were recorded by HOBO Water Temperature loggers while the estimated Tmax was estimated from NicheMapR under open (filled triangles) and shaded habitats (open circles). Dashed line represents 1:1 scale, and R² = 0.5621393, with a mean absolute error of 2.9461639.
The updated estimated pond temperatures did not differ much relative to the original simulations.
R version 4.2.2 (2022-10-31)
Platform: aarch64-apple-darwin20 (64-bit)
attached base packages: stats, graphics, grDevices, utils, datasets, methods and base
other attached packages: microclima(v.0.1.0), RNetCDF(v.2.6-1), mcera5(v.0.3.0), raster(v.3.6-13), sp(v.1.5-1), pander(v.0.6.5), NicheMapR(v.3.2.1), diversitree(v.0.9-16), phytools(v.1.2-0), maps(v.3.4.1), ape(v.5.6-2), rstan(v.2.21.7), StanHeaders(v.2.21.0-7), brms(v.2.18.0), Rcpp(v.1.0.9), colorspace(v.2.0-3), forcats(v.0.5.2), stringr(v.1.5.0), dplyr(v.1.0.10), purrr(v.1.0.1), readr(v.2.1.3), tidyr(v.1.2.1), tibble(v.3.1.8), tidyverse(v.1.3.2), Matrix(v.1.5-1), cowplot(v.1.1.1), ggplot2(v.3.4.0) and knitr(v.1.41)
loaded via a namespace (and not attached): utf8(v.1.2.2), tidyselect(v.1.2.0), htmlwidgets(v.1.6.1), hoardr(v.0.5.2), grid(v.4.2.2), combinat(v.0.0-8), munsell(v.0.5.0), units(v.0.8-1), codetools(v.0.2-18), DT(v.0.26), miniUI(v.0.1.1.1), withr(v.2.5.0), Brobdingnag(v.1.2-9), progressr(v.0.13.0), highr(v.0.10), rstudioapi(v.0.14), stats4(v.4.2.2), Metrics(v.0.1.4), bayesplot(v.1.10.0), labeling(v.0.4.2), emmeans(v.1.8.3), mnormt(v.2.1.1), optimParallel(v.1.0-2), farver(v.2.1.1), bridgesampling(v.1.1-2), coda(v.0.19-4), vctrs(v.0.5.1), generics(v.0.1.3), clusterGeneration(v.1.3.7), xfun(v.0.36), timechange(v.0.2.0), slippymath(v.0.3.1), R6(v.2.5.1), markdown(v.1.4), fields(v.14.1), cachem(v.1.0.6), assertthat(v.0.2.1), promises(v.1.2.0.1), scales(v.1.2.1), RNCEP(v.1.0.10), googlesheets4(v.1.0.1), gtable(v.0.3.1), ncmeta(v.0.3.5), processx(v.3.8.0), phangorn(v.2.10.0), spam(v.2.9-1), rlang(v.1.0.6), scatterplot3d(v.0.3-42), rgdal(v.1.6-4), gargle(v.1.2.1), broom(v.1.0.2), checkmate(v.2.1.0), inline(v.0.3.19), yaml(v.2.3.6), reshape2(v.1.4.4), abind(v.1.4-5), modelr(v.0.1.10), threejs(v.0.3.3), crosstalk(v.1.2.0), backports(v.1.4.1), httpuv(v.1.6.8), tensorA(v.0.36.2), tools(v.4.2.2), tcltk(v.4.2.2), bookdown(v.0.31), ellipsis(v.0.3.2), jquerylib(v.0.1.4), posterior(v.1.3.1), RColorBrewer(v.1.1-3), proxy(v.0.4-27), plyr(v.1.8.8), progress(v.1.2.2), base64enc(v.0.1-3), classInt(v.0.4-8), elevatr(v.0.4.2), ps(v.1.7.2), prettyunits(v.1.1.1), rpart(v.4.1.19), tgp(v.2.4-21), viridis(v.0.6.2), deSolve(v.1.34), zoo(v.1.8-11), cluster(v.2.1.4), haven(v.2.5.1), fs(v.1.5.2), crul(v.1.3), magrittr(v.2.0.3), colourpicker(v.1.2.0), reprex(v.2.0.2), googledrive(v.2.0.0), mvtnorm(v.1.1-3), matrixStats(v.0.63.0), hms(v.1.1.2), shinyjs(v.2.1.0), mime(v.0.12), evaluate(v.0.19), xtable(v.1.8-4), XML(v.3.99-0.13), shinystan(v.2.6.0), readxl(v.1.4.1), gridExtra(v.2.3), ggeffects(v.1.1.4), rstantools(v.2.2.0), compiler(v.4.2.2), tidync(v.0.3.0), ncdf4(v.1.21), KernSmooth(v.2.23-20), crayon(v.1.5.2), htmltools(v.0.5.4), later(v.1.3.0), tzdb(v.0.3.0), expm(v.0.999-6), RcppParallel(v.5.1.5), lubridate(v.1.9.0), DBI(v.1.1.3), sjlabelled(v.1.2.0), dbplyr(v.2.2.1), subplex(v.1.8), rappdirs(v.0.3.3), MASS(v.7.3-58.1), sf(v.1.0-9), cli(v.3.6.0), quadprog(v.1.5-8), parallel(v.4.2.2), insight(v.0.18.8), dotCall64(v.1.0-2), igraph(v.1.3.5), pkgconfig(v.2.0.3), numDeriv(v.2016.8-1.1), terra(v.1.6-47), xml2(v.1.3.3), dygraphs(v.1.1.1.6), bslib(v.0.4.2), estimability(v.1.4.1), rvest(v.1.0.3), distributional(v.0.3.1), callr(v.3.7.3), digest(v.0.6.31), httpcode(v.0.3.0), rmarkdown(v.2.19), cellranger(v.1.1.0), fastmatch(v.1.1-3), curl(v.5.0.0), shiny(v.1.7.4), gtools(v.3.9.4), lifecycle(v.1.0.3), nlme(v.3.1-160), jsonlite(v.1.8.4), viridisLite(v.0.4.1), fansi(v.1.0.3), pillar(v.1.8.1), lattice(v.0.20-45), loo(v.2.5.1), fastmap(v.1.1.0), httr(v.1.4.4), plotrix(v.3.8-2), pkgbuild(v.1.4.0), glue(v.1.6.2), xts(v.0.12.2), shinythemes(v.1.2.0), class(v.7.3-20), stringi(v.1.7.12), sass(v.0.4.4), rnoaa(v.1.3.8), e1071(v.1.7-12) and maptree(v.1.4-8)
Hawkesbury Institute for the Environment, Western Sydney University, NSW 2753, Australia, nicholas.wu.nz@gmail.com↩︎
I would like to thank J. Kong (Trinity College Dublin) for showing me the way of Rmarkdown.↩︎