Main model results
Overall model: ~ trait type
Final model summary
# Uses nearly full data, minus one trait with only a single estimate
final.model <- rma.mv(yi=val.log ~ trait, V=sv.log,
random = ~1|study/est.id, data=data, method="REML", tdist=T)
mlm.variance.distribution(final.model)| % of total variance | I2 | |
|---|---|---|
| Level 1 | 8.831568 | — |
| Level 2 | 34.418637 | 34.42 |
| Level 3 | 56.749795 | 56.75 |
Model I^2 and R^2:
# Main model:
# Get estimate of I^2, residual heterogeneity:
W <- diag(1/data$sv.log) # create initial weighting matrix
X <- model.matrix(final.model)
P <- W - W %*% X %*% solve(t(X) %*% W %*% X) %*% t(X) %*% W
I2 <- 100 * final.model$sigma2 / (sum(final.model$sigma2) + (final.model$k-final.model$p)/sum(diag(P)))
cat(paste0("Overall residual heterogeneity, I^2 = ",round(sum(I2),1), "%"))Overall residual heterogeneity, I^2 = 84.2%
cat(paste0("Between-study residual heterogeneity, I^2 = ",round(I2[1],1), "%"))Between-study residual heterogeneity, I^2 = 52.4%
cat(paste0("Within-study residual heterogeneity, I^2 = ",round(I2[2],1), "%"))Within-study residual heterogeneity, I^2 = 31.8%
# Get estimate of R^2:
Model1 <- rma.mv(yi=val.log ~ 1, V=sv.log,
random = ~1|study/est.id, data=data, method="ML", tdist=T)
Model2 <- rma.mv(yi=val.log ~ trait, V=sv.log,
random = ~1|study/est.id, data=data, method="ML", tdist=T)
(Model1$sigma2[1] - Model2$sigma2[1]) / Model1$sigma2[1] # R^2 = 0 or -0.14[1] -0.3159911
(Model1$sigma2[2] - Model2$sigma2[2]) / Model1$sigma2[2] # R^2 = 0.56[1] 0.5728472
(sum(Model1$sigma2) - sum(Model2$sigma2)) / sum(Model1$sigma2) # R^2 = 0.29 overall?[1] 0.2698959
Model estimates
Model estimates ~ trait type:
overall_trait_mod_est <- update(final.model, .~.-1, ) %>% # remove intercept
summary %>% coef %>% # extract model coefficients + CI
rownames_to_column("trait") %>%
mutate(trait = str_remove(trait, "trait")) %>%
rename(est = estimate)
overall_trait_mod_est_backtrans <- overall_trait_mod_est %>%
mutate(across(.cols = c(est, ci.lb, ci.ub), # apply an anonymous fn
.fns = function(x){exp(x)-0.2} )) %>% # to back-transform
select(-se, -tval, -pval) %>%
mutate(ci.ub = ifelse(ci.ub >1, 1, ci.ub))
write.csv(overall_trait_mod_est, file="Model Estimates/overall_trait_mod_est.csv", row.names=F)
# write.csv(overall_trait_mod_est_backtrans, file="Model Estimates/overall_trait_mod_est_backtrans.csv", row.names=F)
overall_trait_mod_est| trait | est | se | tval | pval | ci.lb | ci.ub |
|---|---|---|---|---|---|---|
| gene expression | -1.1454361 | 0.2174874 | -5.2666774 | 0.0000010 | -1.5778594 | -0.7130128 |
| photochemistry | -0.7823753 | 0.1524744 | -5.1311923 | 0.0000018 | -1.0855352 | -0.4792154 |
| growth | -0.7570162 | 0.1309643 | -5.7803256 | 0.0000001 | -1.0174083 | -0.4966241 |
| nutrient content | -0.6119458 | 0.1609494 | -3.8021018 | 0.0002692 | -0.9319562 | -0.2919354 |
| bleaching | -0.5764261 | 0.1492929 | -3.8610425 | 0.0002195 | -0.8732603 | -0.2795919 |
| symbiont community | -0.4712294 | 0.2267899 | -2.0778239 | 0.0407426 | -0.9221484 | -0.0203104 |
| morphology | -0.3535242 | 0.2334017 | -1.5146599 | 0.1335684 | -0.8175894 | 0.1105409 |
| immune response | -0.2019735 | 0.1906822 | -1.0592157 | 0.2925023 | -0.5811007 | 0.1771537 |
| survival | -0.0109606 | 0.1218698 | -0.0899367 | 0.9285491 | -0.2532703 | 0.2313492 |
Model estimates ~ trait type + h2, ~ trait type + life stage:
overall_trait_mod_est_addh2 <- update(final.model, .~trait + h2 -1, ) %>% # remove intercept
summary %>% coef %>% # extract model coefficients + CI
rownames_to_column("trait") %>%
mutate(trait = str_remove(trait, "trait")) %>%
rename(est = estimate)
overall_trait_mod_est_addh2_backtrans <- overall_trait_mod_est_addh2 %>%
mutate(across(.cols = c(est, ci.lb, ci.ub), # apply an anonymous fn
.fns = function(x){exp(x)-0.2} )) %>% # to back-transform
select(-se, -tval, -pval) %>%
mutate(ci.ub = ifelse(ci.ub >1, 1, ci.ub))
write.csv(overall_trait_mod_est_addh2, file="Model Estimates/overall_trait_mod_est_addh2.csv", row.names=F)
overall_trait_mod_est_addh2| trait | est | se | tval | pval | ci.lb | ci.ub |
|---|---|---|---|---|---|---|
| gene expression | -1.0679538 | 0.2181622 | -4.8952284 | 0.0000047 | -1.5017932 | -0.6341143 |
| photochemistry | -0.7171386 | 0.1516333 | -4.7294265 | 0.0000090 | -1.0186781 | -0.4155992 |
| growth | -0.6915615 | 0.1314874 | -5.2595279 | 0.0000011 | -0.9530386 | -0.4300845 |
| nutrient content | -0.5497992 | 0.1632611 | -3.3676060 | 0.0011461 | -0.8744619 | -0.2251365 |
| bleaching | -0.4680659 | 0.1619014 | -2.8910552 | 0.0048861 | -0.7900246 | -0.1461072 |
| symbiont community | -0.2919001 | 0.2426445 | -1.2029948 | 0.2323581 | -0.7744254 | 0.1906251 |
| morphology | -0.2747410 | 0.2325601 | -1.1813763 | 0.2407872 | -0.7372123 | 0.1877303 |
| immune response | -0.1462565 | 0.1930812 | -0.7574869 | 0.4508779 | -0.5302197 | 0.2377067 |
| survival | 0.0611561 | 0.1294393 | 0.4724693 | 0.6378171 | -0.1962482 | 0.3185604 |
| h2narrow | -0.2413887 | 0.1686414 | -1.4313724 | 0.1560337 | -0.5767506 | 0.0939733 |
overall_trait_mod_est_addstage <- update(final.model, .~trait + stage -1, ) %>% # remove intercept
summary %>% coef %>% # extract model coefficients + CI
rownames_to_column("trait") %>%
mutate(trait = str_remove(trait, "trait")) %>%
rename(est = estimate)
overall_trait_mod_est_addstage_backtrans <- overall_trait_mod_est_addstage %>%
mutate(across(.cols = c(est, ci.lb, ci.ub), # apply an anonymous fn
.fns = function(x){exp(x)-0.2} )) %>% # to back-transform
select(-se, -tval, -pval) %>%
mutate(ci.ub = ifelse(ci.ub >1, 1, ci.ub))
write.csv(overall_trait_mod_est_addstage, file="Model Estimates/overall_trait_mod_est_addstage.csv", row.names=F)
overall_trait_mod_est_addstage| trait | est | se | tval | pval | ci.lb | ci.ub |
|---|---|---|---|---|---|---|
| gene expression | -1.1527253 | 0.2551335 | -4.5181250 | 0.0000205 | -1.6601756 | -0.6452749 |
| photochemistry | -0.7910471 | 0.2069458 | -3.8224845 | 0.0002545 | -1.2026540 | -0.3794402 |
| growth | -0.7431715 | 0.1956972 | -3.7975572 | 0.0002772 | -1.1324054 | -0.3539375 |
| nutrient content | -0.6146672 | 0.2029390 | -3.0288278 | 0.0032715 | -1.0183047 | -0.2110297 |
| bleaching | -0.5705276 | 0.2016775 | -2.8289105 | 0.0058546 | -0.9716560 | -0.1693992 |
| symbiont community | -0.4511896 | 0.2367748 | -1.9055640 | 0.0601691 | -0.9221252 | 0.0197460 |
| morphology | -0.3127279 | 0.2653877 | -1.1783812 | 0.2420120 | -0.8405733 | 0.2151176 |
| immune response | -0.2142387 | 0.2328888 | -0.9199184 | 0.3602813 | -0.6774452 | 0.2489678 |
| survival | -0.0049826 | 0.1668999 | -0.0298537 | 0.9762554 | -0.3369398 | 0.3269746 |
| stagejuvenile | -0.2824011 | 0.2329974 | -1.2120352 | 0.2289380 | -0.7458235 | 0.1810214 |
| stageadult | 0.1001852 | 0.2008286 | 0.4988592 | 0.6191981 | -0.2992547 | 0.4996251 |
These estimates are used to calculate effect sizes in separate excel spreadsheets (found at my github repo: ecolology/heritabilitymeta
Sub-analysis A: ~ trait x life stage + h2 (dat_s subset)
Final model output
# Data subset:
dat_s <- data %>%
filter(!(trait %in% c("photochemistry", "immune response"))) %>%
mutate(trait = fct_drop(trait))
# table.plot("trait", "stage", Data=dat_s)
final.model.A <- rma(yi=val.log ~ trait*stage + h2,
vi=sv.log, data=dat_s, method="REML", test="knha")
final.model.A
Mixed-Effects Model (k = 74; tau^2 estimator: REML)
tau^2 (estimated amount of residual heterogeneity): 0.0382 (SE = 0.0173)
tau (square root of estimated tau^2 value): 0.1953
I^2 (residual heterogeneity / unaccounted variability): 46.98%
H^2 (unaccounted variability / sampling variability): 1.89
R^2 (amount of heterogeneity accounted for): 78.27%
Test for Residual Heterogeneity:
QE(df = 55) = 96.0189, p-val = 0.0005
Test of Moderators (coefficients 2:19):
F(df1 = 18, df2 = 55) = 7.8780, p-val < .0001
Model Results:
estimate se tval pval
intrcpt -0.2731 0.5329 -0.5126 0.6103
traitgrowth 0.4395 0.1690 2.6012 0.0119
traitnutrient content 0.0561 0.5609 0.1001 0.9206
traitbleaching -0.3175 0.5803 -0.5470 0.5866
traitsymbiont community 0.1795 0.5609 0.3200 0.7501
traitmorphology 0.1718 0.5757 0.2984 0.7665
traitsurvival 0.2574 0.5368 0.4794 0.6335
stagejuvenile 0.1620 0.1729 0.9374 0.3526
stageadult -0.6607 0.5544 -1.1917 0.2385
h2narrow -0.2716 0.1195 -2.2720 0.0270
traitgrowth:stagejuvenile -1.4359 0.5894 -2.4364 0.0181
traitbleaching:stagejuvenile -0.6695 0.3533 -1.8951 0.0633
traitsymbiont community:stagejuvenile -0.5102 0.6872 -0.7424 0.4610
traitmorphology:stagejuvenile -0.4727 0.3466 -1.3640 0.1781
traitnutrient content:stageadult -0.1588 0.5932 -0.2678 0.7899
traitbleaching:stageadult 1.1584 0.6216 1.8636 0.0677
traitsymbiont community:stageadult 0.6817 0.6128 1.1125 0.2708
traitmorphology:stageadult 0.3645 0.6503 0.5605 0.5774
traitsurvival:stageadult 0.3266 0.5682 0.5748 0.5678
ci.lb ci.ub
intrcpt -1.3410 0.7947
traitgrowth 0.1009 0.7781 *
traitnutrient content -1.0679 1.1802
traitbleaching -1.4805 0.8456
traitsymbiont community -0.9446 1.3036
traitmorphology -0.9819 1.3255
traitsurvival -0.8184 1.3331
stagejuvenile -0.1844 0.5084
stageadult -1.7718 0.4504
h2narrow -0.5112 -0.0320 *
traitgrowth:stagejuvenile -2.6170 -0.2548 *
traitbleaching:stagejuvenile -1.3776 0.0385 .
traitsymbiont community:stagejuvenile -1.8873 0.8670
traitmorphology:stagejuvenile -1.1672 0.2218
traitnutrient content:stageadult -1.3476 1.0299
traitbleaching:stageadult -0.0873 2.4042 .
traitsymbiont community:stageadult -0.5463 1.9098
traitmorphology:stageadult -0.9388 1.6678
traitsurvival:stageadult -0.8121 1.4653
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Model estimates ~ trait type x life stage + heritability type:
subA_mod_est <- dat_s %>%
group_by(trait, h2, stage) %>%
count() %>% ungroup %>%
arrange(h2, stage, trait) %>%
mutate(est = NA_real_, se = NA_real_)
for (i in 1:nrow(subA_mod_est)) {
row.to.fill <- slice(subA_mod_est, i)
new.data <- dat_s %>%
mutate(
trait = fct_relevel(trait, as.character(row.to.fill$trait)),
h2 = fct_relevel(h2, as.character(row.to.fill$h2)),
stage = fct_relevel(stage, as.character(row.to.fill$stage)))
mod <- new.data %>%
rma(yi=val.log ~ trait * stage + h2, vi=sv.log,
data=., method="REML", test = "knha")
subA_mod_est[i,] <-
row.to.fill %>% mutate(est = coef(mod)["intrcpt"], se = ifelse(is.na(mod$se[1]), 0, mod$se[1]))
}
rm(row.to.fill, new.data, mod)
subA_mod_est <- subA_mod_est %>%
mutate(ci.lb = est - se*qt(0.975, 100),
ci.ub = est + se*qt(0.975, 100))
subA_mod_est_backtrans <- subA_mod_est %>%
mutate(across(.cols = c(est, ci.lb, ci.ub), # apply an anonymous fn
.fns = function(x){exp(x)-0.2} )) %>% # to back-transform
select(-se) %>%
mutate(ci.ub = ifelse(ci.ub >1, 1, ci.ub))
write.csv(subA_mod_est, file="Model Estimates/subA_mod_est.csv", row.names=F)
# write.csv(subA_mod_est_backtrans, file="Model Estimates/subA_mod_est_backtrans.csv", row.names=F)
subA_mod_est| trait | h2 | stage | n | est | se | ci.lb | ci.ub |
|---|---|---|---|---|---|---|---|
| nutrient content | broad | larvae | 2 | -0.2169756 | 0.1750709 | -0.5643114 | 0.1303602 |
| bleaching | broad | larvae | 2 | -0.5905857 | 0.2299316 | -1.0467635 | -0.1344080 |
| morphology | broad | larvae | 1 | -0.1013378 | 0.2179227 | -0.5336903 | 0.3310147 |
| survival | broad | larvae | 2 | -0.0157691 | 0.1308402 | -0.2753523 | 0.2438141 |
| growth | broad | juvenile | 2 | -1.1074603 | 0.1355200 | -1.3763281 | -0.8385925 |
| morphology | broad | juvenile | 1 | -0.4119960 | 0.2120161 | -0.8326298 | 0.0086378 |
| survival | broad | juvenile | 1 | 0.1462689 | 0.1413821 | -0.1342292 | 0.4267669 |
| gene expression | broad | adult | 8 | -0.9338112 | 0.1530899 | -1.2375372 | -0.6300853 |
| growth | broad | adult | 15 | -0.4942861 | 0.0715090 | -0.6361579 | -0.3524144 |
| nutrient content | broad | adult | 5 | -1.0364919 | 0.1176608 | -1.2699276 | -0.8030562 |
| bleaching | broad | adult | 2 | -0.0928555 | 0.1388115 | -0.3682536 | 0.1825425 |
| symbiont community | broad | adult | 1 | -0.0725707 | 0.1935641 | -0.4565963 | 0.3114549 |
| morphology | broad | adult | 2 | -0.3975158 | 0.2405139 | -0.8746886 | 0.0796569 |
| survival | broad | adult | 6 | -0.3498817 | 0.1061082 | -0.5603973 | -0.1393661 |
| gene expression | narrow | larvae | 1 | -0.5447272 | 0.5192737 | -1.5749513 | 0.4854970 |
| symbiont community | narrow | larvae | 2 | -0.3652115 | 0.2120663 | -0.7859450 | 0.0555220 |
| survival | narrow | larvae | 3 | -0.2873720 | 0.1360182 | -0.5572283 | -0.0175157 |
| growth | narrow | juvenile | 6 | -1.3790632 | 0.1333482 | -1.6436222 | -1.1145042 |
| bleaching | narrow | juvenile | 3 | -1.3696826 | 0.1757371 | -1.7183401 | -1.0210252 |
| symbiont community | narrow | juvenile | 1 | -0.7133499 | 0.6303829 | -1.9640116 | 0.5373118 |
| morphology | narrow | juvenile | 1 | -0.6835989 | 0.1969485 | -1.0743391 | -0.2928587 |
| survival | narrow | juvenile | 3 | -0.1253340 | 0.1351653 | -0.3934982 | 0.1428302 |
| bleaching | narrow | adult | 2 | -0.3644584 | 0.1632971 | -0.6884352 | -0.0404816 |
| morphology | narrow | adult | 2 | -0.6691187 | 0.2488572 | -1.1628443 | -0.1753931 |
These estimates are used to calculate effect sizes in separate excel spreadsheets (found at my github repo: ecolology/heritabilitymeta)
Post-hoc contrasts of life stage x trait type
# Create contrast matrices for testing hypotheses:
group <- paste0(dat_s$trait, "_", dat_s$stage)
group <- aggregate(model.matrix(final.model.A) ~ group, FUN=mean)
rownames(group) <- group$group
(group <- group[,-1])| intrcpt | traitgrowth | traitnutrient content | traitbleaching | traitsymbiont community | traitmorphology | traitsurvival | stagejuvenile | stageadult | h2narrow | traitgrowth:stagejuvenile | traitbleaching:stagejuvenile | traitsymbiont community:stagejuvenile | traitmorphology:stagejuvenile | traitnutrient content:stageadult | traitbleaching:stageadult | traitsymbiont community:stageadult | traitmorphology:stageadult | traitsurvival:stageadult | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| bleaching_adult | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0.50 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
| bleaching_juvenile | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1.00 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| bleaching_larvae | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| gene expression_adult | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| gene expression_larvae | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| growth_adult | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| growth_juvenile | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0.75 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| morphology_adult | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0.50 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
| morphology_juvenile | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0.50 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
| morphology_larvae | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| nutrient content_adult | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0.00 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
| nutrient content_larvae | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| survival_adult | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
| survival_juvenile | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0.75 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| survival_larvae | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0.60 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| symbiont community_adult | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0.00 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
| symbiont community_juvenile | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1.00 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| symbiont community_larvae | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1.00 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
# From CI plot, a number of potential differences:
# H1: growth juvenile vs. growth adult (broad sense constant)
# H2: bleaching juvenile vs. bleaching adult
# H3: bleaching juvenile vs. bleaching larvae
# H3: nutrient content larvae vs. nutrient content adult
cont.mat <- rbind(group["growth_juvenile",] - group["growth_adult",],
group["bleaching_juvenile",] - group["bleaching_adult",],
group["bleaching_juvenile",] - group["bleaching_larvae",],
group["nutrient content_larvae",] - group["nutrient content_adult",]) %>% as.matrix
# anova(final.model.Dii, L=cont.mat) # unadjusted
multcomp::glht(final.model.A,
linfct=cont.mat,
test=Ftest()) %>%
summary()
Simultaneous Tests for General Linear Hypotheses
Fit: rma(yi = val.log ~ trait * stage + h2, vi = sv.log, data = dat_s,
method = "REML", test = "knha")
Linear Hypotheses:
Estimate Std. Error z value Pr(>|z|)
growth_juvenile == 0 -0.8169 0.1427 -5.725 < 1e-04 ***
bleaching_juvenile == 0 -1.1410 0.2242 -5.089 < 1e-04 ***
bleaching_juvenile1 == 0 -0.7791 0.2894 -2.692 0.027577 *
nutrient content_larvae == 0 0.8195 0.2109 3.885 0.000419 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Adjusted p values reported -- single-step method)
Effect sizes of \(h^2\) vs. \(H^2\):
beta = -coef(final.model.A)["h2narrow"]
## Equation for H2:
# H2 = e^beta * h2 + 0.2(e^beta - 1))
# h2 = 0.1, H2 = ...
exp(beta) * 0.1 + (0.2*exp(beta)-0.2) h2narrow
0.1936197
# H2 = 0.2006651
# Another way to write it: H2 = m * h2 + b:
# m = 1.33555; b = 0.06711006
h2 <- seq(0.01,0.8,0.01)
H2 <- exp(beta) * h2 + (0.2*exp(beta)-0.2)
plot(H2, h2, type = 'l', xlim = c(0,1))# other way: h2 = (H2 - 0.2(e^beta - 1))*e^(-beta)
# h2 = exp(-beta) * H2 - (0.2(e^beta - 1))*e^(-beta)
# h2 = 0.831158 * H2 -0.0337684
(0.2*exp(beta) - 0.2)*exp(-beta) # -intercept h2narrow
0.04756862
# e.g., H2 = 0.2:
0.748755 * 0.2 -0.05024899[1] 0.09950201
# h2 = 0.1Sub-analysis Di: models of temperature difference (dat_tm subset)
Final and trait x temperature model results
Final model:
final.model.Di
Multivariate Meta-Analysis Model (k = 70; method: REML)
Variance Components:
estim sqrt nlvls fixed factor
sigma^2.1 0.0722 0.2688 12 no study
sigma^2.2 0.0616 0.2482 70 no study/est.id
Test for Residual Heterogeneity:
QE(df = 63) = 343.8923, p-val < .0001
Test of Moderators (coefficients 2:7):
F(df1 = 6, df2 = 63) = 8.0903, p-val < .0001
Model Results:
estimate se tval pval ci.lb ci.ub
intrcpt -0.7526 0.1600 -4.7042 <.0001 -1.0723 -0.4329 ***
traitgrowth 0.0484 0.1488 0.3253 0.7460 -0.2490 0.3458
traitnutrient content 0.1898 0.1764 1.0760 0.2860 -0.1627 0.5422
traitbleaching 0.1699 0.2035 0.8350 0.4069 -0.2367 0.5765
traitimmune response 0.5845 0.1969 2.9681 0.0042 0.1910 0.9780 **
traitsurvival 0.8209 0.1564 5.2501 <.0001 0.5084 1.1334 ***
h2narrow -0.3904 0.2275 -1.7159 0.0911 -0.8451 0.0643 .
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Trait x temp model:
traitxtemp.mod <- rma.mv(yi=val.log ~ trait*temp.s -1,
V=sv.log, random = ~1|study/est.id,
data=dat_tm, method="REML", tdist=T, sigma2 = c(NA, NA))
traitxtemp.mod
Multivariate Meta-Analysis Model (k = 70; method: REML)
Variance Components:
estim sqrt nlvls fixed factor
sigma^2.1 0.0992 0.3149 12 no study
sigma^2.2 0.0405 0.2013 70 no study/est.id
Test for Residual Heterogeneity:
QE(df = 58) = 257.6998, p-val < .0001
Test of Moderators (coefficients 1:12):
F(df1 = 12, df2 = 58) = 8.0738, p-val < .0001
Model Results:
estimate se tval pval ci.lb
traitphotochemistry -0.8284 0.2222 -3.7288 0.0004 -1.2731
traitgrowth -0.7841 0.1606 -4.8822 <.0001 -1.1056
traitnutrient content -0.6782 0.2031 -3.3399 0.0015 -1.0847
traitbleaching -0.3909 0.2627 -1.4879 0.1422 -0.9168
traitimmune response -0.6819 0.2373 -2.8737 0.0057 -1.1568
traitsurvival 0.0307 0.1705 0.1801 0.8577 -0.3105
temp.s -0.0079 0.1345 -0.0585 0.9535 -0.2771
traitgrowth:temp.s -0.0151 0.1586 -0.0951 0.9246 -0.3326
traitnutrient content:temp.s 0.0526 0.1717 0.3062 0.7606 -0.2911
traitbleaching:temp.s -0.2549 0.1976 -1.2902 0.2021 -0.6505
traitimmune response:temp.s 0.5337 0.2023 2.6382 0.0107 0.1288
traitsurvival:temp.s -0.0296 0.1519 -0.1952 0.8459 -0.3336
ci.ub
traitphotochemistry -0.3837 ***
traitgrowth -0.4626 ***
traitnutrient content -0.2717 **
traitbleaching 0.1350
traitimmune response -0.2069 **
traitsurvival 0.3719
temp.s 0.2613
traitgrowth:temp.s 0.3024
traitnutrient content:temp.s 0.3962
traitbleaching:temp.s 0.1406
traitimmune response:temp.s 0.9387 *
traitsurvival:temp.s 0.2743
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Trait + h2 + temp model:
trait.temp.h2.mod <- rma.mv(yi=val.log ~ trait + h2 + temp.s -1,
V=sv.log, random = ~1|study/est.id,
data=dat_tm, method="REML", tdist=T, sigma2 = c(NA, NA))
trait.temp.h2.mod
Multivariate Meta-Analysis Model (k = 70; method: REML)
Variance Components:
estim sqrt nlvls fixed factor
sigma^2.1 0.0706 0.2658 12 no study
sigma^2.2 0.0628 0.2505 70 no study/est.id
Test for Residual Heterogeneity:
QE(df = 62) = 337.3466, p-val < .0001
Test of Moderators (coefficients 1:8):
F(df1 = 8, df2 = 62) = 9.0449, p-val < .0001
Model Results:
estimate se tval pval ci.lb ci.ub
traitphotochemistry -0.7899 0.1733 -4.5571 <.0001 -1.1364 -0.4434 ***
traitgrowth -0.7299 0.1500 -4.8666 <.0001 -1.0297 -0.4301 ***
traitnutrient content -0.6043 0.1877 -3.2201 0.0020 -0.9795 -0.2292 **
traitbleaching -0.6157 0.2032 -3.0297 0.0036 -1.0220 -0.2095 **
traitimmune response -0.2138 0.2159 -0.9901 0.3260 -0.6453 0.2178
traitsurvival 0.0241 0.1607 0.1497 0.8815 -0.2971 0.3452
h2narrow -0.4083 0.2282 -1.7888 0.0785 -0.8645 0.0480 .
temp.s 0.0299 0.0527 0.5672 0.5726 -0.0755 0.1353
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Effect size with +1°C across low, medium, and high heritability:
x <- c(0.1, 0.5, 0.9)
# +1°C:
round(exp( log(x+0.2) +0.01*sqrt(1)) - 0.2, 3)/x[1] 1.030000 1.014000 1.012222
round(exp( log(x+0.2) +0.03*sqrt(3)) - 0.2, 3)/x[1] 1.160000 1.074000 1.065556
Effect sizes for temperature difference
# Effect size of heritability:
dat_tm_traitlevels <- levels(dat_tm$trait)
h2_est <- data.frame(trait=NULL, broad=NULL, narrow=NULL)
for(i in seq_along(dat_tm_traitlevels)) {
final.model.Di %>%
update(.~., data=mutate(dat_tm, trait = fct_relevel(trait, dat_tm_traitlevels[i]))) %>%
summary %>% coef %>%
slice(1) %>%
pull(estimate) %>%
{data.frame(trait=dat_tm_traitlevels[i], broad=round(exp(.) - 0.2,3), narrow=round(exp(.-0.38792173)-0.2,3))} %>%
rbind(h2_est, .) -> h2_est
}
h2_est <- h2_est %>%
mutate(rel.diff = broad/narrow) %>%
arrange(-rel.diff)
write.csv(h2_est, file="Effect size calculations/subDi_trait&h2_mod_est_effsizes.csv", row.names=F)
# Effect size of temperature difference (use intercept to avoid calculating trait-specific slopes:
for(i in seq_along(levels(dat_tm$trait))) {
new.mod <- final.model.Di %>%
update(.~trait*temp.s,
data=mutate(dat_tm,
trait = fct_relevel(trait, levels(dat_tm$trait)[i]))) %>%
summary %>% coef %>%
rownames_to_column("trait")
temp.slope <- filter(new.mod, trait=="temp.s") %>% pull(estimate)
temp_est_new <- new.mod %>%
filter(trait=="intrcpt") %>%
pull(estimate) %>% {data.frame(
trait=dat_tm_traitlevels[i],
h2_0C = exp(. +temp.slope*sqrt(0)) - 0.2,
h2_1C = exp(. +temp.slope*sqrt(1)) - 0.2,
h2_3C = exp(. +temp.slope*sqrt(3)) - 0.2)}
if (i == 1) {temp_est <- temp_est_new} else {temp_est <- rbind(temp_est, temp_est_new)}
}
temp_est| trait | h2_0C | h2_1C | h2_3C |
|---|---|---|---|
| photochemistry | 0.2367350 | 0.2333105 | 0.2308207 |
| growth | 0.2565298 | 0.2461696 | 0.2387348 |
| nutrient content | 0.3075216 | 0.3307204 | 0.3483726 |
| bleaching | 0.4764549 | 0.3201151 | 0.2290853 |
| immune response | 0.3056713 | 0.6555619 | 1.0573017 |
| survival | 0.8311815 | 0.7932150 | 0.7663107 |
# write.csv(temp_est, file="Model Estimates/subDi_traitxtemp.s_mod_est.csv", row.names=F)Calculate relative effect sizes by each trait, with an increase in manipulated temperature of 0C, +1C, and +3°C:
temp_est_effsizes <- temp_est %>%
mutate(plus1_diff = ifelse(h2_1C>h2_0C,
h2_1C/h2_0C, -1+h2_1C/h2_0C),
plus3_diff = ifelse(h2_3C>h2_1C,
h2_3C/h2_1C, -1+h2_3C/h2_1C))
temp_est_effsizes| trait | h2_0C | h2_1C | h2_3C | plus1_diff | plus3_diff |
|---|---|---|---|---|---|
| photochemistry | 0.2367350 | 0.2333105 | 0.2308207 | -0.0144653 | -0.0106718 |
| growth | 0.2565298 | 0.2461696 | 0.2387348 | -0.0403857 | -0.0302019 |
| nutrient content | 0.3075216 | 0.3307204 | 0.3483726 | 1.0754378 | 1.0533751 |
| bleaching | 0.4764549 | 0.3201151 | 0.2290853 | -0.3281313 | -0.2843658 |
| immune response | 0.3056713 | 0.6555619 | 1.0573017 | 2.1446630 | 1.6128175 |
| survival | 0.8311815 | 0.7932150 | 0.7663107 | -0.0456778 | -0.0339180 |
write.csv(temp_est_effsizes, file = "Effect size calculations/subDi_traitxtemp.s_mod_est_effsizes.csv", row.names=F)