├── 02_Run ├── .Rprofile ├── renv │ ├── .gitignore │ └── settings.json ├── .gitignore ├── 02_Run.Rproj ├── _src │ ├── env_CatFoodExp2021_analysis.txt │ └── env_PopDyn_analysis.txt ├── README.md ├── 1_data │ └── README.md └── 2_scripts │ └── 1a_CatFoodExp2021_analysis_fitness.R ├── 01_Reported ├── .Rprofile ├── renv │ ├── .gitignore │ └── settings.json ├── .gitignore ├── _src │ ├── env_CatFoodExp2021_analysis.txt │ └── env_PopDyn_analysis.txt ├── README.md ├── 1_data │ ├── README_data.md │ └── README.md └── 2_scripts │ └── 1a_CatFoodExp2021_analysis_fitness.R ├── 03_Reliable ├── .Rprofile ├── renv │ ├── .gitignore │ └── settings.json ├── .gitignore ├── 03_Reliable.Rproj ├── _src │ ├── env_CatFoodExp2021_analysis.txt │ └── env_PopDyn_analysis.txt ├── README.md ├── 1_data │ └── README.md └── 2_scripts │ └── 1a_CatFoodExp2021_analysis_fitness.R ├── 04_Reproducible ├── .Rprofile ├── renv │ ├── .gitignore │ └── settings.json ├── .gitignore ├── 04_Reproducible.Rproj ├── _src │ ├── env_CatFoodExp2021_analysis.txt │ └── env_PopDyn_analysis.txt ├── README.md ├── 1_data │ └── README.md └── 2_scripts │ └── 1a_CatFoodExp2021_analysis_fitness.R ├── 06_Other_considerations ├── .Rprofile ├── renv │ ├── .gitignore │ └── settings.json ├── .gitignore ├── 06_Other_considerations.Rproj ├── _src │ ├── env_CatFoodExp2021_analysis.txt │ └── env_PopDyn_analysis.txt ├── README.md ├── 1_data │ └── README.md └── 2_scripts │ └── 1a_CatFoodExp2021_analysis_fitness.R ├── 05_Organization_Structure ├── .Rprofile ├── renv │ ├── .gitignore │ └── settings.json ├── .gitignore ├── 05_Organization_Structure.Rproj ├── _src │ ├── env_CatFoodExp2021_analysis.txt │ └── env_PopDyn_analysis.txt ├── README.md ├── 1_data │ └── README.md └── 2_scripts │ └── 1a_CatFoodExp2021_analysis_fitness.R ├── .gitignore └── README.md /02_Run/.Rprofile: -------------------------------------------------------------------------------- 1 | source("renv/activate.R") 2 | -------------------------------------------------------------------------------- /01_Reported/.Rprofile: -------------------------------------------------------------------------------- 1 | source("renv/activate.R") 2 | -------------------------------------------------------------------------------- /03_Reliable/.Rprofile: -------------------------------------------------------------------------------- 1 | source("renv/activate.R") 2 | -------------------------------------------------------------------------------- /04_Reproducible/.Rprofile: -------------------------------------------------------------------------------- 1 | source("renv/activate.R") 2 | -------------------------------------------------------------------------------- /06_Other_considerations/.Rprofile: -------------------------------------------------------------------------------- 1 | source("renv/activate.R") 2 | -------------------------------------------------------------------------------- /05_Organization_Structure/.Rprofile: -------------------------------------------------------------------------------- 1 | source("renv/activate.R") 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.Rproj 2 | .Rproj.user/ 3 | .Rhistory 4 | .RData 5 | .Ruserdata 6 | -------------------------------------------------------------------------------- /02_Run/renv/.gitignore: -------------------------------------------------------------------------------- 1 | library/ 2 | local/ 3 | cellar/ 4 | lock/ 5 | python/ 6 | sandbox/ 7 | staging/ 8 | -------------------------------------------------------------------------------- /01_Reported/renv/.gitignore: -------------------------------------------------------------------------------- 1 | library/ 2 | local/ 3 | cellar/ 4 | lock/ 5 | python/ 6 | sandbox/ 7 | staging/ 8 | -------------------------------------------------------------------------------- /03_Reliable/renv/.gitignore: -------------------------------------------------------------------------------- 1 | library/ 2 | local/ 3 | cellar/ 4 | lock/ 5 | python/ 6 | sandbox/ 7 | staging/ 8 | -------------------------------------------------------------------------------- /02_Run/.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | *.DS_Store 6 | 7 | 1_data/*.csv 8 | 9 | -------------------------------------------------------------------------------- /04_Reproducible/renv/.gitignore: -------------------------------------------------------------------------------- 1 | library/ 2 | local/ 3 | cellar/ 4 | lock/ 5 | python/ 6 | sandbox/ 7 | staging/ 8 | -------------------------------------------------------------------------------- /01_Reported/.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | *.DS_Store 6 | 7 | 1_data/*.csv 8 | 9 | -------------------------------------------------------------------------------- /03_Reliable/.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | *.DS_Store 6 | 7 | 1_data/*.csv 8 | 9 | -------------------------------------------------------------------------------- /06_Other_considerations/renv/.gitignore: -------------------------------------------------------------------------------- 1 | library/ 2 | local/ 3 | cellar/ 4 | lock/ 5 | python/ 6 | sandbox/ 7 | staging/ 8 | -------------------------------------------------------------------------------- /04_Reproducible/.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | *.DS_Store 6 | 7 | 1_data/*.csv 8 | 9 | -------------------------------------------------------------------------------- /05_Organization_Structure/renv/.gitignore: -------------------------------------------------------------------------------- 1 | library/ 2 | local/ 3 | cellar/ 4 | lock/ 5 | python/ 6 | sandbox/ 7 | staging/ 8 | -------------------------------------------------------------------------------- /06_Other_considerations/.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | *.DS_Store 6 | 7 | 1_data/*.csv 8 | 9 | -------------------------------------------------------------------------------- /05_Organization_Structure/.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | *.DS_Store 6 | 7 | 1_data/*.csv 8 | 9 | -------------------------------------------------------------------------------- /02_Run/02_Run.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /03_Reliable/03_Reliable.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /04_Reproducible/04_Reproducible.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /05_Organization_Structure/05_Organization_Structure.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /06_Other_considerations/06_Other_considerations.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | -------------------------------------------------------------------------------- /02_Run/renv/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "bioconductor.version": null, 3 | "external.libraries": [], 4 | "ignored.packages": [], 5 | "package.dependency.fields": [ 6 | "Imports", 7 | "Depends", 8 | "LinkingTo" 9 | ], 10 | "ppm.enabled": null, 11 | "ppm.ignored.urls": [], 12 | "r.version": null, 13 | "snapshot.type": "implicit", 14 | "use.cache": true, 15 | "vcs.ignore.cellar": true, 16 | "vcs.ignore.library": true, 17 | "vcs.ignore.local": true, 18 | "vcs.manage.ignores": true 19 | } 20 | -------------------------------------------------------------------------------- /01_Reported/renv/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "bioconductor.version": null, 3 | "external.libraries": [], 4 | "ignored.packages": [], 5 | "package.dependency.fields": [ 6 | "Imports", 7 | "Depends", 8 | "LinkingTo" 9 | ], 10 | "ppm.enabled": null, 11 | "ppm.ignored.urls": [], 12 | "r.version": null, 13 | "snapshot.type": "implicit", 14 | "use.cache": true, 15 | "vcs.ignore.cellar": true, 16 | "vcs.ignore.library": true, 17 | "vcs.ignore.local": true, 18 | "vcs.manage.ignores": true 19 | } 20 | -------------------------------------------------------------------------------- /03_Reliable/renv/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "bioconductor.version": null, 3 | "external.libraries": [], 4 | "ignored.packages": [], 5 | "package.dependency.fields": [ 6 | "Imports", 7 | "Depends", 8 | "LinkingTo" 9 | ], 10 | "ppm.enabled": null, 11 | "ppm.ignored.urls": [], 12 | "r.version": null, 13 | "snapshot.type": "implicit", 14 | "use.cache": true, 15 | "vcs.ignore.cellar": true, 16 | "vcs.ignore.library": true, 17 | "vcs.ignore.local": true, 18 | "vcs.manage.ignores": true 19 | } 20 | -------------------------------------------------------------------------------- /04_Reproducible/renv/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "bioconductor.version": null, 3 | "external.libraries": [], 4 | "ignored.packages": [], 5 | "package.dependency.fields": [ 6 | "Imports", 7 | "Depends", 8 | "LinkingTo" 9 | ], 10 | "ppm.enabled": null, 11 | "ppm.ignored.urls": [], 12 | "r.version": null, 13 | "snapshot.type": "implicit", 14 | "use.cache": true, 15 | "vcs.ignore.cellar": true, 16 | "vcs.ignore.library": true, 17 | "vcs.ignore.local": true, 18 | "vcs.manage.ignores": true 19 | } 20 | -------------------------------------------------------------------------------- /05_Organization_Structure/renv/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "bioconductor.version": null, 3 | "external.libraries": [], 4 | "ignored.packages": [], 5 | "package.dependency.fields": [ 6 | "Imports", 7 | "Depends", 8 | "LinkingTo" 9 | ], 10 | "ppm.enabled": null, 11 | "ppm.ignored.urls": [], 12 | "r.version": null, 13 | "snapshot.type": "implicit", 14 | "use.cache": true, 15 | "vcs.ignore.cellar": true, 16 | "vcs.ignore.library": true, 17 | "vcs.ignore.local": true, 18 | "vcs.manage.ignores": true 19 | } 20 | -------------------------------------------------------------------------------- /06_Other_considerations/renv/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "bioconductor.version": null, 3 | "external.libraries": [], 4 | "ignored.packages": [], 5 | "package.dependency.fields": [ 6 | "Imports", 7 | "Depends", 8 | "LinkingTo" 9 | ], 10 | "ppm.enabled": null, 11 | "ppm.ignored.urls": [], 12 | "r.version": null, 13 | "snapshot.type": "implicit", 14 | "use.cache": true, 15 | "vcs.ignore.cellar": true, 16 | "vcs.ignore.library": true, 17 | "vcs.ignore.local": true, 18 | "vcs.manage.ignores": true 19 | } 20 | -------------------------------------------------------------------------------- /02_Run/_src/env_CatFoodExp2021_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 coxme_2.2-17 bdsmatrix_1.3-6 survival_3.2-13 cowplot_1.1.1 readxl_1.3.1 16 | [9] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 ggplot2_3.3.5 17 | [17] tidyverse_1.3.1 18 | 19 | loaded via a namespace (and not attached): 20 | [1] httr_1.4.2 jsonlite_1.8.0 splines_4.1.2 carData_3.0-5 modelr_0.1.8 assertthat_0.2.1 21 | [7] cellranger_1.1.0 numDeriv_2016.8-1.1 pillar_1.7.0 backports_1.4.1 lattice_0.20-45 glue_1.6.2 22 | [13] digest_0.6.29 ggsignif_0.6.3 rvest_1.0.2 minqa_1.2.4 colorspace_2.0-3 plyr_1.8.7 23 | [19] pkgconfig_2.0.3 broom_0.7.12 haven_2.4.3 mvtnorm_1.1-3 xtable_1.8-4 scales_1.1.1 24 | [25] km.ci_0.5-6 KMsurv_0.1-5 tzdb_0.2.0 emmeans_1.7.5 mgcv_1.8-38 farver_2.1.0 25 | [31] generics_0.1.2 car_3.0-12 ellipsis_0.3.2 ggpubr_0.4.0 withr_2.5.0 cli_3.2.0 26 | [37] magrittr_2.0.2 crayon_1.5.1 estimability_1.4 fs_1.5.2 fansi_1.0.3 nlme_3.1-153 27 | [43] MASS_7.3-54 rstatix_0.7.0 xml2_1.3.3 tools_4.1.2 data.table_1.14.2 hms_1.1.1 28 | [49] lifecycle_1.0.1 munsell_0.5.0 reprex_2.0.1 compiler_4.1.2 survminer_0.4.9 rlang_1.0.2 29 | [55] grid_4.1.2 nloptr_2.0.0 rstudioapi_0.13 Rmisc_1.5.1 labeling_0.4.2 boot_1.3-28 30 | [61] gtable_0.3.0 abind_1.4-5 DBI_1.1.2 R6_2.5.1 gridExtra_2.3 zoo_1.8-10 31 | [67] lubridate_1.8.0 knitr_1.38 survMisc_0.5.6 utf8_1.2.2 stringi_1.7.6 Rcpp_1.0.8.3 32 | [73] vctrs_0.3.8 dbplyr_2.1.1 tidyselect_1.1.2 xfun_0.30 33 | -------------------------------------------------------------------------------- /01_Reported/_src/env_CatFoodExp2021_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 coxme_2.2-17 bdsmatrix_1.3-6 survival_3.2-13 cowplot_1.1.1 readxl_1.3.1 16 | [9] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 ggplot2_3.3.5 17 | [17] tidyverse_1.3.1 18 | 19 | loaded via a namespace (and not attached): 20 | [1] httr_1.4.2 jsonlite_1.8.0 splines_4.1.2 carData_3.0-5 modelr_0.1.8 assertthat_0.2.1 21 | [7] cellranger_1.1.0 numDeriv_2016.8-1.1 pillar_1.7.0 backports_1.4.1 lattice_0.20-45 glue_1.6.2 22 | [13] digest_0.6.29 ggsignif_0.6.3 rvest_1.0.2 minqa_1.2.4 colorspace_2.0-3 plyr_1.8.7 23 | [19] pkgconfig_2.0.3 broom_0.7.12 haven_2.4.3 mvtnorm_1.1-3 xtable_1.8-4 scales_1.1.1 24 | [25] km.ci_0.5-6 KMsurv_0.1-5 tzdb_0.2.0 emmeans_1.7.5 mgcv_1.8-38 farver_2.1.0 25 | [31] generics_0.1.2 car_3.0-12 ellipsis_0.3.2 ggpubr_0.4.0 withr_2.5.0 cli_3.2.0 26 | [37] magrittr_2.0.2 crayon_1.5.1 estimability_1.4 fs_1.5.2 fansi_1.0.3 nlme_3.1-153 27 | [43] MASS_7.3-54 rstatix_0.7.0 xml2_1.3.3 tools_4.1.2 data.table_1.14.2 hms_1.1.1 28 | [49] lifecycle_1.0.1 munsell_0.5.0 reprex_2.0.1 compiler_4.1.2 survminer_0.4.9 rlang_1.0.2 29 | [55] grid_4.1.2 nloptr_2.0.0 rstudioapi_0.13 Rmisc_1.5.1 labeling_0.4.2 boot_1.3-28 30 | [61] gtable_0.3.0 abind_1.4-5 DBI_1.1.2 R6_2.5.1 gridExtra_2.3 zoo_1.8-10 31 | [67] lubridate_1.8.0 knitr_1.38 survMisc_0.5.6 utf8_1.2.2 stringi_1.7.6 Rcpp_1.0.8.3 32 | [73] vctrs_0.3.8 dbplyr_2.1.1 tidyselect_1.1.2 xfun_0.30 33 | -------------------------------------------------------------------------------- /03_Reliable/_src/env_CatFoodExp2021_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 coxme_2.2-17 bdsmatrix_1.3-6 survival_3.2-13 cowplot_1.1.1 readxl_1.3.1 16 | [9] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 ggplot2_3.3.5 17 | [17] tidyverse_1.3.1 18 | 19 | loaded via a namespace (and not attached): 20 | [1] httr_1.4.2 jsonlite_1.8.0 splines_4.1.2 carData_3.0-5 modelr_0.1.8 assertthat_0.2.1 21 | [7] cellranger_1.1.0 numDeriv_2016.8-1.1 pillar_1.7.0 backports_1.4.1 lattice_0.20-45 glue_1.6.2 22 | [13] digest_0.6.29 ggsignif_0.6.3 rvest_1.0.2 minqa_1.2.4 colorspace_2.0-3 plyr_1.8.7 23 | [19] pkgconfig_2.0.3 broom_0.7.12 haven_2.4.3 mvtnorm_1.1-3 xtable_1.8-4 scales_1.1.1 24 | [25] km.ci_0.5-6 KMsurv_0.1-5 tzdb_0.2.0 emmeans_1.7.5 mgcv_1.8-38 farver_2.1.0 25 | [31] generics_0.1.2 car_3.0-12 ellipsis_0.3.2 ggpubr_0.4.0 withr_2.5.0 cli_3.2.0 26 | [37] magrittr_2.0.2 crayon_1.5.1 estimability_1.4 fs_1.5.2 fansi_1.0.3 nlme_3.1-153 27 | [43] MASS_7.3-54 rstatix_0.7.0 xml2_1.3.3 tools_4.1.2 data.table_1.14.2 hms_1.1.1 28 | [49] lifecycle_1.0.1 munsell_0.5.0 reprex_2.0.1 compiler_4.1.2 survminer_0.4.9 rlang_1.0.2 29 | [55] grid_4.1.2 nloptr_2.0.0 rstudioapi_0.13 Rmisc_1.5.1 labeling_0.4.2 boot_1.3-28 30 | [61] gtable_0.3.0 abind_1.4-5 DBI_1.1.2 R6_2.5.1 gridExtra_2.3 zoo_1.8-10 31 | [67] lubridate_1.8.0 knitr_1.38 survMisc_0.5.6 utf8_1.2.2 stringi_1.7.6 Rcpp_1.0.8.3 32 | [73] vctrs_0.3.8 dbplyr_2.1.1 tidyselect_1.1.2 xfun_0.30 33 | -------------------------------------------------------------------------------- /04_Reproducible/_src/env_CatFoodExp2021_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 coxme_2.2-17 bdsmatrix_1.3-6 survival_3.2-13 cowplot_1.1.1 readxl_1.3.1 16 | [9] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 ggplot2_3.3.5 17 | [17] tidyverse_1.3.1 18 | 19 | loaded via a namespace (and not attached): 20 | [1] httr_1.4.2 jsonlite_1.8.0 splines_4.1.2 carData_3.0-5 modelr_0.1.8 assertthat_0.2.1 21 | [7] cellranger_1.1.0 numDeriv_2016.8-1.1 pillar_1.7.0 backports_1.4.1 lattice_0.20-45 glue_1.6.2 22 | [13] digest_0.6.29 ggsignif_0.6.3 rvest_1.0.2 minqa_1.2.4 colorspace_2.0-3 plyr_1.8.7 23 | [19] pkgconfig_2.0.3 broom_0.7.12 haven_2.4.3 mvtnorm_1.1-3 xtable_1.8-4 scales_1.1.1 24 | [25] km.ci_0.5-6 KMsurv_0.1-5 tzdb_0.2.0 emmeans_1.7.5 mgcv_1.8-38 farver_2.1.0 25 | [31] generics_0.1.2 car_3.0-12 ellipsis_0.3.2 ggpubr_0.4.0 withr_2.5.0 cli_3.2.0 26 | [37] magrittr_2.0.2 crayon_1.5.1 estimability_1.4 fs_1.5.2 fansi_1.0.3 nlme_3.1-153 27 | [43] MASS_7.3-54 rstatix_0.7.0 xml2_1.3.3 tools_4.1.2 data.table_1.14.2 hms_1.1.1 28 | [49] lifecycle_1.0.1 munsell_0.5.0 reprex_2.0.1 compiler_4.1.2 survminer_0.4.9 rlang_1.0.2 29 | [55] grid_4.1.2 nloptr_2.0.0 rstudioapi_0.13 Rmisc_1.5.1 labeling_0.4.2 boot_1.3-28 30 | [61] gtable_0.3.0 abind_1.4-5 DBI_1.1.2 R6_2.5.1 gridExtra_2.3 zoo_1.8-10 31 | [67] lubridate_1.8.0 knitr_1.38 survMisc_0.5.6 utf8_1.2.2 stringi_1.7.6 Rcpp_1.0.8.3 32 | [73] vctrs_0.3.8 dbplyr_2.1.1 tidyselect_1.1.2 xfun_0.30 33 | -------------------------------------------------------------------------------- /02_Run/README.md: -------------------------------------------------------------------------------- 1 | *This is a partial copy from the [original repository](https://github.com/NEvanDis/WM_fitness), made for the Hackathon. 2 | We kept all the repository the same, except the script folder. There you find only the script `1a_CatFoodExp2021_analysis_fitness.R` which is our focus in the hackathon.* 3 | 4 | 5 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8276288.svg)](https://doi.org/10.5281/zenodo.8276288) Version of record scripts 6 | 7 | # Winter moth individual fitness and population growth 8 | This folder contains all the scripts needed to reproduce the analysis of experimental and field winter moth data belonging to manuscript _Phenological mismatch affects individual fitness and population growth in the winter moth_, published in Proc Roy Soc B: https://doi.org/10.1098/rspb.2023.0414 9 | 10 | **NB: The raw data, including both experimental data and field data, can be found on Dryad https://doi.org/10.5061/dryad.m905qfv5p** 11 | 12 |   13 | 14 | ## Authors 15 | Natalie E. van Dis, ORCID ID: 0000-0002-9934-6751 16 | 17 |   18 | 19 | ## Analysis and visualization of Experimental data 20 | R scripts to reproduce the analysis and visualization (incl. manuscript figures) of the 2021 winter moth caterpillar feeding experiment: 21 | 22 | ### Script: ```2_scripts/1a_CatFoodExp2021_analysis_fitness.R ``` 23 | (1) What are the fitness consequences of day to day timing (a)synchrony with budburst? 24 | 25 | ### Script: ```2_scripts/1b_CatFoodExp2021_analysis_devtime.R ``` 26 | (2) Can food quality affect the timing of life stages? 27 | 28 | ### Script: ```2_scripts/suppl_pupaweight_proxy.R ``` 29 | Supplemental: Is pupation weight a good proxy for fecundity? 30 | 31 | See ```_src/env_CatFoodExp2021_analysis.txt``` for used R package versions. 32 | 33 |   34 | 35 | ## Analysis and visualization of long-term Field data 36 | ### Script: ```2_scripts/2_prep_FieldData.R ``` 37 | R script to get trapping effort descriptives and to prep all the field data for analysis. 38 | 39 | ### Script: ```2_scripts/3_plot_popnum.R ``` 40 | R script to reproduce the manuscript figure that visualizes winter moth population dynamics and population phenological mismatch over time (1993-2021) at four locations in the Netherlands. 41 | 42 | ### Script: ```2_scripts/4_popdyn_analysis.R ``` 43 | R script to reproduce the analysis of winter moth population dynamics: how much variation in population growth can be explained by timing mismatch? 44 | 45 | See ```_src/env_PopDyn_analysis.txt``` for used R package versions. 46 | -------------------------------------------------------------------------------- /05_Organization_Structure/_src/env_CatFoodExp2021_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 coxme_2.2-17 bdsmatrix_1.3-6 survival_3.2-13 cowplot_1.1.1 readxl_1.3.1 16 | [9] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 ggplot2_3.3.5 17 | [17] tidyverse_1.3.1 18 | 19 | loaded via a namespace (and not attached): 20 | [1] httr_1.4.2 jsonlite_1.8.0 splines_4.1.2 carData_3.0-5 modelr_0.1.8 assertthat_0.2.1 21 | [7] cellranger_1.1.0 numDeriv_2016.8-1.1 pillar_1.7.0 backports_1.4.1 lattice_0.20-45 glue_1.6.2 22 | [13] digest_0.6.29 ggsignif_0.6.3 rvest_1.0.2 minqa_1.2.4 colorspace_2.0-3 plyr_1.8.7 23 | [19] pkgconfig_2.0.3 broom_0.7.12 haven_2.4.3 mvtnorm_1.1-3 xtable_1.8-4 scales_1.1.1 24 | [25] km.ci_0.5-6 KMsurv_0.1-5 tzdb_0.2.0 emmeans_1.7.5 mgcv_1.8-38 farver_2.1.0 25 | [31] generics_0.1.2 car_3.0-12 ellipsis_0.3.2 ggpubr_0.4.0 withr_2.5.0 cli_3.2.0 26 | [37] magrittr_2.0.2 crayon_1.5.1 estimability_1.4 fs_1.5.2 fansi_1.0.3 nlme_3.1-153 27 | [43] MASS_7.3-54 rstatix_0.7.0 xml2_1.3.3 tools_4.1.2 data.table_1.14.2 hms_1.1.1 28 | [49] lifecycle_1.0.1 munsell_0.5.0 reprex_2.0.1 compiler_4.1.2 survminer_0.4.9 rlang_1.0.2 29 | [55] grid_4.1.2 nloptr_2.0.0 rstudioapi_0.13 Rmisc_1.5.1 labeling_0.4.2 boot_1.3-28 30 | [61] gtable_0.3.0 abind_1.4-5 DBI_1.1.2 R6_2.5.1 gridExtra_2.3 zoo_1.8-10 31 | [67] lubridate_1.8.0 knitr_1.38 survMisc_0.5.6 utf8_1.2.2 stringi_1.7.6 Rcpp_1.0.8.3 32 | [73] vctrs_0.3.8 dbplyr_2.1.1 tidyselect_1.1.2 xfun_0.30 33 | -------------------------------------------------------------------------------- /06_Other_considerations/_src/env_CatFoodExp2021_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 coxme_2.2-17 bdsmatrix_1.3-6 survival_3.2-13 cowplot_1.1.1 readxl_1.3.1 16 | [9] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 ggplot2_3.3.5 17 | [17] tidyverse_1.3.1 18 | 19 | loaded via a namespace (and not attached): 20 | [1] httr_1.4.2 jsonlite_1.8.0 splines_4.1.2 carData_3.0-5 modelr_0.1.8 assertthat_0.2.1 21 | [7] cellranger_1.1.0 numDeriv_2016.8-1.1 pillar_1.7.0 backports_1.4.1 lattice_0.20-45 glue_1.6.2 22 | [13] digest_0.6.29 ggsignif_0.6.3 rvest_1.0.2 minqa_1.2.4 colorspace_2.0-3 plyr_1.8.7 23 | [19] pkgconfig_2.0.3 broom_0.7.12 haven_2.4.3 mvtnorm_1.1-3 xtable_1.8-4 scales_1.1.1 24 | [25] km.ci_0.5-6 KMsurv_0.1-5 tzdb_0.2.0 emmeans_1.7.5 mgcv_1.8-38 farver_2.1.0 25 | [31] generics_0.1.2 car_3.0-12 ellipsis_0.3.2 ggpubr_0.4.0 withr_2.5.0 cli_3.2.0 26 | [37] magrittr_2.0.2 crayon_1.5.1 estimability_1.4 fs_1.5.2 fansi_1.0.3 nlme_3.1-153 27 | [43] MASS_7.3-54 rstatix_0.7.0 xml2_1.3.3 tools_4.1.2 data.table_1.14.2 hms_1.1.1 28 | [49] lifecycle_1.0.1 munsell_0.5.0 reprex_2.0.1 compiler_4.1.2 survminer_0.4.9 rlang_1.0.2 29 | [55] grid_4.1.2 nloptr_2.0.0 rstudioapi_0.13 Rmisc_1.5.1 labeling_0.4.2 boot_1.3-28 30 | [61] gtable_0.3.0 abind_1.4-5 DBI_1.1.2 R6_2.5.1 gridExtra_2.3 zoo_1.8-10 31 | [67] lubridate_1.8.0 knitr_1.38 survMisc_0.5.6 utf8_1.2.2 stringi_1.7.6 Rcpp_1.0.8.3 32 | [73] vctrs_0.3.8 dbplyr_2.1.1 tidyselect_1.1.2 xfun_0.30 33 | -------------------------------------------------------------------------------- /01_Reported/README.md: -------------------------------------------------------------------------------- 1 | *This is a partial copy from the [original repository](https://github.com/NEvanDis/WM_fitness), made for the Hackathon. 2 | We kept all the repository the same, except the script folder. There you find only the script `1a_CatFoodExp2021_analysis_fitness.R` which is our focus in the hackathon.* 3 | 4 | 5 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8276288.svg)](https://doi.org/10.5281/zenodo.8276288) Version of record scripts 6 | 7 | # Winter moth individual fitness and population growth 8 | This folder contains all the scripts needed to reproduce the analysis of experimental and field winter moth data belonging to manuscript _Phenological mismatch affects individual fitness and population growth in the winter moth_, published in Proc Roy Soc B: https://doi.org/10.1098/rspb.2023.0414 9 | 10 | **NB: The raw data, including both experimental data and field data, can be found on Dryad https://doi.org/10.5061/dryad.m905qfv5p** 11 | 12 |   13 | 14 | ## Authors 15 | Natalie E. van Dis, ORCID ID: 0000-0002-9934-6751 16 | 17 |   18 | 19 | ## Analysis and visualization of Experimental data 20 | R scripts to reproduce the analysis and visualization (incl. manuscript figures) of the 2021 winter moth caterpillar feeding experiment: 21 | 22 | ### Script: ```2_scripts/1a_CatFoodExp2021_analysis_fitness.R ``` 23 | (1) What are the fitness consequences of day to day timing (a)synchrony with budburst? 24 | 25 | ### Script: ```2_scripts/1b_CatFoodExp2021_analysis_devtime.R ``` 26 | (2) Can food quality affect the timing of life stages? 27 | 28 | ### Script: ```2_scripts/suppl_pupaweight_proxy.R ``` 29 | Supplemental: Is pupation weight a good proxy for fecundity? 30 | 31 | See ```_src/env_CatFoodExp2021_analysis.txt``` for used R package versions. 32 | 33 |   34 | 35 | ## Analysis and visualization of long-term Field data 36 | ### Script: ```2_scripts/2_prep_FieldData.R ``` 37 | R script to get trapping effort descriptives and to prep all the field data for analysis. 38 | 39 | ### Script: ```2_scripts/3_plot_popnum.R ``` 40 | R script to reproduce the manuscript figure that visualizes winter moth population dynamics and population phenological mismatch over time (1993-2021) at four locations in the Netherlands. 41 | 42 | ### Script: ```2_scripts/4_popdyn_analysis.R ``` 43 | R script to reproduce the analysis of winter moth population dynamics: how much variation in population growth can be explained by timing mismatch? 44 | 45 | See ```_src/env_PopDyn_analysis.txt``` for used R package versions. 46 | -------------------------------------------------------------------------------- /03_Reliable/README.md: -------------------------------------------------------------------------------- 1 | *This is a partial copy from the [original repository](https://github.com/NEvanDis/WM_fitness), made for the Hackathon. 2 | We kept all the repository the same, except the script folder. There you find only the script `1a_CatFoodExp2021_analysis_fitness.R` which is our focus in the hackathon.* 3 | 4 | 5 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8276288.svg)](https://doi.org/10.5281/zenodo.8276288) Version of record scripts 6 | 7 | # Winter moth individual fitness and population growth 8 | This folder contains all the scripts needed to reproduce the analysis of experimental and field winter moth data belonging to manuscript _Phenological mismatch affects individual fitness and population growth in the winter moth_, published in Proc Roy Soc B: https://doi.org/10.1098/rspb.2023.0414 9 | 10 | **NB: The raw data, including both experimental data and field data, can be found on Dryad https://doi.org/10.5061/dryad.m905qfv5p** 11 | 12 |   13 | 14 | ## Authors 15 | Natalie E. van Dis, ORCID ID: 0000-0002-9934-6751 16 | 17 |   18 | 19 | ## Analysis and visualization of Experimental data 20 | R scripts to reproduce the analysis and visualization (incl. manuscript figures) of the 2021 winter moth caterpillar feeding experiment: 21 | 22 | ### Script: ```2_scripts/1a_CatFoodExp2021_analysis_fitness.R ``` 23 | (1) What are the fitness consequences of day to day timing (a)synchrony with budburst? 24 | 25 | ### Script: ```2_scripts/1b_CatFoodExp2021_analysis_devtime.R ``` 26 | (2) Can food quality affect the timing of life stages? 27 | 28 | ### Script: ```2_scripts/suppl_pupaweight_proxy.R ``` 29 | Supplemental: Is pupation weight a good proxy for fecundity? 30 | 31 | See ```_src/env_CatFoodExp2021_analysis.txt``` for used R package versions. 32 | 33 |   34 | 35 | ## Analysis and visualization of long-term Field data 36 | ### Script: ```2_scripts/2_prep_FieldData.R ``` 37 | R script to get trapping effort descriptives and to prep all the field data for analysis. 38 | 39 | ### Script: ```2_scripts/3_plot_popnum.R ``` 40 | R script to reproduce the manuscript figure that visualizes winter moth population dynamics and population phenological mismatch over time (1993-2021) at four locations in the Netherlands. 41 | 42 | ### Script: ```2_scripts/4_popdyn_analysis.R ``` 43 | R script to reproduce the analysis of winter moth population dynamics: how much variation in population growth can be explained by timing mismatch? 44 | 45 | See ```_src/env_PopDyn_analysis.txt``` for used R package versions. 46 | -------------------------------------------------------------------------------- /04_Reproducible/README.md: -------------------------------------------------------------------------------- 1 | *This is a partial copy from the [original repository](https://github.com/NEvanDis/WM_fitness), made for the Hackathon. 2 | We kept all the repository the same, except the script folder. There you find only the script `1a_CatFoodExp2021_analysis_fitness.R` which is our focus in the hackathon.* 3 | 4 | 5 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8276288.svg)](https://doi.org/10.5281/zenodo.8276288) Version of record scripts 6 | 7 | # Winter moth individual fitness and population growth 8 | This folder contains all the scripts needed to reproduce the analysis of experimental and field winter moth data belonging to manuscript _Phenological mismatch affects individual fitness and population growth in the winter moth_, published in Proc Roy Soc B: https://doi.org/10.1098/rspb.2023.0414 9 | 10 | **NB: The raw data, including both experimental data and field data, can be found on Dryad https://doi.org/10.5061/dryad.m905qfv5p** 11 | 12 |   13 | 14 | ## Authors 15 | Natalie E. van Dis, ORCID ID: 0000-0002-9934-6751 16 | 17 |   18 | 19 | ## Analysis and visualization of Experimental data 20 | R scripts to reproduce the analysis and visualization (incl. manuscript figures) of the 2021 winter moth caterpillar feeding experiment: 21 | 22 | ### Script: ```2_scripts/1a_CatFoodExp2021_analysis_fitness.R ``` 23 | (1) What are the fitness consequences of day to day timing (a)synchrony with budburst? 24 | 25 | ### Script: ```2_scripts/1b_CatFoodExp2021_analysis_devtime.R ``` 26 | (2) Can food quality affect the timing of life stages? 27 | 28 | ### Script: ```2_scripts/suppl_pupaweight_proxy.R ``` 29 | Supplemental: Is pupation weight a good proxy for fecundity? 30 | 31 | See ```_src/env_CatFoodExp2021_analysis.txt``` for used R package versions. 32 | 33 |   34 | 35 | ## Analysis and visualization of long-term Field data 36 | ### Script: ```2_scripts/2_prep_FieldData.R ``` 37 | R script to get trapping effort descriptives and to prep all the field data for analysis. 38 | 39 | ### Script: ```2_scripts/3_plot_popnum.R ``` 40 | R script to reproduce the manuscript figure that visualizes winter moth population dynamics and population phenological mismatch over time (1993-2021) at four locations in the Netherlands. 41 | 42 | ### Script: ```2_scripts/4_popdyn_analysis.R ``` 43 | R script to reproduce the analysis of winter moth population dynamics: how much variation in population growth can be explained by timing mismatch? 44 | 45 | See ```_src/env_PopDyn_analysis.txt``` for used R package versions. 46 | -------------------------------------------------------------------------------- /06_Other_considerations/README.md: -------------------------------------------------------------------------------- 1 | *This is a partial copy from the [original repository](https://github.com/NEvanDis/WM_fitness), made for the Hackathon. 2 | We kept all the repository the same, except the script folder. There you find only the script `1a_CatFoodExp2021_analysis_fitness.R` which is our focus in the hackathon.* 3 | 4 | 5 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8276288.svg)](https://doi.org/10.5281/zenodo.8276288) Version of record scripts 6 | 7 | # Winter moth individual fitness and population growth 8 | This folder contains all the scripts needed to reproduce the analysis of experimental and field winter moth data belonging to manuscript _Phenological mismatch affects individual fitness and population growth in the winter moth_, published in Proc Roy Soc B: https://doi.org/10.1098/rspb.2023.0414 9 | 10 | **NB: The raw data, including both experimental data and field data, can be found on Dryad https://doi.org/10.5061/dryad.m905qfv5p** 11 | 12 |   13 | 14 | ## Authors 15 | Natalie E. van Dis, ORCID ID: 0000-0002-9934-6751 16 | 17 |   18 | 19 | ## Analysis and visualization of Experimental data 20 | R scripts to reproduce the analysis and visualization (incl. manuscript figures) of the 2021 winter moth caterpillar feeding experiment: 21 | 22 | ### Script: ```2_scripts/1a_CatFoodExp2021_analysis_fitness.R ``` 23 | (1) What are the fitness consequences of day to day timing (a)synchrony with budburst? 24 | 25 | ### Script: ```2_scripts/1b_CatFoodExp2021_analysis_devtime.R ``` 26 | (2) Can food quality affect the timing of life stages? 27 | 28 | ### Script: ```2_scripts/suppl_pupaweight_proxy.R ``` 29 | Supplemental: Is pupation weight a good proxy for fecundity? 30 | 31 | See ```_src/env_CatFoodExp2021_analysis.txt``` for used R package versions. 32 | 33 |   34 | 35 | ## Analysis and visualization of long-term Field data 36 | ### Script: ```2_scripts/2_prep_FieldData.R ``` 37 | R script to get trapping effort descriptives and to prep all the field data for analysis. 38 | 39 | ### Script: ```2_scripts/3_plot_popnum.R ``` 40 | R script to reproduce the manuscript figure that visualizes winter moth population dynamics and population phenological mismatch over time (1993-2021) at four locations in the Netherlands. 41 | 42 | ### Script: ```2_scripts/4_popdyn_analysis.R ``` 43 | R script to reproduce the analysis of winter moth population dynamics: how much variation in population growth can be explained by timing mismatch? 44 | 45 | See ```_src/env_PopDyn_analysis.txt``` for used R package versions. 46 | -------------------------------------------------------------------------------- /05_Organization_Structure/README.md: -------------------------------------------------------------------------------- 1 | *This is a partial copy from the [original repository](https://github.com/NEvanDis/WM_fitness), made for the Hackathon. 2 | We kept all the repository the same, except the script folder. There you find only the script `1a_CatFoodExp2021_analysis_fitness.R` which is our focus in the hackathon.* 3 | 4 | 5 | [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8276288.svg)](https://doi.org/10.5281/zenodo.8276288) Version of record scripts 6 | 7 | # Winter moth individual fitness and population growth 8 | This folder contains all the scripts needed to reproduce the analysis of experimental and field winter moth data belonging to manuscript _Phenological mismatch affects individual fitness and population growth in the winter moth_, published in Proc Roy Soc B: https://doi.org/10.1098/rspb.2023.0414 9 | 10 | **NB: The raw data, including both experimental data and field data, can be found on Dryad https://doi.org/10.5061/dryad.m905qfv5p** 11 | 12 |   13 | 14 | ## Authors 15 | Natalie E. van Dis, ORCID ID: 0000-0002-9934-6751 16 | 17 |   18 | 19 | ## Analysis and visualization of Experimental data 20 | R scripts to reproduce the analysis and visualization (incl. manuscript figures) of the 2021 winter moth caterpillar feeding experiment: 21 | 22 | ### Script: ```2_scripts/1a_CatFoodExp2021_analysis_fitness.R ``` 23 | (1) What are the fitness consequences of day to day timing (a)synchrony with budburst? 24 | 25 | ### Script: ```2_scripts/1b_CatFoodExp2021_analysis_devtime.R ``` 26 | (2) Can food quality affect the timing of life stages? 27 | 28 | ### Script: ```2_scripts/suppl_pupaweight_proxy.R ``` 29 | Supplemental: Is pupation weight a good proxy for fecundity? 30 | 31 | See ```_src/env_CatFoodExp2021_analysis.txt``` for used R package versions. 32 | 33 |   34 | 35 | ## Analysis and visualization of long-term Field data 36 | ### Script: ```2_scripts/2_prep_FieldData.R ``` 37 | R script to get trapping effort descriptives and to prep all the field data for analysis. 38 | 39 | ### Script: ```2_scripts/3_plot_popnum.R ``` 40 | R script to reproduce the manuscript figure that visualizes winter moth population dynamics and population phenological mismatch over time (1993-2021) at four locations in the Netherlands. 41 | 42 | ### Script: ```2_scripts/4_popdyn_analysis.R ``` 43 | R script to reproduce the analysis of winter moth population dynamics: how much variation in population growth can be explained by timing mismatch? 44 | 45 | See ```_src/env_PopDyn_analysis.txt``` for used R package versions. 46 | -------------------------------------------------------------------------------- /02_Run/_src/env_PopDyn_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] effectsize_0.7.0 rms_6.3-0 SparseM_1.81 Hmisc_4.7-0 Formula_1.2-4 survival_3.2-13 lattice_0.20-45 16 | [8] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 forecast_8.17.0 tseries_0.10-51 cowplot_1.1.1 readxl_1.3.1 17 | [15] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 18 | [22] ggplot2_3.3.5 tidyverse_1.3.1 19 | 20 | loaded via a namespace (and not attached): 21 | [1] minqa_1.2.4 TH.data_1.1-1 VGAM_1.1-7 colorspace_2.0-3 ellipsis_0.3.2 estimability_1.4 22 | [7] htmlTable_2.4.0 parameters_0.18.1 base64enc_0.1-3 fs_1.5.2 rstudioapi_0.13 farver_2.1.0 23 | [13] MatrixModels_0.5-0 fansi_1.0.3 mvtnorm_1.1-3 lubridate_1.8.0 xml2_1.3.3 codetools_0.2-18 24 | [19] splines_4.1.2 knitr_1.38 jsonlite_1.8.0 nloptr_2.0.0 broom_0.7.12 cluster_2.1.2 25 | [25] dbplyr_2.1.1 png_0.1-7 compiler_4.1.2 httr_1.4.2 emmeans_1.7.5 backports_1.4.1 26 | [31] assertthat_0.2.1 fastmap_1.1.0 cli_3.2.0 htmltools_0.5.2 quantreg_5.88 tools_4.1.2 27 | [37] gtable_0.3.0 glue_1.6.2 Rcpp_1.0.8.3 carData_3.0-5 cellranger_1.1.0 fracdiff_1.5-1 28 | [43] vctrs_0.3.8 urca_1.3-0 nlme_3.1-153 lmtest_0.9-40 insight_0.18.0 timeDate_4021.104 29 | [49] xfun_0.30 Rmisc_1.5.1 rvest_1.0.2 lifecycle_1.0.1 polspline_1.1.20 MASS_7.3-54 30 | [55] zoo_1.8-10 scales_1.1.1 hms_1.1.1 parallel_4.1.2 sandwich_3.0-2 RColorBrewer_1.1-2 31 | [61] quantmod_0.4.20 curl_4.3.2 pbapply_1.5-0 gridExtra_2.3 rpart_4.1-15 latticeExtra_0.6-29 32 | [67] stringi_1.7.6 bayestestR_0.12.1 checkmate_2.0.0 TTR_0.24.3 boot_1.3-28 rlang_1.0.2 33 | [73] pkgconfig_2.0.3 htmlwidgets_1.5.4 tidyselect_1.1.2 plyr_1.8.7 magrittr_2.0.2 R6_2.5.1 34 | [79] generics_0.1.2 multcomp_1.4-19 DBI_1.1.2 withr_2.5.0 pillar_1.7.0 haven_2.4.3 35 | [85] foreign_0.8-81 xts_0.12.1 datawizard_0.4.1 abind_1.4-5 nnet_7.3-16 modelr_0.1.8 36 | [91] crayon_1.5.1 car_3.0-12 utf8_1.2.2 tzdb_0.2.0 jpeg_0.1-9 grid_4.1.2 37 | [97] data.table_1.14.2 AICcmodavg_2.3-1 reprex_2.0.1 digest_0.6.29 xtable_1.8-4 numDeriv_2016.8-1.1 38 | [103] stats4_4.1.2 munsell_0.5.0 unmarked_1.2.5 quadprog_1.5-8 39 | -------------------------------------------------------------------------------- /01_Reported/_src/env_PopDyn_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] effectsize_0.7.0 rms_6.3-0 SparseM_1.81 Hmisc_4.7-0 Formula_1.2-4 survival_3.2-13 lattice_0.20-45 16 | [8] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 forecast_8.17.0 tseries_0.10-51 cowplot_1.1.1 readxl_1.3.1 17 | [15] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 18 | [22] ggplot2_3.3.5 tidyverse_1.3.1 19 | 20 | loaded via a namespace (and not attached): 21 | [1] minqa_1.2.4 TH.data_1.1-1 VGAM_1.1-7 colorspace_2.0-3 ellipsis_0.3.2 estimability_1.4 22 | [7] htmlTable_2.4.0 parameters_0.18.1 base64enc_0.1-3 fs_1.5.2 rstudioapi_0.13 farver_2.1.0 23 | [13] MatrixModels_0.5-0 fansi_1.0.3 mvtnorm_1.1-3 lubridate_1.8.0 xml2_1.3.3 codetools_0.2-18 24 | [19] splines_4.1.2 knitr_1.38 jsonlite_1.8.0 nloptr_2.0.0 broom_0.7.12 cluster_2.1.2 25 | [25] dbplyr_2.1.1 png_0.1-7 compiler_4.1.2 httr_1.4.2 emmeans_1.7.5 backports_1.4.1 26 | [31] assertthat_0.2.1 fastmap_1.1.0 cli_3.2.0 htmltools_0.5.2 quantreg_5.88 tools_4.1.2 27 | [37] gtable_0.3.0 glue_1.6.2 Rcpp_1.0.8.3 carData_3.0-5 cellranger_1.1.0 fracdiff_1.5-1 28 | [43] vctrs_0.3.8 urca_1.3-0 nlme_3.1-153 lmtest_0.9-40 insight_0.18.0 timeDate_4021.104 29 | [49] xfun_0.30 Rmisc_1.5.1 rvest_1.0.2 lifecycle_1.0.1 polspline_1.1.20 MASS_7.3-54 30 | [55] zoo_1.8-10 scales_1.1.1 hms_1.1.1 parallel_4.1.2 sandwich_3.0-2 RColorBrewer_1.1-2 31 | [61] quantmod_0.4.20 curl_4.3.2 pbapply_1.5-0 gridExtra_2.3 rpart_4.1-15 latticeExtra_0.6-29 32 | [67] stringi_1.7.6 bayestestR_0.12.1 checkmate_2.0.0 TTR_0.24.3 boot_1.3-28 rlang_1.0.2 33 | [73] pkgconfig_2.0.3 htmlwidgets_1.5.4 tidyselect_1.1.2 plyr_1.8.7 magrittr_2.0.2 R6_2.5.1 34 | [79] generics_0.1.2 multcomp_1.4-19 DBI_1.1.2 withr_2.5.0 pillar_1.7.0 haven_2.4.3 35 | [85] foreign_0.8-81 xts_0.12.1 datawizard_0.4.1 abind_1.4-5 nnet_7.3-16 modelr_0.1.8 36 | [91] crayon_1.5.1 car_3.0-12 utf8_1.2.2 tzdb_0.2.0 jpeg_0.1-9 grid_4.1.2 37 | [97] data.table_1.14.2 AICcmodavg_2.3-1 reprex_2.0.1 digest_0.6.29 xtable_1.8-4 numDeriv_2016.8-1.1 38 | [103] stats4_4.1.2 munsell_0.5.0 unmarked_1.2.5 quadprog_1.5-8 39 | -------------------------------------------------------------------------------- /03_Reliable/_src/env_PopDyn_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] effectsize_0.7.0 rms_6.3-0 SparseM_1.81 Hmisc_4.7-0 Formula_1.2-4 survival_3.2-13 lattice_0.20-45 16 | [8] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 forecast_8.17.0 tseries_0.10-51 cowplot_1.1.1 readxl_1.3.1 17 | [15] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 18 | [22] ggplot2_3.3.5 tidyverse_1.3.1 19 | 20 | loaded via a namespace (and not attached): 21 | [1] minqa_1.2.4 TH.data_1.1-1 VGAM_1.1-7 colorspace_2.0-3 ellipsis_0.3.2 estimability_1.4 22 | [7] htmlTable_2.4.0 parameters_0.18.1 base64enc_0.1-3 fs_1.5.2 rstudioapi_0.13 farver_2.1.0 23 | [13] MatrixModels_0.5-0 fansi_1.0.3 mvtnorm_1.1-3 lubridate_1.8.0 xml2_1.3.3 codetools_0.2-18 24 | [19] splines_4.1.2 knitr_1.38 jsonlite_1.8.0 nloptr_2.0.0 broom_0.7.12 cluster_2.1.2 25 | [25] dbplyr_2.1.1 png_0.1-7 compiler_4.1.2 httr_1.4.2 emmeans_1.7.5 backports_1.4.1 26 | [31] assertthat_0.2.1 fastmap_1.1.0 cli_3.2.0 htmltools_0.5.2 quantreg_5.88 tools_4.1.2 27 | [37] gtable_0.3.0 glue_1.6.2 Rcpp_1.0.8.3 carData_3.0-5 cellranger_1.1.0 fracdiff_1.5-1 28 | [43] vctrs_0.3.8 urca_1.3-0 nlme_3.1-153 lmtest_0.9-40 insight_0.18.0 timeDate_4021.104 29 | [49] xfun_0.30 Rmisc_1.5.1 rvest_1.0.2 lifecycle_1.0.1 polspline_1.1.20 MASS_7.3-54 30 | [55] zoo_1.8-10 scales_1.1.1 hms_1.1.1 parallel_4.1.2 sandwich_3.0-2 RColorBrewer_1.1-2 31 | [61] quantmod_0.4.20 curl_4.3.2 pbapply_1.5-0 gridExtra_2.3 rpart_4.1-15 latticeExtra_0.6-29 32 | [67] stringi_1.7.6 bayestestR_0.12.1 checkmate_2.0.0 TTR_0.24.3 boot_1.3-28 rlang_1.0.2 33 | [73] pkgconfig_2.0.3 htmlwidgets_1.5.4 tidyselect_1.1.2 plyr_1.8.7 magrittr_2.0.2 R6_2.5.1 34 | [79] generics_0.1.2 multcomp_1.4-19 DBI_1.1.2 withr_2.5.0 pillar_1.7.0 haven_2.4.3 35 | [85] foreign_0.8-81 xts_0.12.1 datawizard_0.4.1 abind_1.4-5 nnet_7.3-16 modelr_0.1.8 36 | [91] crayon_1.5.1 car_3.0-12 utf8_1.2.2 tzdb_0.2.0 jpeg_0.1-9 grid_4.1.2 37 | [97] data.table_1.14.2 AICcmodavg_2.3-1 reprex_2.0.1 digest_0.6.29 xtable_1.8-4 numDeriv_2016.8-1.1 38 | [103] stats4_4.1.2 munsell_0.5.0 unmarked_1.2.5 quadprog_1.5-8 39 | -------------------------------------------------------------------------------- /04_Reproducible/_src/env_PopDyn_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] effectsize_0.7.0 rms_6.3-0 SparseM_1.81 Hmisc_4.7-0 Formula_1.2-4 survival_3.2-13 lattice_0.20-45 16 | [8] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 forecast_8.17.0 tseries_0.10-51 cowplot_1.1.1 readxl_1.3.1 17 | [15] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 18 | [22] ggplot2_3.3.5 tidyverse_1.3.1 19 | 20 | loaded via a namespace (and not attached): 21 | [1] minqa_1.2.4 TH.data_1.1-1 VGAM_1.1-7 colorspace_2.0-3 ellipsis_0.3.2 estimability_1.4 22 | [7] htmlTable_2.4.0 parameters_0.18.1 base64enc_0.1-3 fs_1.5.2 rstudioapi_0.13 farver_2.1.0 23 | [13] MatrixModels_0.5-0 fansi_1.0.3 mvtnorm_1.1-3 lubridate_1.8.0 xml2_1.3.3 codetools_0.2-18 24 | [19] splines_4.1.2 knitr_1.38 jsonlite_1.8.0 nloptr_2.0.0 broom_0.7.12 cluster_2.1.2 25 | [25] dbplyr_2.1.1 png_0.1-7 compiler_4.1.2 httr_1.4.2 emmeans_1.7.5 backports_1.4.1 26 | [31] assertthat_0.2.1 fastmap_1.1.0 cli_3.2.0 htmltools_0.5.2 quantreg_5.88 tools_4.1.2 27 | [37] gtable_0.3.0 glue_1.6.2 Rcpp_1.0.8.3 carData_3.0-5 cellranger_1.1.0 fracdiff_1.5-1 28 | [43] vctrs_0.3.8 urca_1.3-0 nlme_3.1-153 lmtest_0.9-40 insight_0.18.0 timeDate_4021.104 29 | [49] xfun_0.30 Rmisc_1.5.1 rvest_1.0.2 lifecycle_1.0.1 polspline_1.1.20 MASS_7.3-54 30 | [55] zoo_1.8-10 scales_1.1.1 hms_1.1.1 parallel_4.1.2 sandwich_3.0-2 RColorBrewer_1.1-2 31 | [61] quantmod_0.4.20 curl_4.3.2 pbapply_1.5-0 gridExtra_2.3 rpart_4.1-15 latticeExtra_0.6-29 32 | [67] stringi_1.7.6 bayestestR_0.12.1 checkmate_2.0.0 TTR_0.24.3 boot_1.3-28 rlang_1.0.2 33 | [73] pkgconfig_2.0.3 htmlwidgets_1.5.4 tidyselect_1.1.2 plyr_1.8.7 magrittr_2.0.2 R6_2.5.1 34 | [79] generics_0.1.2 multcomp_1.4-19 DBI_1.1.2 withr_2.5.0 pillar_1.7.0 haven_2.4.3 35 | [85] foreign_0.8-81 xts_0.12.1 datawizard_0.4.1 abind_1.4-5 nnet_7.3-16 modelr_0.1.8 36 | [91] crayon_1.5.1 car_3.0-12 utf8_1.2.2 tzdb_0.2.0 jpeg_0.1-9 grid_4.1.2 37 | [97] data.table_1.14.2 AICcmodavg_2.3-1 reprex_2.0.1 digest_0.6.29 xtable_1.8-4 numDeriv_2016.8-1.1 38 | [103] stats4_4.1.2 munsell_0.5.0 unmarked_1.2.5 quadprog_1.5-8 39 | -------------------------------------------------------------------------------- /05_Organization_Structure/_src/env_PopDyn_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] effectsize_0.7.0 rms_6.3-0 SparseM_1.81 Hmisc_4.7-0 Formula_1.2-4 survival_3.2-13 lattice_0.20-45 16 | [8] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 forecast_8.17.0 tseries_0.10-51 cowplot_1.1.1 readxl_1.3.1 17 | [15] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 18 | [22] ggplot2_3.3.5 tidyverse_1.3.1 19 | 20 | loaded via a namespace (and not attached): 21 | [1] minqa_1.2.4 TH.data_1.1-1 VGAM_1.1-7 colorspace_2.0-3 ellipsis_0.3.2 estimability_1.4 22 | [7] htmlTable_2.4.0 parameters_0.18.1 base64enc_0.1-3 fs_1.5.2 rstudioapi_0.13 farver_2.1.0 23 | [13] MatrixModels_0.5-0 fansi_1.0.3 mvtnorm_1.1-3 lubridate_1.8.0 xml2_1.3.3 codetools_0.2-18 24 | [19] splines_4.1.2 knitr_1.38 jsonlite_1.8.0 nloptr_2.0.0 broom_0.7.12 cluster_2.1.2 25 | [25] dbplyr_2.1.1 png_0.1-7 compiler_4.1.2 httr_1.4.2 emmeans_1.7.5 backports_1.4.1 26 | [31] assertthat_0.2.1 fastmap_1.1.0 cli_3.2.0 htmltools_0.5.2 quantreg_5.88 tools_4.1.2 27 | [37] gtable_0.3.0 glue_1.6.2 Rcpp_1.0.8.3 carData_3.0-5 cellranger_1.1.0 fracdiff_1.5-1 28 | [43] vctrs_0.3.8 urca_1.3-0 nlme_3.1-153 lmtest_0.9-40 insight_0.18.0 timeDate_4021.104 29 | [49] xfun_0.30 Rmisc_1.5.1 rvest_1.0.2 lifecycle_1.0.1 polspline_1.1.20 MASS_7.3-54 30 | [55] zoo_1.8-10 scales_1.1.1 hms_1.1.1 parallel_4.1.2 sandwich_3.0-2 RColorBrewer_1.1-2 31 | [61] quantmod_0.4.20 curl_4.3.2 pbapply_1.5-0 gridExtra_2.3 rpart_4.1-15 latticeExtra_0.6-29 32 | [67] stringi_1.7.6 bayestestR_0.12.1 checkmate_2.0.0 TTR_0.24.3 boot_1.3-28 rlang_1.0.2 33 | [73] pkgconfig_2.0.3 htmlwidgets_1.5.4 tidyselect_1.1.2 plyr_1.8.7 magrittr_2.0.2 R6_2.5.1 34 | [79] generics_0.1.2 multcomp_1.4-19 DBI_1.1.2 withr_2.5.0 pillar_1.7.0 haven_2.4.3 35 | [85] foreign_0.8-81 xts_0.12.1 datawizard_0.4.1 abind_1.4-5 nnet_7.3-16 modelr_0.1.8 36 | [91] crayon_1.5.1 car_3.0-12 utf8_1.2.2 tzdb_0.2.0 jpeg_0.1-9 grid_4.1.2 37 | [97] data.table_1.14.2 AICcmodavg_2.3-1 reprex_2.0.1 digest_0.6.29 xtable_1.8-4 numDeriv_2016.8-1.1 38 | [103] stats4_4.1.2 munsell_0.5.0 unmarked_1.2.5 quadprog_1.5-8 39 | -------------------------------------------------------------------------------- /06_Other_considerations/_src/env_PopDyn_analysis.txt: -------------------------------------------------------------------------------- 1 | R version 4.1.2 (2021-11-01) 2 | Platform: x86_64-w64-mingw32/x64 (64-bit) 3 | Running under: Windows 10 x64 (build 19044) 4 | 5 | Matrix products: default 6 | 7 | locale: 8 | [1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252 9 | [4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252 10 | 11 | attached base packages: 12 | [1] stats graphics grDevices utils datasets methods base 13 | 14 | other attached packages: 15 | [1] effectsize_0.7.0 rms_6.3-0 SparseM_1.81 Hmisc_4.7-0 Formula_1.2-4 survival_3.2-13 lattice_0.20-45 16 | [8] lmerTest_3.1-3 lme4_1.1-28 Matrix_1.3-4 forecast_8.17.0 tseries_0.10-51 cowplot_1.1.1 readxl_1.3.1 17 | [15] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.8 purrr_0.3.4 readr_2.1.2 tidyr_1.2.0 tibble_3.1.6 18 | [22] ggplot2_3.3.5 tidyverse_1.3.1 19 | 20 | loaded via a namespace (and not attached): 21 | [1] minqa_1.2.4 TH.data_1.1-1 VGAM_1.1-7 colorspace_2.0-3 ellipsis_0.3.2 estimability_1.4 22 | [7] htmlTable_2.4.0 parameters_0.18.1 base64enc_0.1-3 fs_1.5.2 rstudioapi_0.13 farver_2.1.0 23 | [13] MatrixModels_0.5-0 fansi_1.0.3 mvtnorm_1.1-3 lubridate_1.8.0 xml2_1.3.3 codetools_0.2-18 24 | [19] splines_4.1.2 knitr_1.38 jsonlite_1.8.0 nloptr_2.0.0 broom_0.7.12 cluster_2.1.2 25 | [25] dbplyr_2.1.1 png_0.1-7 compiler_4.1.2 httr_1.4.2 emmeans_1.7.5 backports_1.4.1 26 | [31] assertthat_0.2.1 fastmap_1.1.0 cli_3.2.0 htmltools_0.5.2 quantreg_5.88 tools_4.1.2 27 | [37] gtable_0.3.0 glue_1.6.2 Rcpp_1.0.8.3 carData_3.0-5 cellranger_1.1.0 fracdiff_1.5-1 28 | [43] vctrs_0.3.8 urca_1.3-0 nlme_3.1-153 lmtest_0.9-40 insight_0.18.0 timeDate_4021.104 29 | [49] xfun_0.30 Rmisc_1.5.1 rvest_1.0.2 lifecycle_1.0.1 polspline_1.1.20 MASS_7.3-54 30 | [55] zoo_1.8-10 scales_1.1.1 hms_1.1.1 parallel_4.1.2 sandwich_3.0-2 RColorBrewer_1.1-2 31 | [61] quantmod_0.4.20 curl_4.3.2 pbapply_1.5-0 gridExtra_2.3 rpart_4.1-15 latticeExtra_0.6-29 32 | [67] stringi_1.7.6 bayestestR_0.12.1 checkmate_2.0.0 TTR_0.24.3 boot_1.3-28 rlang_1.0.2 33 | [73] pkgconfig_2.0.3 htmlwidgets_1.5.4 tidyselect_1.1.2 plyr_1.8.7 magrittr_2.0.2 R6_2.5.1 34 | [79] generics_0.1.2 multcomp_1.4-19 DBI_1.1.2 withr_2.5.0 pillar_1.7.0 haven_2.4.3 35 | [85] foreign_0.8-81 xts_0.12.1 datawizard_0.4.1 abind_1.4-5 nnet_7.3-16 modelr_0.1.8 36 | [91] crayon_1.5.1 car_3.0-12 utf8_1.2.2 tzdb_0.2.0 jpeg_0.1-9 grid_4.1.2 37 | [97] data.table_1.14.2 AICcmodavg_2.3-1 reprex_2.0.1 digest_0.6.29 xtable_1.8-4 numDeriv_2016.8-1.1 38 | [103] stats4_4.1.2 munsell_0.5.0 unmarked_1.2.5 quadprog_1.5-8 39 | -------------------------------------------------------------------------------- /01_Reported/1_data/README_data.md: -------------------------------------------------------------------------------- 1 | # Raw data belonging to the manuscript "Phenological mismatch affects individual fitness and population growth in the winter moth" 2 | 3 | ## Study 4 | We know little about the fine-scale fitness consequences of phenological mismatch at the individual level and how this mismatch affects population dynamics in the winter moth. 5 | To determine the fitness consequences of mistimed egg hatching relative to timing of oak budburst, we quantified survival and pupation weight in a feeding experiment. 6 | We then investigated whether these individual fitness consequences have population-level impacts by estimating the effect of phenological mismatch on population dynamics, using our long-term data (1994-2021) on relative winter moth population densities at four locations in the Netherlands. 7 | 8 | 9 | ## Methods 10 | Field data on winter moths were collected yearly since 1994 in four forests around Arnhem, the Netherlands, using simple funnel traps to catch adult moths in winter (see [Van Asch et al. 2013, Nat Clim Change (3)] for details). 11 | Eggs collected from these wild adults were kept in a field shed at the Netherlands Institute of Ecology. 12 | Deposited field data for the period 1994-2021 include per year: number of adult moths collected, with for each moth (individual-based data with individual identifier): number of eggs laid, spring seasonal timing of their eggs kept in our field shed, and spring seasonal timing of budburst of oak trees in the field on which adults were caught. 13 | 14 | Experimental data were collected in a caterpillar feeding experiment in the Spring of 2021, using eggs from the long-term field monitoring (described above). 15 | The experiment consisted of a split-brood design, where the timing of hatching of eggs laid by each female was manipulated to induce staggered hatching. 16 | Caterpillars were then divided over different photoperiod treatments (constant photoperiod or naturally changing photoperiod) and different phenological mismatch treatments (hatching before [0-4 days] or after oak budburst [1-5 days], and then fed with oak leaves accordingly). 17 | Deposited experimental data include per caterpillar (individual-based data with individual identifier): parent origin (Catch area, tree, and date), hatch date, death date (if died before pupating), pupation date, pupation weight, date of adult emerging, adult weight, and adult sex. 18 | 19 | 20 | ## Description of the data and file structure 21 | All data files are linked through the individual identifiers described below (i.e. TubeID, ClutchID, CaterpillarID). 22 | 23 | --- Field data files 24 | **NB: YearCatch = November/December when adult moths are caught, YearHatch = YearCatch+1 i.e. first Spring following catching period in the previous year** 25 | 26 | <1994-2021_Field_nr-traps_deposit.csv> 27 | Contains the number of funnel traps placed for each forest and each year of data (AreaShortName: DO=Doorwerth, HV=Hoge Veluwe, OH=Oosterhout, WA=Warnsborn) 28 | 29 | <1994-2021_Field_PopNum_raw_deposit.csv> 30 | Contains for each forest and each year of data, the number of adult winter moth females (NoFemale) and males (NoMale) per catch date in NovemberDays i.e. julian dates with origin YEARCATCH-10-31 (NovemberDate) on each tree (identified by the combination of Site and Tree numbers) 31 | 32 | <1994-2021_Field_timing_deposit.csv> 33 | Contains for each forest and each year, catch information for each female [identifier=TubeID] incl. the tree species and timing of budburst of that tree in the following Spring in AprilDays i.e. julian dates with origin YEARHATCH-03-31 (MinOfAprilDate), as well as the hatching date of her egg clutche(s) (identifier=ClutchID) calculated as the date on which 50% of the eggs had hatched in AprilDays (D50Calc). The measure of phenological mismatch is then calculated as: Mismatch = D50Calc - MinOfAprilDate 34 | 35 | <1994-2021_Field_Eggs_deposit.csv> 36 | Contains for each forest and each year and each female (i.e. TubeID) the number of eggs she laid. 37 | 38 | 39 | --- Experimental data files 40 | **NB: Treatment names consist of photoperiod treatment: Changing [Chang] or Constant [Const]; and phenological mismatch treatment: Day[-4,5]** 41 | 42 | 43 | Contains all experimental data collected from the caterpillar feeding experiment (CatFoodExp2021), incl. for each Caterpillar (identifier=CaterpillarID) their origin (ClutchID -> TubeID incl. catch info for the female parent), the treatment the caterpillar was assigned to, when the caterpillar hatched in April Days i.e. julian dates with origin 2021-03-31 (HatchAprilDay), death date in April days if applicable (DeadAprilDay), the pupation date in April days if applicable (PupationAprilDay), weight at pupation in grams (PupaWeight), the date of adult emergence in November days i.e. julian dates with origin 2021-10-31 if applicable (AdultNovDate), adult weight (in grams) and adult sex. 44 | 45 | 46 | ## Code/Software 47 | All code needed to reproduce the manuscript's analysis of field data and experimental data using R are included. Environment files indicate required software. 48 | All code is annotated and can also be accessed on GitHub: https://github.com/NEvanDis/WM_fitness 49 | -------------------------------------------------------------------------------- /03_Reliable/1_data/README.md: -------------------------------------------------------------------------------- 1 | # Raw data belonging to the manuscript "Phenological mismatch affects individual fitness and population growth in the winter moth" 2 | 3 | ## Download 4 | You can download the data from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 5 | 6 | 7 | ## Study 8 | We know little about the fine-scale fitness consequences of phenological mismatch at the individual level and how this mismatch affects population dynamics in the winter moth. 9 | To determine the fitness consequences of mistimed egg hatching relative to timing of oak budburst, we quantified survival and pupation weight in a feeding experiment. 10 | We then investigated whether these individual fitness consequences have population-level impacts by estimating the effect of phenological mismatch on population dynamics, using our long-term data (1994-2021) on relative winter moth population densities at four locations in the Netherlands. 11 | 12 | 13 | ## Methods 14 | Field data on winter moths were collected yearly since 1994 in four forests around Arnhem, the Netherlands, using simple funnel traps to catch adult moths in winter (see [Van Asch et al. 2013, Nat Clim Change (3)] for details). 15 | Eggs collected from these wild adults were kept in a field shed at the Netherlands Institute of Ecology. 16 | Deposited field data for the period 1994-2021 include per year: number of adult moths collected, with for each moth (individual-based data with individual identifier): number of eggs laid, spring seasonal timing of their eggs kept in our field shed, and spring seasonal timing of budburst of oak trees in the field on which adults were caught. 17 | 18 | Experimental data were collected in a caterpillar feeding experiment in the Spring of 2021, using eggs from the long-term field monitoring (described above). 19 | The experiment consisted of a split-brood design, where the timing of hatching of eggs laid by each female was manipulated to induce staggered hatching. 20 | Caterpillars were then divided over different photoperiod treatments (constant photoperiod or naturally changing photoperiod) and different phenological mismatch treatments (hatching before [0-4 days] or after oak budburst [1-5 days], and then fed with oak leaves accordingly). 21 | Deposited experimental data include per caterpillar (individual-based data with individual identifier): parent origin (Catch area, tree, and date), hatch date, death date (if died before pupating), pupation date, pupation weight, date of adult emerging, adult weight, and adult sex. 22 | 23 | 24 | ## Description of the data and file structure 25 | All data files are linked through the individual identifiers described below (i.e. TubeID, ClutchID, CaterpillarID). 26 | 27 | --- Field data files 28 | **NB: YearCatch = November/December when adult moths are caught, YearHatch = YearCatch+1 i.e. first Spring following catching period in the previous year** 29 | 30 | <1994-2021_Field_nr-traps_deposit.csv> 31 | Contains the number of funnel traps placed for each forest and each year of data (AreaShortName: DO=Doorwerth, HV=Hoge Veluwe, OH=Oosterhout, WA=Warnsborn) 32 | 33 | <1994-2021_Field_PopNum_raw_deposit.csv> 34 | Contains for each forest and each year of data, the number of adult winter moth females (NoFemale) and males (NoMale) per catch date in NovemberDays i.e. julian dates with origin YEARCATCH-10-31 (NovemberDate) on each tree (identified by the combination of Site and Tree numbers) 35 | 36 | <1994-2021_Field_timing_deposit.csv> 37 | Contains for each forest and each year, catch information for each female [identifier=TubeID] incl. the tree species and timing of budburst of that tree in the following Spring in AprilDays i.e. julian dates with origin YEARHATCH-03-31 (MinOfAprilDate), as well as the hatching date of her egg clutche(s) (identifier=ClutchID) calculated as the date on which 50% of the eggs had hatched in AprilDays (D50Calc). The measure of phenological mismatch is then calculated as: Mismatch = D50Calc - MinOfAprilDate 38 | 39 | <1994-2021_Field_Eggs_deposit.csv> 40 | Contains for each forest and each year and each female (i.e. TubeID) the number of eggs she laid. 41 | 42 | 43 | --- Experimental data files 44 | **NB: Treatment names consist of photoperiod treatment: Changing [Chang] or Constant [Const]; and phenological mismatch treatment: Day[-4,5]** 45 | 46 | 47 | Contains all experimental data collected from the caterpillar feeding experiment (CatFoodExp2021), incl. for each Caterpillar (identifier=CaterpillarID) their origin (ClutchID -> TubeID incl. catch info for the female parent), the treatment the caterpillar was assigned to, when the caterpillar hatched in April Days i.e. julian dates with origin 2021-03-31 (HatchAprilDay), death date in April days if applicable (DeadAprilDay), the pupation date in April days if applicable (PupationAprilDay), weight at pupation in grams (PupaWeight), the date of adult emergence in November days i.e. julian dates with origin 2021-10-31 if applicable (AdultNovDate), adult weight (in grams) and adult sex. 48 | 49 | 50 | ## Code/Software 51 | All code needed to reproduce the manuscript's analysis of field data and experimental data using R are included. Environment files indicate required software. 52 | All code is annotated and can also be accessed on GitHub: https://github.com/NEvanDis/WM_fitness 53 | -------------------------------------------------------------------------------- /04_Reproducible/1_data/README.md: -------------------------------------------------------------------------------- 1 | # Raw data belonging to the manuscript "Phenological mismatch affects individual fitness and population growth in the winter moth" 2 | 3 | ## Download 4 | You can download the data from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 5 | 6 | 7 | ## Study 8 | We know little about the fine-scale fitness consequences of phenological mismatch at the individual level and how this mismatch affects population dynamics in the winter moth. 9 | To determine the fitness consequences of mistimed egg hatching relative to timing of oak budburst, we quantified survival and pupation weight in a feeding experiment. 10 | We then investigated whether these individual fitness consequences have population-level impacts by estimating the effect of phenological mismatch on population dynamics, using our long-term data (1994-2021) on relative winter moth population densities at four locations in the Netherlands. 11 | 12 | 13 | ## Methods 14 | Field data on winter moths were collected yearly since 1994 in four forests around Arnhem, the Netherlands, using simple funnel traps to catch adult moths in winter (see [Van Asch et al. 2013, Nat Clim Change (3)] for details). 15 | Eggs collected from these wild adults were kept in a field shed at the Netherlands Institute of Ecology. 16 | Deposited field data for the period 1994-2021 include per year: number of adult moths collected, with for each moth (individual-based data with individual identifier): number of eggs laid, spring seasonal timing of their eggs kept in our field shed, and spring seasonal timing of budburst of oak trees in the field on which adults were caught. 17 | 18 | Experimental data were collected in a caterpillar feeding experiment in the Spring of 2021, using eggs from the long-term field monitoring (described above). 19 | The experiment consisted of a split-brood design, where the timing of hatching of eggs laid by each female was manipulated to induce staggered hatching. 20 | Caterpillars were then divided over different photoperiod treatments (constant photoperiod or naturally changing photoperiod) and different phenological mismatch treatments (hatching before [0-4 days] or after oak budburst [1-5 days], and then fed with oak leaves accordingly). 21 | Deposited experimental data include per caterpillar (individual-based data with individual identifier): parent origin (Catch area, tree, and date), hatch date, death date (if died before pupating), pupation date, pupation weight, date of adult emerging, adult weight, and adult sex. 22 | 23 | 24 | ## Description of the data and file structure 25 | All data files are linked through the individual identifiers described below (i.e. TubeID, ClutchID, CaterpillarID). 26 | 27 | --- Field data files 28 | **NB: YearCatch = November/December when adult moths are caught, YearHatch = YearCatch+1 i.e. first Spring following catching period in the previous year** 29 | 30 | <1994-2021_Field_nr-traps_deposit.csv> 31 | Contains the number of funnel traps placed for each forest and each year of data (AreaShortName: DO=Doorwerth, HV=Hoge Veluwe, OH=Oosterhout, WA=Warnsborn) 32 | 33 | <1994-2021_Field_PopNum_raw_deposit.csv> 34 | Contains for each forest and each year of data, the number of adult winter moth females (NoFemale) and males (NoMale) per catch date in NovemberDays i.e. julian dates with origin YEARCATCH-10-31 (NovemberDate) on each tree (identified by the combination of Site and Tree numbers) 35 | 36 | <1994-2021_Field_timing_deposit.csv> 37 | Contains for each forest and each year, catch information for each female [identifier=TubeID] incl. the tree species and timing of budburst of that tree in the following Spring in AprilDays i.e. julian dates with origin YEARHATCH-03-31 (MinOfAprilDate), as well as the hatching date of her egg clutche(s) (identifier=ClutchID) calculated as the date on which 50% of the eggs had hatched in AprilDays (D50Calc). The measure of phenological mismatch is then calculated as: Mismatch = D50Calc - MinOfAprilDate 38 | 39 | <1994-2021_Field_Eggs_deposit.csv> 40 | Contains for each forest and each year and each female (i.e. TubeID) the number of eggs she laid. 41 | 42 | 43 | --- Experimental data files 44 | **NB: Treatment names consist of photoperiod treatment: Changing [Chang] or Constant [Const]; and phenological mismatch treatment: Day[-4,5]** 45 | 46 | 47 | Contains all experimental data collected from the caterpillar feeding experiment (CatFoodExp2021), incl. for each Caterpillar (identifier=CaterpillarID) their origin (ClutchID -> TubeID incl. catch info for the female parent), the treatment the caterpillar was assigned to, when the caterpillar hatched in April Days i.e. julian dates with origin 2021-03-31 (HatchAprilDay), death date in April days if applicable (DeadAprilDay), the pupation date in April days if applicable (PupationAprilDay), weight at pupation in grams (PupaWeight), the date of adult emergence in November days i.e. julian dates with origin 2021-10-31 if applicable (AdultNovDate), adult weight (in grams) and adult sex. 48 | 49 | 50 | ## Code/Software 51 | All code needed to reproduce the manuscript's analysis of field data and experimental data using R are included. Environment files indicate required software. 52 | All code is annotated and can also be accessed on GitHub: https://github.com/NEvanDis/WM_fitness 53 | -------------------------------------------------------------------------------- /05_Organization_Structure/1_data/README.md: -------------------------------------------------------------------------------- 1 | # Raw data belonging to the manuscript "Phenological mismatch affects individual fitness and population growth in the winter moth" 2 | 3 | ## Download 4 | You can download the data from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 5 | 6 | 7 | ## Study 8 | We know little about the fine-scale fitness consequences of phenological mismatch at the individual level and how this mismatch affects population dynamics in the winter moth. 9 | To determine the fitness consequences of mistimed egg hatching relative to timing of oak budburst, we quantified survival and pupation weight in a feeding experiment. 10 | We then investigated whether these individual fitness consequences have population-level impacts by estimating the effect of phenological mismatch on population dynamics, using our long-term data (1994-2021) on relative winter moth population densities at four locations in the Netherlands. 11 | 12 | 13 | ## Methods 14 | Field data on winter moths were collected yearly since 1994 in four forests around Arnhem, the Netherlands, using simple funnel traps to catch adult moths in winter (see [Van Asch et al. 2013, Nat Clim Change (3)] for details). 15 | Eggs collected from these wild adults were kept in a field shed at the Netherlands Institute of Ecology. 16 | Deposited field data for the period 1994-2021 include per year: number of adult moths collected, with for each moth (individual-based data with individual identifier): number of eggs laid, spring seasonal timing of their eggs kept in our field shed, and spring seasonal timing of budburst of oak trees in the field on which adults were caught. 17 | 18 | Experimental data were collected in a caterpillar feeding experiment in the Spring of 2021, using eggs from the long-term field monitoring (described above). 19 | The experiment consisted of a split-brood design, where the timing of hatching of eggs laid by each female was manipulated to induce staggered hatching. 20 | Caterpillars were then divided over different photoperiod treatments (constant photoperiod or naturally changing photoperiod) and different phenological mismatch treatments (hatching before [0-4 days] or after oak budburst [1-5 days], and then fed with oak leaves accordingly). 21 | Deposited experimental data include per caterpillar (individual-based data with individual identifier): parent origin (Catch area, tree, and date), hatch date, death date (if died before pupating), pupation date, pupation weight, date of adult emerging, adult weight, and adult sex. 22 | 23 | 24 | ## Description of the data and file structure 25 | All data files are linked through the individual identifiers described below (i.e. TubeID, ClutchID, CaterpillarID). 26 | 27 | --- Field data files 28 | **NB: YearCatch = November/December when adult moths are caught, YearHatch = YearCatch+1 i.e. first Spring following catching period in the previous year** 29 | 30 | <1994-2021_Field_nr-traps_deposit.csv> 31 | Contains the number of funnel traps placed for each forest and each year of data (AreaShortName: DO=Doorwerth, HV=Hoge Veluwe, OH=Oosterhout, WA=Warnsborn) 32 | 33 | <1994-2021_Field_PopNum_raw_deposit.csv> 34 | Contains for each forest and each year of data, the number of adult winter moth females (NoFemale) and males (NoMale) per catch date in NovemberDays i.e. julian dates with origin YEARCATCH-10-31 (NovemberDate) on each tree (identified by the combination of Site and Tree numbers) 35 | 36 | <1994-2021_Field_timing_deposit.csv> 37 | Contains for each forest and each year, catch information for each female [identifier=TubeID] incl. the tree species and timing of budburst of that tree in the following Spring in AprilDays i.e. julian dates with origin YEARHATCH-03-31 (MinOfAprilDate), as well as the hatching date of her egg clutche(s) (identifier=ClutchID) calculated as the date on which 50% of the eggs had hatched in AprilDays (D50Calc). The measure of phenological mismatch is then calculated as: Mismatch = D50Calc - MinOfAprilDate 38 | 39 | <1994-2021_Field_Eggs_deposit.csv> 40 | Contains for each forest and each year and each female (i.e. TubeID) the number of eggs she laid. 41 | 42 | 43 | --- Experimental data files 44 | **NB: Treatment names consist of photoperiod treatment: Changing [Chang] or Constant [Const]; and phenological mismatch treatment: Day[-4,5]** 45 | 46 | 47 | Contains all experimental data collected from the caterpillar feeding experiment (CatFoodExp2021), incl. for each Caterpillar (identifier=CaterpillarID) their origin (ClutchID -> TubeID incl. catch info for the female parent), the treatment the caterpillar was assigned to, when the caterpillar hatched in April Days i.e. julian dates with origin 2021-03-31 (HatchAprilDay), death date in April days if applicable (DeadAprilDay), the pupation date in April days if applicable (PupationAprilDay), weight at pupation in grams (PupaWeight), the date of adult emergence in November days i.e. julian dates with origin 2021-10-31 if applicable (AdultNovDate), adult weight (in grams) and adult sex. 48 | 49 | 50 | ## Code/Software 51 | All code needed to reproduce the manuscript's analysis of field data and experimental data using R are included. Environment files indicate required software. 52 | All code is annotated and can also be accessed on GitHub: https://github.com/NEvanDis/WM_fitness 53 | -------------------------------------------------------------------------------- /06_Other_considerations/1_data/README.md: -------------------------------------------------------------------------------- 1 | # Raw data belonging to the manuscript "Phenological mismatch affects individual fitness and population growth in the winter moth" 2 | 3 | ## Download 4 | You can download the data from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 5 | 6 | 7 | ## Study 8 | We know little about the fine-scale fitness consequences of phenological mismatch at the individual level and how this mismatch affects population dynamics in the winter moth. 9 | To determine the fitness consequences of mistimed egg hatching relative to timing of oak budburst, we quantified survival and pupation weight in a feeding experiment. 10 | We then investigated whether these individual fitness consequences have population-level impacts by estimating the effect of phenological mismatch on population dynamics, using our long-term data (1994-2021) on relative winter moth population densities at four locations in the Netherlands. 11 | 12 | 13 | ## Methods 14 | Field data on winter moths were collected yearly since 1994 in four forests around Arnhem, the Netherlands, using simple funnel traps to catch adult moths in winter (see [Van Asch et al. 2013, Nat Clim Change (3)] for details). 15 | Eggs collected from these wild adults were kept in a field shed at the Netherlands Institute of Ecology. 16 | Deposited field data for the period 1994-2021 include per year: number of adult moths collected, with for each moth (individual-based data with individual identifier): number of eggs laid, spring seasonal timing of their eggs kept in our field shed, and spring seasonal timing of budburst of oak trees in the field on which adults were caught. 17 | 18 | Experimental data were collected in a caterpillar feeding experiment in the Spring of 2021, using eggs from the long-term field monitoring (described above). 19 | The experiment consisted of a split-brood design, where the timing of hatching of eggs laid by each female was manipulated to induce staggered hatching. 20 | Caterpillars were then divided over different photoperiod treatments (constant photoperiod or naturally changing photoperiod) and different phenological mismatch treatments (hatching before [0-4 days] or after oak budburst [1-5 days], and then fed with oak leaves accordingly). 21 | Deposited experimental data include per caterpillar (individual-based data with individual identifier): parent origin (Catch area, tree, and date), hatch date, death date (if died before pupating), pupation date, pupation weight, date of adult emerging, adult weight, and adult sex. 22 | 23 | 24 | ## Description of the data and file structure 25 | All data files are linked through the individual identifiers described below (i.e. TubeID, ClutchID, CaterpillarID). 26 | 27 | --- Field data files 28 | **NB: YearCatch = November/December when adult moths are caught, YearHatch = YearCatch+1 i.e. first Spring following catching period in the previous year** 29 | 30 | <1994-2021_Field_nr-traps_deposit.csv> 31 | Contains the number of funnel traps placed for each forest and each year of data (AreaShortName: DO=Doorwerth, HV=Hoge Veluwe, OH=Oosterhout, WA=Warnsborn) 32 | 33 | <1994-2021_Field_PopNum_raw_deposit.csv> 34 | Contains for each forest and each year of data, the number of adult winter moth females (NoFemale) and males (NoMale) per catch date in NovemberDays i.e. julian dates with origin YEARCATCH-10-31 (NovemberDate) on each tree (identified by the combination of Site and Tree numbers) 35 | 36 | <1994-2021_Field_timing_deposit.csv> 37 | Contains for each forest and each year, catch information for each female [identifier=TubeID] incl. the tree species and timing of budburst of that tree in the following Spring in AprilDays i.e. julian dates with origin YEARHATCH-03-31 (MinOfAprilDate), as well as the hatching date of her egg clutche(s) (identifier=ClutchID) calculated as the date on which 50% of the eggs had hatched in AprilDays (D50Calc). The measure of phenological mismatch is then calculated as: Mismatch = D50Calc - MinOfAprilDate 38 | 39 | <1994-2021_Field_Eggs_deposit.csv> 40 | Contains for each forest and each year and each female (i.e. TubeID) the number of eggs she laid. 41 | 42 | 43 | --- Experimental data files 44 | **NB: Treatment names consist of photoperiod treatment: Changing [Chang] or Constant [Const]; and phenological mismatch treatment: Day[-4,5]** 45 | 46 | 47 | Contains all experimental data collected from the caterpillar feeding experiment (CatFoodExp2021), incl. for each Caterpillar (identifier=CaterpillarID) their origin (ClutchID -> TubeID incl. catch info for the female parent), the treatment the caterpillar was assigned to, when the caterpillar hatched in April Days i.e. julian dates with origin 2021-03-31 (HatchAprilDay), death date in April days if applicable (DeadAprilDay), the pupation date in April days if applicable (PupationAprilDay), weight at pupation in grams (PupaWeight), the date of adult emergence in November days i.e. julian dates with origin 2021-10-31 if applicable (AdultNovDate), adult weight (in grams) and adult sex. 48 | 49 | 50 | ## Code/Software 51 | All code needed to reproduce the manuscript's analysis of field data and experimental data using R are included. Environment files indicate required software. 52 | All code is annotated and can also be accessed on GitHub: https://github.com/NEvanDis/WM_fitness 53 | -------------------------------------------------------------------------------- /02_Run/1_data/README.md: -------------------------------------------------------------------------------- 1 | # Raw data belonging to the manuscript "Phenological mismatch affects individual fitness and population growth in the winter moth" 2 | 3 | ## Download 4 | You can download the data from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 5 | 6 | 7 | ## Study 8 | We know little about the fine-scale fitness consequences of phenological mismatch at the individual level and how this mismatch affects population dynamics in the winter moth. 9 | To determine the fitness consequences of mistimed egg hatching relative to timing of oak budburst, we quantified survival and pupation weight in a feeding experiment. 10 | We then investigated whether these individual fitness consequences have population-level impacts by estimating the effect of phenological mismatch on population dynamics, using our long-term data (1994-2021) on relative winter moth population densities at four locations in the Netherlands. 11 | 12 | 13 | ## Methods 14 | Field data on winter moths were collected yearly since 1994 in four forests around Arnhem, the Netherlands, using simple funnel traps to catch adult moths in winter (see [Van Asch et al. 2013, Nat Clim Change (3)] for details). 15 | Eggs collected from these wild adults were kept in a field shed at the Netherlands Institute of Ecology. 16 | Deposited field data for the period 1994-2021 include per year: number of adult moths collected, with for each moth (individual-based data with individual identifier): number of eggs laid, spring seasonal timing of their eggs kept in our field shed, and spring seasonal timing of budburst of oak trees in the field on which adults were caught. 17 | 18 | Experimental data were collected in a caterpillar feeding experiment in the Spring of 2021, using eggs from the long-term field monitoring (described above). 19 | The experiment consisted of a split-brood design, where the timing of hatching of eggs laid by each female was manipulated to induce staggered hatching. 20 | Caterpillars were then divided over different photoperiod treatments (constant photoperiod or naturally changing photoperiod) and different phenological mismatch treatments (hatching before [0-4 days] or after oak budburst [1-5 days], and then fed with oak leaves accordingly). 21 | Deposited experimental data include per caterpillar (individual-based data with individual identifier): parent origin (Catch area, tree, and date), hatch date, death date (if died before pupating), pupation date, pupation weight, date of adult emerging, adult weight, and adult sex. 22 | 23 | 24 | ## Description of the data and file structure 25 | All data files are linked through the individual identifiers described below (i.e. TubeID, ClutchID, CaterpillarID). 26 | 27 | --- Field data files 28 | **NB: YearCatch = November/December when adult moths are caught, YearHatch = YearCatch+1 i.e. first Spring following catching period in the previous year** 29 | 30 | <1994-2021_Field_nr-traps_deposit.csv> 31 | Contains the number of funnel traps placed for each forest and each year of data (AreaShortName: DO=Doorwerth, HV=Hoge Veluwe, OH=Oosterhout, WA=Warnsborn) 32 | 33 | <1994-2021_Field_PopNum_raw_deposit.csv> 34 | Contains for each forest and each year of data, the number of adult winter moth females (NoFemale) and males (NoMale) per catch date in NovemberDays i.e. julian dates with origin YEARCATCH-10-31 (NovemberDate) on each tree (identified by the combination of Site and Tree numbers) 35 | 36 | <1994-2021_Field_timing_deposit.csv> 37 | Contains for each forest and each year, catch information for each female [identifier=TubeID] incl. the tree species and timing of budburst of that tree in the following Spring in AprilDays i.e. julian dates with origin YEARHATCH-03-31 (MinOfAprilDate), as well as the hatching date of her egg clutche(s) (identifier=ClutchID) calculated as the date on which 50% of the eggs had hatched in AprilDays (D50Calc). The measure of phenological mismatch is then calculated as: Mismatch = D50Calc - MinOfAprilDate 38 | 39 | <1994-2021_Field_Eggs_deposit.csv> 40 | Contains for each forest and each year and each female (i.e. TubeID) the number of eggs she laid. 41 | 42 | 43 | --- Experimental data files 44 | **NB: Treatment names consist of photoperiod treatment: Changing [Chang] or Constant [Const]; and phenological mismatch treatment: Day[-4,5]** 45 | 46 | 47 | Contains all experimental data collected from the caterpillar feeding experiment (CatFoodExp2021), incl. for each Caterpillar (identifier=CaterpillarID) their origin (ClutchID -> TubeID incl. catch info for the female parent), the treatment the caterpillar was assigned to, when the caterpillar hatched in April Days i.e. julian dates with origin 2021-03-31 (HatchAprilDay), death date in April days if applicable (DeadAprilDay), the pupation date in April days if applicable (PupationAprilDay), weight at pupation in grams (PupaWeight), the date of adult emergence in November days i.e. julian dates with origin 2021-10-31 if applicable (AdultNovDate), adult weight (in grams) and adult sex. 48 | 49 | 50 | ## Code/Software 51 | All code needed to reproduce the manuscript's analysis of field data and experimental data using R are included. Environment files indicate required software. 52 | All code is annotated and can also be accessed on GitHub: https://github.com/NEvanDis/WM_fitness 53 | -------------------------------------------------------------------------------- /01_Reported/1_data/README.md: -------------------------------------------------------------------------------- 1 | # Raw data belonging to the manuscript "Phenological mismatch affects individual fitness and population growth in the winter moth" 2 | 3 | ## Download 4 | You can download the data from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 5 | 6 | 7 | ## Study 8 | We know little about the fine-scale fitness consequences of phenological mismatch at the individual level and how this mismatch affects population dynamics in the winter moth. 9 | To determine the fitness consequences of mistimed egg hatching relative to timing of oak budburst, we quantified survival and pupation weight in a feeding experiment. 10 | We then investigated whether these individual fitness consequences have population-level impacts by estimating the effect of phenological mismatch on population dynamics, using our long-term data (1994-2021) on relative winter moth population densities at four locations in the Netherlands. 11 | 12 | 13 | ## Methods 14 | Field data on winter moths were collected yearly since 1994 in four forests around Arnhem, the Netherlands, using simple funnel traps to catch adult moths in winter (see [Van Asch et al. 2013, Nat Clim Change (3)] for details). 15 | Eggs collected from these wild adults were kept in a field shed at the Netherlands Institute of Ecology. 16 | Deposited field data for the period 1994-2021 include per year: number of adult moths collected, with for each moth (individual-based data with individual identifier): number of eggs laid, spring seasonal timing of their eggs kept in our field shed, and spring seasonal timing of budburst of oak trees in the field on which adults were caught. 17 | 18 | Experimental data were collected in a caterpillar feeding experiment in the Spring of 2021, using eggs from the long-term field monitoring (described above). 19 | The experiment consisted of a split-brood design, where the timing of hatching of eggs laid by each female was manipulated to induce staggered hatching. 20 | Caterpillars were then divided over different photoperiod treatments (constant photoperiod or naturally changing photoperiod) and different phenological mismatch treatments (hatching before [0-4 days] or after oak budburst [1-5 days], and then fed with oak leaves accordingly). 21 | Deposited experimental data include per caterpillar (individual-based data with individual identifier): parent origin (Catch area, tree, and date), hatch date, death date (if died before pupating), pupation date, pupation weight, date of adult emerging, adult weight, and adult sex. 22 | 23 | 24 | ## Description of the data and file structure 25 | All data files are linked through the individual identifiers described below (i.e. TubeID, ClutchID, CaterpillarID). 26 | 27 | --- Field data files 28 | **NB: YearCatch = November/December when adult moths are caught, YearHatch = YearCatch+1 i.e. first Spring following catching period in the previous year** 29 | 30 | <1994-2021_Field_nr-traps_deposit.csv> 31 | Contains the number of funnel traps placed for each forest and each year of data (AreaShortName: DO=Doorwerth, HV=Hoge Veluwe, OH=Oosterhout, WA=Warnsborn) 32 | 33 | <1994-2021_Field_PopNum_raw_deposit.csv> 34 | Contains for each forest and each year of data, the number of adult winter moth females (NoFemale) and males (NoMale) per catch date in NovemberDays i.e. julian dates with origin YEARCATCH-10-31 (NovemberDate) on each tree (identified by the combination of Site and Tree numbers) 35 | 36 | <1994-2021_Field_timing_deposit.csv> 37 | Contains for each forest and each year, catch information for each female [identifier=TubeID] incl. the tree species and timing of budburst of that tree in the following Spring in AprilDays i.e. julian dates with origin YEARHATCH-03-31 (MinOfAprilDate), as well as the hatching date of her egg clutche(s) (identifier=ClutchID) calculated as the date on which 50% of the eggs had hatched in AprilDays (D50Calc). The measure of phenological mismatch is then calculated as: Mismatch = D50Calc - MinOfAprilDate 38 | 39 | <1994-2021_Field_Eggs_deposit.csv> 40 | Contains for each forest and each year and each female (i.e. TubeID) the number of eggs she laid. 41 | 42 | 43 | --- Experimental data files 44 | **NB: Treatment names consist of photoperiod treatment: Changing [Chang] or Constant [Const]; and phenological mismatch treatment: Day[-4,5]** 45 | 46 | 47 | Contains all experimental data collected from the caterpillar feeding experiment (CatFoodExp2021), incl. for each Caterpillar (identifier=CaterpillarID) their origin (ClutchID -> TubeID incl. catch info for the female parent), the treatment the caterpillar was assigned to, when the caterpillar hatched in April Days i.e. julian dates with origin 2021-03-31 (HatchAprilDay), death date in April days if applicable (DeadAprilDay), the pupation date in April days if applicable (PupationAprilDay), weight at pupation in grams (PupaWeight), the date of adult emergence in November days i.e. julian dates with origin 2021-10-31 if applicable (AdultNovDate), adult weight (in grams) and adult sex. 48 | 49 | 50 | ## Code/Software 51 | All code needed to reproduce the manuscript's analysis of field data and experimental data using R are included. Environment files indicate required software. 52 | All code is annotated and can also be accessed on GitHub: https://github.com/NEvanDis/WM_fitness 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeStandard 2 | 3 | This is the collaborative repository for the **SORTEE Code Club Hackathon: Creating a Code Standard**, writing the "perfect" Open, Reliable, and Transparent (ORT) code for Ecology & Evolution. 4 | 5 | The Hackathon takes place online on _Wed Oct 16 2024, 06:00-07:55 UTC +00:00_ as part of [the 2024 SORTEE Conference](https://www.sortee.org/upcoming/): the Society for Open, Reliable, and Transparent Ecology & Evolution. In this repo you can find all the relevant instructions, files and links to other resources used during the hackathon. 6 | 7 | ❗ **This repository is your landing page for the Hackathon. Please bookmark this repo for easy access to all resources.** 8 | 9 | Before the Hackathon, make sure you have a Github account. 10 | 11 | 🙋 **Hackathon hosts:** Natalie E. van Dis & Arthur V. Rodrigues 12 | 🧑‍🤝‍🧑 **Hackathon participants:** Kevin R. Bairos-Novak, Mattia Ghilardi, Alfredo Sánchez-Tójar, Saoirse Kelleher, Matthieu Paquet, Romy Zeiss, Saeed Shafiei Sabet, Martin Luquet, Cecilia Baldoni, Abhishek Kumar, Gabe Winter, Giulia Masoero 13 | 14 | ## Hackathon links 15 | 16 | 1. [HackMD](https://hackmd.io/kxNotAiRQdaIq62pkQ2K_A) -- Collaborative Markdown file for real-time writing that we will use as a notebook during the Hackathon. Here you can find more detailed information about the Hackathon. 17 | 18 |        :page_facing_up: Please carefully read section [Hackathon Outline](https://hackmd.io/kxNotAiRQdaIq62pkQ2K_A#Hackathon-outline) describing how we will work. 19 | 20 | 2. [Slides](https://docs.google.com/presentation/d/1fSY_UCjT8Wz---Ultba62r_sItDC2qKkmnwcY78LEuY/edit?usp=sharing) -- The slides with the introduction, instructions, and schedule for the Hackathon are available here. 21 | 3. [Participant sign-up sheet](https://docs.google.com/spreadsheets/d/1U3LnAbkklFMbEmkUIWbzjq7RAtb_xPedyc2VvixNRDE/edit?usp=sharing) -- We will ask participants to sign-up during the Hackathon and fill in their information to be added to the team of this repo and be listed as contributor to the Code Standard. 22 | 4. [Paper](https://royalsocietypublishing.org/doi/10.1098/rspb.2023.0414) -- To create the Code Standard, we will work on the code from this paper: _van Dis et al 2023. Phenological mismatch affects individual fitness and population growth in the winter moth. Proc R Soc B 290: 20230414._ 23 | 5. [Data repository](https://datadryad.org/stash/dataset/doi:10.5061/dryad.m905qfv5p) -- For the Hackathon, you will only need to download the files ```CatFood2021_deposit.csv``` and ```README.md``` from the data repository. 24 | 25 | ## How to work in the repository 26 | 27 | Clone the repository to your computer by creating an R project or by using the `git` command bellow: 28 | 29 | `git clone https://github.com/SORTEE/CodeStandard.git` 30 | 31 | ### ❗ Important 32 | 33 | After cloning the repository, switch to the `hackathon` branch. You will not be allowed to push changes to the `main` branch. 34 | 35 | Command: `git switch hackathon` or if you have an older version of git installed: `git checkout hackathon` 36 | Check that you are in the right place with command: `git branch` 37 | 38 | ## Repository structure 39 | 40 | The repository has six folders with the same internal structure and files. Each folder will be used by one of the working groups during the Hackathon: 41 | 42 | ├── :open_file_folder:01_Reported 43 | ├── :open_file_folder:02_Run 44 | ├── :open_file_folder:03_Reliable 45 | ├── :open_file_folder:04_Reproducible 46 | ├── :open_file_folder:05_Organization_Structure 47 | ├── :open_file_folder:06_Other_considerations 48 | ├── :page_facing_up:LICENSE 49 | └── :page_facing_up:README.md 50 | 51 | In each folder, we provide the same initial files to be reviewed and modified in the Hackathon. 52 | 53 | The idea is that from the same initial code we will have six different final code versions, focusing on different goals. This way, each code version shows the ORT steps implemented when focusing on a particular goal (e.g. goal Group 1: Make sure the code perfectly matches the methods of the paper). **After the Hackathon, these six different versions will be united into one single code/folder to make up the Code Standard.** 54 | 55 | ## Good practices for collaboration in Github 56 | 57 | We are collaborating using `git` and Github to allow multiple people to edit the code while working in the same project folder. We assume that the participants have basic knowledge and experience with `git` and Github. 58 | 59 | Since we are several people in the same repo at the same time, we need to avoid `git` conflicts. 60 | 61 | We suggest to: 62 | 63 | - Avoid working in the same file at the same time. Communicate! Discuss within your group the task division before starting to work in a particular file. Let people know that you are working there. 64 | - `commmit` and `push` often (i.e. for every task/major change). Always `pull` before pushing your commits. 65 | - You can come across merging messages (especially if you are using the command line to ```pull/push```). If so, accept the merging. It depends on the editor configured on your `git`, but helpful commands can be `:wq` (write and quite) or `ctrl/cmd + x`. 66 | - If you have a `git` conflict, you need to resolve it before committing. If you are unsure how to, discuss with your group or ask the Hackathon hosts for help before changing and committing the file. 67 | - If you get stuck using `git` locally in your machine, you can edit files directly on Github and add the changes you made as a commit. Also here: make sure you are working in the `hackathon` branch. 68 | - We have a `git` help section at the end on the slides. Check there: [Hackathon Slides](https://docs.google.com/presentation/d/1fSY_UCjT8Wz---Ultba62r_sItDC2qKkmnwcY78LEuY/edit?usp=sharing). 69 | 70 | -------------------------------------------------------------------------------- /02_Run/2_scripts/1a_CatFoodExp2021_analysis_fitness.R: -------------------------------------------------------------------------------- 1 | # Analysis of Phenological mismatch experiment 2021 #### 2 | # Manipulated timing of egg hatching of eggs from wild Mothers caught in 2020 3 | # Either hatching on day of budburst (Day0), before (Day-4 to -1), or after (Day+1 to +5) 4 | # Disentangle effects of photoperiod and food quality: photoperiod treatment (changing or constant) 5 | 6 | # before start download the dataset 'CatFood2021_deposit.csv' 7 | # from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 8 | 9 | # the dataset should be saved in the folder 1_data 10 | 11 | 12 | # Open R project in main folder 13 | 14 | # Restore library 15 | renv::restore() 16 | 17 | # Load packages 18 | #----------------------------------- 19 | library(tidyverse) 20 | library(cowplot) 21 | theme_set(theme_cowplot()) #white background instead of grey -> don't load if want grey grid 22 | library(lme4) 23 | library(lmerTest) 24 | library(Rmisc) 25 | 26 | 27 | # Load data #### 28 | #----------------------------------- 29 | d <- read.csv("1_data/CatFood2021_deposit.csv") 30 | head(d) 31 | 32 | # renaming TubeID as MotherID to match the terminology used in the Statistical section of the paper 33 | d <- rename(d, MotherID = TubeID) 34 | 35 | length(unique(d$MotherID)) # should be 22 mothers 36 | table(d$Treatment) # photoperiod and mismatch treatment coded in one variable 37 | 38 | 39 | # Descriptives 40 | #----------------------------------- 41 | 42 | # N per Area 43 | table(d[!duplicated(d$MotherID), "AreaShortName"]) 44 | 45 | 46 | #--------------------------------------------------------------------------------------------------------------------------- 47 | # Fitness curve #### 48 | #---------------------------------- 49 | # RQ1: What are the fitness consequences of day to day timing (a)synchrony with budburst? #### 50 | 51 | # Survival data #### 52 | d_surv <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment)) %>% 53 | select(MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, DeadAprilDay, PupationAprilDay) %>% 54 | pivot_longer(cols=c(DeadAprilDay, PupationAprilDay), names_to="Info", values_to="TimeOfEvent") %>% 55 | filter(!is.na(TimeOfEvent)) %>% 56 | mutate(Event=ifelse(Info=="DeadAprilDay", 1, 0), Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 57 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 58 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 59 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 60 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 61 | mutate(MismTreat1=MismTreat+5, # no negatives to be able to fit squared term 62 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 63 | # Vidisha coded it as TimeOfEvent=DeadAprilDay or PupationAprilDay, with event=Died or Survived 64 | head(d_surv) 65 | str(d_surv) 66 | table(d_surv$MismTreat2) 67 | 68 | length(unique(d_surv$CaterpillarID)) # should be 976 69 | 70 | 71 | #----------------------------------- 72 | # Survival analysis #### 73 | #----------------------------------- 74 | levels(d_surv$Treatment) 75 | levels(d_surv$PhotoTreat) 76 | levels(d_surv$MismTreatf) # as factor or not? Marcel thinks not #### 77 | levels(d_surv$MotherID) 78 | table(d_surv$TimeOfEvent) 79 | table(d_surv$Event) # this variable corresponds to "survival" as defined in the paper (e.g., the response variable in the first binomial mixed-effect model) 80 | 81 | # Visualize survival probabilities #### 82 | head(d_surv) 83 | 84 | surv_probs <- aggregate(Event~MismTreat + PhotoTreat + MotherID, d_surv, sum) # per mother 85 | surv_probs$samplesize <- aggregate(Info~MismTreat + PhotoTreat + MotherID, d_surv, length)$Info 86 | surv_probs$probs <- 100 - (surv_probs$Event/surv_probs$samplesize*100) # event = death 87 | head(surv_probs) 88 | 89 | surv_avg <- Rmisc::summarySE(surv_probs, measurevar="probs", groupvars=c("MismTreat")) # average of two photoperiod treatments 90 | surv_avg$samplesize <- aggregate(Info~MismTreat, d_surv, length)$Info 91 | surv_avg 92 | 93 | raw_surv <- ggplot(data=surv_avg, aes(x=MismTreat, y=probs))+ 94 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 95 | geom_jitter(data=surv_probs, aes(col=PhotoTreat), alpha=0.3, size=3, height=0.5, width=0.25)+ 96 | geom_point(size=5, col="black") + 97 | geom_errorbar(aes(ymax = probs+se, ymin=probs-se), width=0.3, col="black") + 98 | geom_text(aes(label=samplesize, y=probs+8.3), col="black", size=4,fontface="bold")+ # N caterpillars in each treatment 99 | labs(y="Survival (%)", x="Mismatch with oak budburst date (days)")+ 100 | scale_y_continuous(breaks=seq(0,100, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 101 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 102 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 103 | raw_surv 104 | # ggsave(filename="_results/Survival_raw.png", plot=raw_surv , device="png", width=200, height=150, units="mm", dpi="print") 105 | 106 | 107 | # Fit binomial model #### 108 | #----------------------------------- 109 | head(d_surv) # test if probability of survival differs between treatments 110 | 111 | glm1 <- glmer(Event ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), family=binomial, data=d_surv, 112 | na.action="na.fail", control=glmerControl(calc.derivs=F)) # helps convergence 113 | anova1 <- drop1(glm1,test="Chi") %>% as.data.frame # interaction not significant; the use of Chi-square test to determine statistical significance should be explicitly mention in the paper 114 | anova1$mod <- "glm1" 115 | 116 | glm2 <- update(glm1, ~ . -MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 117 | anova2 <- drop1(glm2,test="Chi") %>% as.data.frame #no effect of PhotoTreatment, but effect of MismTreat and MismTreat^2 118 | anova2$mod <- "glm2" 119 | 120 | # Final model #### 121 | glm_final <- glm2 122 | summary(glm_final)# Estimates are log odds 123 | glm_res <- summary(glm_final)$coefficients %>% as.data.frame 124 | 125 | # write.csv(glm_res, file="_results/output_Surv_glmer.csv", row.names=T) 126 | # write.csv(rbind(anova1, anova2), file="_results/anova_Surv_glmer.csv", row.names=T) 127 | 128 | # Get predictions #### 129 | glm.pred <- d_surv[!duplicated(d_surv[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 130 | glm.pred$pred <- predict(glm_final, newdata=glm.pred, type="response") # predictions are probability of dying now 131 | glm.pred$survprob <- (1-glm.pred$pred) 132 | aggregate(survprob~MismTreat, data=glm.pred, mean) # peak at Day2 133 | glm.pred$rel <- glm.pred$survprob/mean(filter(glm.pred, MismTreat==1)$survprob) # expressive relative to peak 134 | head(glm.pred) 135 | 136 | # Visualize predictions #### 137 | pred <- Rmisc::summarySE(glm.pred, measurevar="survprob", groupvars=c("MismTreat")) # average of two photoperiod treatments 138 | pred$samplesize <- aggregate(CaterpillarID~MismTreat, data=d_surv, length)$CaterpillarID 139 | 140 | # Add predictions to raw data figure 141 | p_surv <- raw_surv + #geom_line(data=pred, aes(y=survprob*100)) + 142 | geom_smooth(data=pred, aes(y=survprob*100), se=F, col="red3") 143 | p_surv 144 | # ggsave(filename="_results/Survival_wpred_rev.png", plot=p_surv, device="png", width=200, height=150, units="mm", dpi="print") 145 | 146 | rm(anova1, anova2, glm_res, glm1, glm2, pred, surv_probs, surv_avg, raw_surv) #cleanup 147 | 148 | 149 | #----------------------------------- 150 | # Pupation weight analysis #### 151 | #----------------------------------- 152 | head(d) 153 | 154 | d_pupa <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment), PupaWeight=PupaWeight_ingrams*1000) %>% 155 | select(ExperimentName, MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, PupationAprilDay, PupaWeight) %>% 156 | filter(!is.na(PupationAprilDay)) %>% 157 | mutate(Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 158 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 159 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 160 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 161 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 162 | mutate(MismTreat1=MismTreat+5, # no negatives 163 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 164 | head(d_pupa) # 346 individuals survived until pupation 165 | nrow(d_pupa)/nrow(d)*100 # ~35% 166 | 167 | 168 | # Visualize #### 169 | weight <- Rmisc::summarySE(d_pupa, measurevar="PupaWeight", groupvars=c("MismTreat", "PhotoTreat")) 170 | weight$pos <- ifelse(is.na(weight$se)==T, 0, weight$se) # position of sample size labels 171 | weight 172 | 173 | raw_weight <- ggplot(data=weight, aes(x=MismTreat, y=PupaWeight, col=PhotoTreat, fill=PhotoTreat))+ 174 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 175 | scale_fill_manual(values=c("grey27", "orangered2"))+ 176 | geom_jitter(data=d_pupa, aes(col=PhotoTreat), alpha=0.3, size=3, height=0, width=0.25)+ #alpha=0.3, size=2, height=0, width=0.25 177 | geom_errorbar(data=filter(weight, PhotoTreat=="Changing"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="black") + 178 | geom_errorbar(data=filter(weight, PhotoTreat=="Constant"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="orangered4") + 179 | geom_point(size=5, shape=21, col="black")+ 180 | #geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-2.3), col="black", size=4, fontface="bold")+ 181 | #geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold")+ 182 | labs(y="Weight at pupation (mg)", x="Mismatch with oak budburst date (days)")+ 183 | scale_y_continuous(breaks=seq(15,75, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 184 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 185 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 186 | raw_weight 187 | # ggsave(filename="_results/PupWeight_raw.png", plot=raw_weight , device="png", width=200, height=150, units="mm", dpi="print") 188 | 189 | 190 | # Fit linear mixed model #### 191 | #----------------------------------- 192 | lm1 <- lmer(PupaWeight ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), data=d_pupa) 193 | anova1 <- anova(lm1) %>% as.data.frame() # interaction not significant 194 | anova1$mod <- "lm1" 195 | 196 | lm2 <- update(lm1, ~ . - MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 197 | anova2 <- anova(lm2) %>% as.data.frame() # Squared mismatch not significant 198 | anova2$mod <- "lm2" 199 | 200 | lm3 <- update(lm2, ~ . - MismTreat2) # simplify model 201 | anova3 <- anova(lm3) %>% as.data.frame() # PhotoTreat and MismTreat significant 202 | anova3$mod <- "lm3" 203 | 204 | # Still there if exclude first time point with low sample size? 205 | lm4 <- lmer(PupaWeight ~ -1 + MismTreat1 + PhotoTreat + (1|MotherID), data=filter(d_pupa, MismTreat!=-4)) 206 | anova(lm4) # yes 207 | 208 | 209 | # Final model #### 210 | lm_final <- lm3 211 | summary(lm_final) 212 | lm_res <- summary(lm_final)$coefficients %>% as.data.frame 213 | 214 | plot(lm_final) #equal variance? ok 215 | qqnorm(resid(lm_final)) #normally distributed? ok 216 | qqline(resid(lm_final)) 217 | 218 | # write.csv(lm_res, file="_results/output_PupaWeight_lmer.csv", row.names=T) 219 | # write.csv(rbind(anova1, anova2, anova3), file="_results/anova_PupaWeight_lmer.csv", row.names=T) 220 | 221 | # Get predictions #### 222 | lm.pred <- d_pupa[!duplicated(d_pupa[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 223 | lm.pred$pred <- predict(lm_final, newdata=lm.pred, type="response") 224 | head(lm.pred) 225 | 226 | # Visualize predictions #### 227 | pred1 <- Rmisc::summarySE(lm.pred, measurevar="pred", groupvars=c("MismTreat", "PhotoTreat")) # significant effect of photoperiod, so show separate means 228 | pred1$samplesize <- weight$N 229 | pred1$pos <- ifelse(is.na(pred1$se)==T, 0, pred1$se) # position of sample size labels 230 | 231 | # add predictions to raw data figure 232 | p_weight <- raw_weight + #geom_line(data=pred1, aes(y=pred)) + 233 | geom_smooth(data=pred1, aes(y=pred, col=PhotoTreat), se=F, method=lm)+ 234 | geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-1.5), col="black", size=4, fontface="bold")+ 235 | geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold") 236 | p_weight 237 | # ggsave(filename="_results/PupWeight_wpred_rev.png", plot=p_weight, device="png", width=200, height=150, units="mm", dpi="print") 238 | 239 | 240 | 241 | #-------------------------------------------- 242 | # Get fitness curve #### 243 | #-------------------------------------------- 244 | 245 | # Don't care about PhotoTreat effect, drop from models #### 246 | glm_fit <- glmer(Event ~ MismTreat1 + MismTreat2 + (1 | MotherID), family="binomial", data=d_surv) 247 | lm_fit <- lmer(PupaWeight ~ MismTreat1 + (1 | MotherID), data=d_pupa) 248 | 249 | # Get predictions to use for curve #### 250 | glm.fit <- d_surv[!duplicated(d_surv[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 251 | glm.fit$pred <- predict(glm_fit, newdata=glm.fit, type="response") # predictions are probability of dying now 252 | glm.fit$survpred <- (1-glm.fit$pred) 253 | 254 | lm.fit <- d_pupa[!duplicated(d_pupa[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 255 | lm.fit$pred <- predict(lm_fit, newdata=lm.fit, type="response") 256 | 257 | head(glm.fit) # pred = probability of dying, survpred=1-pred, 220 observations = 22 mothers * 10 MismTreat groups 258 | head(lm.fit) # pred=predicted weight from lmer, only 154 observations 259 | 260 | 261 | # Fit curve to absolute fitness #### 262 | #----------------------------------- 263 | RelFit <- merge(glm.fit[,c("MotherID", "MismTreat", "survpred")], lm.fit[,c("MotherID", "MismTreat", "pred")], by=c("MotherID", "MismTreat"), all=T) 264 | colnames(RelFit)[c(3,4)] <- c("survpred", "pupwpred") 265 | RelFit$Fit <- RelFit$survpred*RelFit$pupwpred # multiply absolute values 266 | head(RelFit) # can only do for 154 observations, clutches with >=1 caterpillar surviving until pupation 267 | table(RelFit$MismTreat, is.na(RelFit$Fit)) # for the other clutches, fitness = 0 268 | RelFit$Fit2 <- ifelse(is.na(RelFit$Fit)==T, 0, RelFit$Fit) 269 | 270 | # loess model to describe the curve #### 271 | loess_mod <- loess(Fit2~ -1 + MismTreat, data=RelFit) 272 | summary(loess_mod) 273 | 274 | curve <- RelFit[!duplicated(RelFit[,c("MismTreat")]),] %>% select(MismTreat) 275 | curve$pred <- predict(loess_mod, newdata=curve) 276 | curve <- arrange(curve, MismTreat) 277 | curve # peak at day2 278 | curve$rel <- curve$pred/filter(curve, MismTreat==2)$pred # expressive relative to peak 279 | 280 | RelFit$rel <- RelFit$Fit2/mean(filter(RelFit, MismTreat==2)$Fit2) 281 | 282 | RelFit_means <- Rmisc::summarySE(RelFit, measurevar="rel", groupvars=c("MismTreat")) 283 | #RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_pupa, length)$MotherID # number of caterpillars curve is based on 284 | RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_surv, length)$MotherID # number of caterpillars curve is based on = all 285 | RelFit_means$curve <- curve$rel 286 | head(RelFit_means) 287 | # write.csv(RelFit_means, file="_results/RelFitness_rev.csv", row.names=F) 288 | 289 | p_relfit <- ggplot(data=RelFit, aes(x=MismTreat, y=rel)) + 290 | geom_jitter(size=3, alpha=0.4, height=0, width=0.25, shape=21, fill="dodgerblue2", col="dodgerblue4")+ 291 | geom_point(data=RelFit_means, size=5) + 292 | geom_errorbar(data=RelFit_means, aes(ymax = rel+se, ymin=rel-se), width=0.3) + 293 | #geom_line(data=curve, aes(y=pred), col="darkred", size=1)+ 294 | #geom_smooth(data=curve, se=F, col="red3", size=1)+ # makes it look more like a smooth line, but otherwise exactly the same as using geom_line 295 | geom_text(data=RelFit_means,aes(label=samplesize, y=rel+0.12), col="black", size=5, fontface="bold")+ # number of caterpillars 296 | geom_hline(yintercept=1, linetype="dashed")+ 297 | labs(y="Relative fitness", x="Mismatch with oak budburst date (days)")+ 298 | scale_y_continuous(lim=c(0,1.21), breaks=seq(0,1.6, by=0.2))+ scale_x_continuous(breaks=seq(-4,5, by=1))+ #lim=c(-0.1,1.3) 299 | theme(legend.position="none")+ 300 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 301 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 302 | p_relfit 303 | # ggsave(filename="_results/FitnessCurve_rev.png", plot=p_relfit, device="png", width=200, height=150, units="mm", dpi="print") 304 | 305 | 306 | 307 | 308 | sessionInfo() %>% capture.output(file="_src/env_CatFoodExp2021_analysis.txt") 309 | -------------------------------------------------------------------------------- /01_Reported/2_scripts/1a_CatFoodExp2021_analysis_fitness.R: -------------------------------------------------------------------------------- 1 | # Analysis of Phenological mismatch experiment 2021 #### 2 | # Manipulated timing of egg hatching of eggs from wild Mothers caught in 2020 3 | # Either hatching on day of budburst (Day0), before (Day-4 to -1), or after (Day+1 to +5) 4 | # Disentangle effects of photoperiod and food quality: photoperiod treatment (changing or constant) 5 | 6 | # before start download the dataset 'CatFood2021_deposit.csv' 7 | # from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 8 | 9 | # the dataset should be saved in the folder 1_data 10 | 11 | 12 | # Open R project in main folder 13 | 14 | # Restore library 15 | renv::restore() 16 | 17 | # Load packages 18 | #----------------------------------- 19 | library(tidyverse) 20 | library(cowplot) 21 | theme_set(theme_cowplot()) #white background instead of grey -> don't load if want grey grid 22 | library(lme4) 23 | library(lmerTest) 24 | library(Rmisc) 25 | 26 | 27 | # Load data #### 28 | #----------------------------------- 29 | d <- read.csv("1_data/CatFood2021_deposit.csv") 30 | head(d) 31 | 32 | # renaming TubeID as MotherID to match the terminology used in the Statistical section of the paper 33 | d <- rename(d, MotherID = TubeID) 34 | 35 | length(unique(d$MotherID)) # should be 22 mothers 36 | table(d$Treatment) # photoperiod and mismatch treatment coded in one variable 37 | 38 | 39 | # Descriptives 40 | #----------------------------------- 41 | 42 | # N per Area 43 | table(d[!duplicated(d$MotherID), "AreaShortName"]) 44 | 45 | 46 | #--------------------------------------------------------------------------------------------------------------------------- 47 | # Fitness curve #### 48 | #---------------------------------- 49 | # RQ1: What are the fitness consequences of day to day timing (a)synchrony with budburst? #### 50 | 51 | # Survival data #### 52 | d_surv <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment)) %>% 53 | select(MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, DeadAprilDay, PupationAprilDay) %>% 54 | pivot_longer(cols=c(DeadAprilDay, PupationAprilDay), names_to="Info", values_to="TimeOfEvent") %>% 55 | filter(!is.na(TimeOfEvent)) %>% 56 | mutate(Event=ifelse(Info=="DeadAprilDay", 1, 0), Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 57 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 58 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 59 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 60 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 61 | mutate(MismTreat1=MismTreat+5, # no negatives to be able to fit squared term 62 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 63 | # Vidisha coded it as TimeOfEvent=DeadAprilDay or PupationAprilDay, with event=Died or Survived 64 | head(d_surv) 65 | str(d_surv) 66 | table(d_surv$MismTreat2) 67 | 68 | length(unique(d_surv$CaterpillarID)) # should be 976 69 | 70 | 71 | #----------------------------------- 72 | # Survival analysis #### 73 | #----------------------------------- 74 | levels(d_surv$Treatment) 75 | levels(d_surv$PhotoTreat) 76 | levels(d_surv$MismTreatf) # as factor or not? Marcel thinks not #### 77 | levels(d_surv$MotherID) 78 | table(d_surv$TimeOfEvent) 79 | table(d_surv$Event) # this variable corresponds to "survival" as defined in the paper (e.g., the response variable in the first binomial mixed-effect model) 80 | 81 | # Visualize survival probabilities #### 82 | head(d_surv) 83 | 84 | surv_probs <- aggregate(Event~MismTreat + PhotoTreat + MotherID, d_surv, sum) # per mother 85 | surv_probs$samplesize <- aggregate(Info~MismTreat + PhotoTreat + MotherID, d_surv, length)$Info 86 | surv_probs$probs <- 100 - (surv_probs$Event/surv_probs$samplesize*100) # event = death 87 | head(surv_probs) 88 | 89 | surv_avg <- Rmisc::summarySE(surv_probs, measurevar="probs", groupvars=c("MismTreat")) # average of two photoperiod treatments 90 | surv_avg$samplesize <- aggregate(Info~MismTreat, d_surv, length)$Info 91 | surv_avg 92 | 93 | raw_surv <- ggplot(data=surv_avg, aes(x=MismTreat, y=probs))+ 94 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 95 | geom_jitter(data=surv_probs, aes(col=PhotoTreat), alpha=0.3, size=3, height=0.5, width=0.25)+ 96 | geom_point(size=5, col="black") + 97 | geom_errorbar(aes(ymax = probs+se, ymin=probs-se), width=0.3, col="black") + 98 | geom_text(aes(label=samplesize, y=probs+8.3), col="black", size=4,fontface="bold")+ # N caterpillars in each treatment 99 | labs(y="Survival (%)", x="Mismatch with oak budburst date (days)")+ 100 | scale_y_continuous(breaks=seq(0,100, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 101 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 102 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 103 | raw_surv 104 | # ggsave(filename="_results/Survival_raw.png", plot=raw_surv , device="png", width=200, height=150, units="mm", dpi="print") 105 | 106 | 107 | # Fit binomial model #### 108 | #----------------------------------- 109 | head(d_surv) # test if probability of survival differs between treatments 110 | 111 | glm1 <- glmer(Event ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), family=binomial, data=d_surv, 112 | na.action="na.fail", control=glmerControl(calc.derivs=F)) # helps convergence 113 | anova1 <- drop1(glm1,test="Chi") %>% as.data.frame # interaction not significant; the use of Chi-square test to determine statistical significance should be explicitly mention in the paper 114 | anova1$mod <- "glm1" 115 | 116 | glm2 <- update(glm1, ~ . -MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 117 | anova2 <- drop1(glm2,test="Chi") %>% as.data.frame #no effect of PhotoTreatment, but effect of MismTreat and MismTreat^2 118 | anova2$mod <- "glm2" 119 | 120 | # Final model #### 121 | glm_final <- glm2 122 | summary(glm_final)# Estimates are log odds 123 | glm_res <- summary(glm_final)$coefficients %>% as.data.frame 124 | 125 | # write.csv(glm_res, file="_results/output_Surv_glmer.csv", row.names=T) 126 | # write.csv(rbind(anova1, anova2), file="_results/anova_Surv_glmer.csv", row.names=T) 127 | 128 | # Get predictions #### 129 | glm.pred <- d_surv[!duplicated(d_surv[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 130 | glm.pred$pred <- predict(glm_final, newdata=glm.pred, type="response") # predictions are probability of dying now 131 | glm.pred$survprob <- (1-glm.pred$pred) 132 | aggregate(survprob~MismTreat, data=glm.pred, mean) # peak at Day2 133 | glm.pred$rel <- glm.pred$survprob/mean(filter(glm.pred, MismTreat==1)$survprob) # expressive relative to peak 134 | head(glm.pred) 135 | 136 | # Visualize predictions #### 137 | pred <- Rmisc::summarySE(glm.pred, measurevar="survprob", groupvars=c("MismTreat")) # average of two photoperiod treatments 138 | pred$samplesize <- aggregate(CaterpillarID~MismTreat, data=d_surv, length)$CaterpillarID 139 | 140 | # Add predictions to raw data figure 141 | p_surv <- raw_surv + #geom_line(data=pred, aes(y=survprob*100)) + 142 | geom_smooth(data=pred, aes(y=survprob*100), se=F, col="red3") 143 | p_surv 144 | # ggsave(filename="_results/Survival_wpred_rev.png", plot=p_surv, device="png", width=200, height=150, units="mm", dpi="print") 145 | 146 | rm(anova1, anova2, glm_res, glm1, glm2, pred, surv_probs, surv_avg, raw_surv) #cleanup 147 | 148 | 149 | #----------------------------------- 150 | # Pupation weight analysis #### 151 | #----------------------------------- 152 | head(d) 153 | 154 | d_pupa <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment), PupaWeight=PupaWeight_ingrams*1000) %>% 155 | select(ExperimentName, MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, PupationAprilDay, PupaWeight) %>% 156 | filter(!is.na(PupationAprilDay)) %>% 157 | mutate(Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 158 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 159 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 160 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 161 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 162 | mutate(MismTreat1=MismTreat+5, # no negatives 163 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 164 | head(d_pupa) # 346 individuals survived until pupation 165 | nrow(d_pupa)/nrow(d)*100 # ~35% 166 | 167 | 168 | # Visualize #### 169 | weight <- Rmisc::summarySE(d_pupa, measurevar="PupaWeight", groupvars=c("MismTreat", "PhotoTreat")) 170 | weight$pos <- ifelse(is.na(weight$se)==T, 0, weight$se) # position of sample size labels 171 | weight 172 | 173 | raw_weight <- ggplot(data=weight, aes(x=MismTreat, y=PupaWeight, col=PhotoTreat, fill=PhotoTreat))+ 174 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 175 | scale_fill_manual(values=c("grey27", "orangered2"))+ 176 | geom_jitter(data=d_pupa, aes(col=PhotoTreat), alpha=0.3, size=3, height=0, width=0.25)+ #alpha=0.3, size=2, height=0, width=0.25 177 | geom_errorbar(data=filter(weight, PhotoTreat=="Changing"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="black") + 178 | geom_errorbar(data=filter(weight, PhotoTreat=="Constant"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="orangered4") + 179 | geom_point(size=5, shape=21, col="black")+ 180 | #geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-2.3), col="black", size=4, fontface="bold")+ 181 | #geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold")+ 182 | labs(y="Weight at pupation (mg)", x="Mismatch with oak budburst date (days)")+ 183 | scale_y_continuous(breaks=seq(15,75, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 184 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 185 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 186 | raw_weight 187 | # ggsave(filename="_results/PupWeight_raw.png", plot=raw_weight , device="png", width=200, height=150, units="mm", dpi="print") 188 | 189 | 190 | # Fit linear mixed model #### 191 | #----------------------------------- 192 | lm1 <- lmer(PupaWeight ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), data=d_pupa) 193 | anova1 <- anova(lm1) %>% as.data.frame() # interaction not significant 194 | anova1$mod <- "lm1" 195 | 196 | lm2 <- update(lm1, ~ . - MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 197 | anova2 <- anova(lm2) %>% as.data.frame() # Squared mismatch not significant 198 | anova2$mod <- "lm2" 199 | 200 | lm3 <- update(lm2, ~ . - MismTreat2) # simplify model 201 | anova3 <- anova(lm3) %>% as.data.frame() # PhotoTreat and MismTreat significant 202 | anova3$mod <- "lm3" 203 | 204 | # Still there if exclude first time point with low sample size? 205 | lm4 <- lmer(PupaWeight ~ -1 + MismTreat1 + PhotoTreat + (1|MotherID), data=filter(d_pupa, MismTreat!=-4)) 206 | anova(lm4) # yes 207 | 208 | 209 | # Final model #### 210 | lm_final <- lm3 211 | summary(lm_final) 212 | lm_res <- summary(lm_final)$coefficients %>% as.data.frame 213 | 214 | plot(lm_final) #equal variance? ok 215 | qqnorm(resid(lm_final)) #normally distributed? ok 216 | qqline(resid(lm_final)) 217 | 218 | # write.csv(lm_res, file="_results/output_PupaWeight_lmer.csv", row.names=T) 219 | # write.csv(rbind(anova1, anova2, anova3), file="_results/anova_PupaWeight_lmer.csv", row.names=T) 220 | 221 | # Get predictions #### 222 | lm.pred <- d_pupa[!duplicated(d_pupa[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 223 | lm.pred$pred <- predict(lm_final, newdata=lm.pred, type="response") 224 | head(lm.pred) 225 | 226 | # Visualize predictions #### 227 | pred1 <- Rmisc::summarySE(lm.pred, measurevar="pred", groupvars=c("MismTreat", "PhotoTreat")) # significant effect of photoperiod, so show separate means 228 | pred1$samplesize <- weight$N 229 | pred1$pos <- ifelse(is.na(pred1$se)==T, 0, pred1$se) # position of sample size labels 230 | 231 | # add predictions to raw data figure 232 | p_weight <- raw_weight + #geom_line(data=pred1, aes(y=pred)) + 233 | geom_smooth(data=pred1, aes(y=pred, col=PhotoTreat), se=F, method=lm)+ 234 | geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-1.5), col="black", size=4, fontface="bold")+ 235 | geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold") 236 | p_weight 237 | # ggsave(filename="_results/PupWeight_wpred_rev.png", plot=p_weight, device="png", width=200, height=150, units="mm", dpi="print") 238 | 239 | 240 | 241 | #-------------------------------------------- 242 | # Get fitness curve #### 243 | #-------------------------------------------- 244 | 245 | # Don't care about PhotoTreat effect, drop from models #### 246 | glm_fit <- glmer(Event ~ MismTreat1 + MismTreat2 + (1 | MotherID), family="binomial", data=d_surv) 247 | lm_fit <- lmer(PupaWeight ~ MismTreat1 + (1 | MotherID), data=d_pupa) 248 | 249 | # Get predictions to use for curve #### 250 | glm.fit <- d_surv[!duplicated(d_surv[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 251 | glm.fit$pred <- predict(glm_fit, newdata=glm.fit, type="response") # predictions are probability of dying now 252 | glm.fit$survpred <- (1-glm.fit$pred) 253 | 254 | lm.fit <- d_pupa[!duplicated(d_pupa[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 255 | lm.fit$pred <- predict(lm_fit, newdata=lm.fit, type="response") 256 | 257 | head(glm.fit) # pred = probability of dying, survpred=1-pred, 220 observations = 22 mothers * 10 MismTreat groups 258 | head(lm.fit) # pred=predicted weight from lmer, only 154 observations 259 | 260 | 261 | # Fit curve to absolute fitness #### 262 | #----------------------------------- 263 | RelFit <- merge(glm.fit[,c("MotherID", "MismTreat", "survpred")], lm.fit[,c("MotherID", "MismTreat", "pred")], by=c("MotherID", "MismTreat"), all=T) 264 | colnames(RelFit)[c(3,4)] <- c("survpred", "pupwpred") 265 | RelFit$Fit <- RelFit$survpred*RelFit$pupwpred # multiply absolute values 266 | head(RelFit) # can only do for 154 observations, clutches with >=1 caterpillar surviving until pupation 267 | table(RelFit$MismTreat, is.na(RelFit$Fit)) # for the other clutches, fitness = 0 268 | RelFit$Fit2 <- ifelse(is.na(RelFit$Fit)==T, 0, RelFit$Fit) 269 | 270 | # loess model to describe the curve #### 271 | loess_mod <- loess(Fit2~ -1 + MismTreat, data=RelFit) 272 | summary(loess_mod) 273 | 274 | curve <- RelFit[!duplicated(RelFit[,c("MismTreat")]),] %>% select(MismTreat) 275 | curve$pred <- predict(loess_mod, newdata=curve) 276 | curve <- arrange(curve, MismTreat) 277 | curve # peak at day2 278 | curve$rel <- curve$pred/filter(curve, MismTreat==2)$pred # expressive relative to peak 279 | 280 | RelFit$rel <- RelFit$Fit2/mean(filter(RelFit, MismTreat==2)$Fit2) 281 | 282 | RelFit_means <- Rmisc::summarySE(RelFit, measurevar="rel", groupvars=c("MismTreat")) 283 | #RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_pupa, length)$MotherID # number of caterpillars curve is based on 284 | RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_surv, length)$MotherID # number of caterpillars curve is based on = all 285 | RelFit_means$curve <- curve$rel 286 | head(RelFit_means) 287 | # write.csv(RelFit_means, file="_results/RelFitness_rev.csv", row.names=F) 288 | 289 | p_relfit <- ggplot(data=RelFit, aes(x=MismTreat, y=rel)) + 290 | geom_jitter(size=3, alpha=0.4, height=0, width=0.25, shape=21, fill="dodgerblue2", col="dodgerblue4")+ 291 | geom_point(data=RelFit_means, size=5) + 292 | geom_errorbar(data=RelFit_means, aes(ymax = rel+se, ymin=rel-se), width=0.3) + 293 | #geom_line(data=curve, aes(y=pred), col="darkred", size=1)+ 294 | #geom_smooth(data=curve, se=F, col="red3", size=1)+ # makes it look more like a smooth line, but otherwise exactly the same as using geom_line 295 | geom_text(data=RelFit_means,aes(label=samplesize, y=rel+0.12), col="black", size=5, fontface="bold")+ # number of caterpillars 296 | geom_hline(yintercept=1, linetype="dashed")+ 297 | labs(y="Relative fitness", x="Mismatch with oak budburst date (days)")+ 298 | scale_y_continuous(lim=c(0,1.21), breaks=seq(0,1.6, by=0.2))+ scale_x_continuous(breaks=seq(-4,5, by=1))+ #lim=c(-0.1,1.3) 299 | theme(legend.position="none")+ 300 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 301 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 302 | p_relfit 303 | # ggsave(filename="_results/FitnessCurve_rev.png", plot=p_relfit, device="png", width=200, height=150, units="mm", dpi="print") 304 | 305 | 306 | 307 | 308 | sessionInfo() %>% capture.output(file="_src/env_CatFoodExp2021_analysis.txt") 309 | -------------------------------------------------------------------------------- /03_Reliable/2_scripts/1a_CatFoodExp2021_analysis_fitness.R: -------------------------------------------------------------------------------- 1 | # Analysis of Phenological mismatch experiment 2021 #### 2 | # Manipulated timing of egg hatching of eggs from wild Mothers caught in 2020 3 | # Either hatching on day of budburst (Day0), before (Day-4 to -1), or after (Day+1 to +5) 4 | # Disentangle effects of photoperiod and food quality: photoperiod treatment (changing or constant) 5 | 6 | # before start download the dataset 'CatFood2021_deposit.csv' 7 | # from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 8 | 9 | # the dataset should be saved in the folder 1_data 10 | 11 | 12 | # Open R project in main folder 13 | 14 | # Restore library 15 | renv::restore() 16 | 17 | # Load packages 18 | #----------------------------------- 19 | library(tidyverse) 20 | library(cowplot) 21 | theme_set(theme_cowplot()) #white background instead of grey -> don't load if want grey grid 22 | library(lme4) 23 | library(lmerTest) 24 | library(Rmisc) 25 | 26 | 27 | # Load data #### 28 | #----------------------------------- 29 | d <- read.csv("1_data/CatFood2021_deposit.csv") 30 | head(d) 31 | 32 | # renaming TubeID as MotherID to match the terminology used in the Statistical section of the paper 33 | d <- rename(d, MotherID = TubeID) 34 | 35 | length(unique(d$MotherID)) # should be 22 mothers 36 | table(d$Treatment) # photoperiod and mismatch treatment coded in one variable 37 | 38 | 39 | # Descriptives 40 | #----------------------------------- 41 | 42 | # N per Area 43 | table(d[!duplicated(d$MotherID), "AreaShortName"]) 44 | 45 | 46 | #--------------------------------------------------------------------------------------------------------------------------- 47 | # Fitness curve #### 48 | #---------------------------------- 49 | # RQ1: What are the fitness consequences of day to day timing (a)synchrony with budburst? #### 50 | 51 | # Survival data #### 52 | d_surv <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment)) %>% 53 | select(MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, DeadAprilDay, PupationAprilDay) %>% 54 | pivot_longer(cols=c(DeadAprilDay, PupationAprilDay), names_to="Info", values_to="TimeOfEvent") %>% 55 | filter(!is.na(TimeOfEvent)) %>% 56 | mutate(Event=ifelse(Info=="DeadAprilDay", 1, 0), Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 57 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 58 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 59 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 60 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 61 | mutate(MismTreat1=MismTreat+5, # no negatives to be able to fit squared term 62 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 63 | # Vidisha coded it as TimeOfEvent=DeadAprilDay or PupationAprilDay, with event=Died or Survived 64 | head(d_surv) 65 | str(d_surv) 66 | table(d_surv$MismTreat2) 67 | 68 | length(unique(d_surv$CaterpillarID)) # should be 976 69 | 70 | 71 | #----------------------------------- 72 | # Survival analysis #### 73 | #----------------------------------- 74 | levels(d_surv$Treatment) 75 | levels(d_surv$PhotoTreat) 76 | levels(d_surv$MismTreatf) # as factor or not? Marcel thinks not #### 77 | levels(d_surv$MotherID) 78 | table(d_surv$TimeOfEvent) 79 | table(d_surv$Event) # this variable corresponds to "survival" as defined in the paper (e.g., the response variable in the first binomial mixed-effect model) 80 | 81 | # Visualize survival probabilities #### 82 | head(d_surv) 83 | 84 | surv_probs <- aggregate(Event~MismTreat + PhotoTreat + MotherID, d_surv, sum) # per mother 85 | surv_probs$samplesize <- aggregate(Info~MismTreat + PhotoTreat + MotherID, d_surv, length)$Info 86 | surv_probs$probs <- 100 - (surv_probs$Event/surv_probs$samplesize*100) # event = death 87 | head(surv_probs) 88 | 89 | surv_avg <- Rmisc::summarySE(surv_probs, measurevar="probs", groupvars=c("MismTreat")) # average of two photoperiod treatments 90 | surv_avg$samplesize <- aggregate(Info~MismTreat, d_surv, length)$Info 91 | surv_avg 92 | 93 | raw_surv <- ggplot(data=surv_avg, aes(x=MismTreat, y=probs))+ 94 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 95 | geom_jitter(data=surv_probs, aes(col=PhotoTreat), alpha=0.3, size=3, height=0.5, width=0.25)+ 96 | geom_point(size=5, col="black") + 97 | geom_errorbar(aes(ymax = probs+se, ymin=probs-se), width=0.3, col="black") + 98 | geom_text(aes(label=samplesize, y=probs+8.3), col="black", size=4,fontface="bold")+ # N caterpillars in each treatment 99 | labs(y="Survival (%)", x="Mismatch with oak budburst date (days)")+ 100 | scale_y_continuous(breaks=seq(0,100, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 101 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 102 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 103 | raw_surv 104 | # ggsave(filename="_results/Survival_raw.png", plot=raw_surv , device="png", width=200, height=150, units="mm", dpi="print") 105 | 106 | 107 | # Fit binomial model #### 108 | #----------------------------------- 109 | head(d_surv) # test if probability of survival differs between treatments 110 | 111 | glm1 <- glmer(Event ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), family=binomial, data=d_surv, 112 | na.action="na.fail", control=glmerControl(calc.derivs=F)) # helps convergence 113 | anova1 <- drop1(glm1,test="Chi") %>% as.data.frame # interaction not significant; the use of Chi-square test to determine statistical significance should be explicitly mention in the paper 114 | anova1$mod <- "glm1" 115 | 116 | glm2 <- update(glm1, ~ . -MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 117 | anova2 <- drop1(glm2,test="Chi") %>% as.data.frame #no effect of PhotoTreatment, but effect of MismTreat and MismTreat^2 118 | anova2$mod <- "glm2" 119 | 120 | # Final model #### 121 | glm_final <- glm2 122 | summary(glm_final)# Estimates are log odds 123 | glm_res <- summary(glm_final)$coefficients %>% as.data.frame 124 | 125 | # write.csv(glm_res, file="_results/output_Surv_glmer.csv", row.names=T) 126 | # write.csv(rbind(anova1, anova2), file="_results/anova_Surv_glmer.csv", row.names=T) 127 | 128 | # Get predictions #### 129 | glm.pred <- d_surv[!duplicated(d_surv[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 130 | glm.pred$pred <- predict(glm_final, newdata=glm.pred, type="response") # predictions are probability of dying now 131 | glm.pred$survprob <- (1-glm.pred$pred) 132 | aggregate(survprob~MismTreat, data=glm.pred, mean) # peak at Day2 133 | glm.pred$rel <- glm.pred$survprob/mean(filter(glm.pred, MismTreat==1)$survprob) # expressive relative to peak 134 | head(glm.pred) 135 | 136 | # Visualize predictions #### 137 | pred <- Rmisc::summarySE(glm.pred, measurevar="survprob", groupvars=c("MismTreat")) # average of two photoperiod treatments 138 | pred$samplesize <- aggregate(CaterpillarID~MismTreat, data=d_surv, length)$CaterpillarID 139 | 140 | # Add predictions to raw data figure 141 | p_surv <- raw_surv + #geom_line(data=pred, aes(y=survprob*100)) + 142 | geom_smooth(data=pred, aes(y=survprob*100), se=F, col="red3") 143 | p_surv 144 | # ggsave(filename="_results/Survival_wpred_rev.png", plot=p_surv, device="png", width=200, height=150, units="mm", dpi="print") 145 | 146 | rm(anova1, anova2, glm_res, glm1, glm2, pred, surv_probs, surv_avg, raw_surv) #cleanup 147 | 148 | 149 | #----------------------------------- 150 | # Pupation weight analysis #### 151 | #----------------------------------- 152 | head(d) 153 | 154 | d_pupa <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment), PupaWeight=PupaWeight_ingrams*1000) %>% 155 | select(ExperimentName, MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, PupationAprilDay, PupaWeight) %>% 156 | filter(!is.na(PupationAprilDay)) %>% 157 | mutate(Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 158 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 159 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 160 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 161 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 162 | mutate(MismTreat1=MismTreat+5, # no negatives 163 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 164 | head(d_pupa) # 346 individuals survived until pupation 165 | nrow(d_pupa)/nrow(d)*100 # ~35% 166 | 167 | 168 | # Visualize #### 169 | weight <- Rmisc::summarySE(d_pupa, measurevar="PupaWeight", groupvars=c("MismTreat", "PhotoTreat")) 170 | weight$pos <- ifelse(is.na(weight$se)==T, 0, weight$se) # position of sample size labels 171 | weight 172 | 173 | raw_weight <- ggplot(data=weight, aes(x=MismTreat, y=PupaWeight, col=PhotoTreat, fill=PhotoTreat))+ 174 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 175 | scale_fill_manual(values=c("grey27", "orangered2"))+ 176 | geom_jitter(data=d_pupa, aes(col=PhotoTreat), alpha=0.3, size=3, height=0, width=0.25)+ #alpha=0.3, size=2, height=0, width=0.25 177 | geom_errorbar(data=filter(weight, PhotoTreat=="Changing"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="black") + 178 | geom_errorbar(data=filter(weight, PhotoTreat=="Constant"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="orangered4") + 179 | geom_point(size=5, shape=21, col="black")+ 180 | #geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-2.3), col="black", size=4, fontface="bold")+ 181 | #geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold")+ 182 | labs(y="Weight at pupation (mg)", x="Mismatch with oak budburst date (days)")+ 183 | scale_y_continuous(breaks=seq(15,75, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 184 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 185 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 186 | raw_weight 187 | # ggsave(filename="_results/PupWeight_raw.png", plot=raw_weight , device="png", width=200, height=150, units="mm", dpi="print") 188 | 189 | 190 | # Fit linear mixed model #### 191 | #----------------------------------- 192 | lm1 <- lmer(PupaWeight ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), data=d_pupa) 193 | anova1 <- anova(lm1) %>% as.data.frame() # interaction not significant 194 | anova1$mod <- "lm1" 195 | 196 | lm2 <- update(lm1, ~ . - MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 197 | anova2 <- anova(lm2) %>% as.data.frame() # Squared mismatch not significant 198 | anova2$mod <- "lm2" 199 | 200 | lm3 <- update(lm2, ~ . - MismTreat2) # simplify model 201 | anova3 <- anova(lm3) %>% as.data.frame() # PhotoTreat and MismTreat significant 202 | anova3$mod <- "lm3" 203 | 204 | # Still there if exclude first time point with low sample size? 205 | lm4 <- lmer(PupaWeight ~ -1 + MismTreat1 + PhotoTreat + (1|MotherID), data=filter(d_pupa, MismTreat!=-4)) 206 | anova(lm4) # yes 207 | 208 | 209 | # Final model #### 210 | lm_final <- lm3 211 | summary(lm_final) 212 | lm_res <- summary(lm_final)$coefficients %>% as.data.frame 213 | 214 | plot(lm_final) #equal variance? ok 215 | qqnorm(resid(lm_final)) #normally distributed? ok 216 | qqline(resid(lm_final)) 217 | 218 | # write.csv(lm_res, file="_results/output_PupaWeight_lmer.csv", row.names=T) 219 | # write.csv(rbind(anova1, anova2, anova3), file="_results/anova_PupaWeight_lmer.csv", row.names=T) 220 | 221 | # Get predictions #### 222 | lm.pred <- d_pupa[!duplicated(d_pupa[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 223 | lm.pred$pred <- predict(lm_final, newdata=lm.pred, type="response") 224 | head(lm.pred) 225 | 226 | # Visualize predictions #### 227 | pred1 <- Rmisc::summarySE(lm.pred, measurevar="pred", groupvars=c("MismTreat", "PhotoTreat")) # significant effect of photoperiod, so show separate means 228 | pred1$samplesize <- weight$N 229 | pred1$pos <- ifelse(is.na(pred1$se)==T, 0, pred1$se) # position of sample size labels 230 | 231 | # add predictions to raw data figure 232 | p_weight <- raw_weight + #geom_line(data=pred1, aes(y=pred)) + 233 | geom_smooth(data=pred1, aes(y=pred, col=PhotoTreat), se=F, method=lm)+ 234 | geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-1.5), col="black", size=4, fontface="bold")+ 235 | geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold") 236 | p_weight 237 | # ggsave(filename="_results/PupWeight_wpred_rev.png", plot=p_weight, device="png", width=200, height=150, units="mm", dpi="print") 238 | 239 | 240 | 241 | #-------------------------------------------- 242 | # Get fitness curve #### 243 | #-------------------------------------------- 244 | 245 | # Don't care about PhotoTreat effect, drop from models #### 246 | glm_fit <- glmer(Event ~ MismTreat1 + MismTreat2 + (1 | MotherID), family="binomial", data=d_surv) 247 | lm_fit <- lmer(PupaWeight ~ MismTreat1 + (1 | MotherID), data=d_pupa) 248 | 249 | # Get predictions to use for curve #### 250 | glm.fit <- d_surv[!duplicated(d_surv[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 251 | glm.fit$pred <- predict(glm_fit, newdata=glm.fit, type="response") # predictions are probability of dying now 252 | glm.fit$survpred <- (1-glm.fit$pred) 253 | 254 | lm.fit <- d_pupa[!duplicated(d_pupa[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 255 | lm.fit$pred <- predict(lm_fit, newdata=lm.fit, type="response") 256 | 257 | head(glm.fit) # pred = probability of dying, survpred=1-pred, 220 observations = 22 mothers * 10 MismTreat groups 258 | head(lm.fit) # pred=predicted weight from lmer, only 154 observations 259 | 260 | 261 | # Fit curve to absolute fitness #### 262 | #----------------------------------- 263 | RelFit <- merge(glm.fit[,c("MotherID", "MismTreat", "survpred")], lm.fit[,c("MotherID", "MismTreat", "pred")], by=c("MotherID", "MismTreat"), all=T) 264 | colnames(RelFit)[c(3,4)] <- c("survpred", "pupwpred") 265 | RelFit$Fit <- RelFit$survpred*RelFit$pupwpred # multiply absolute values 266 | head(RelFit) # can only do for 154 observations, clutches with >=1 caterpillar surviving until pupation 267 | table(RelFit$MismTreat, is.na(RelFit$Fit)) # for the other clutches, fitness = 0 268 | RelFit$Fit2 <- ifelse(is.na(RelFit$Fit)==T, 0, RelFit$Fit) 269 | 270 | # loess model to describe the curve #### 271 | loess_mod <- loess(Fit2~ -1 + MismTreat, data=RelFit) 272 | summary(loess_mod) 273 | 274 | curve <- RelFit[!duplicated(RelFit[,c("MismTreat")]),] %>% select(MismTreat) 275 | curve$pred <- predict(loess_mod, newdata=curve) 276 | curve <- arrange(curve, MismTreat) 277 | curve # peak at day2 278 | curve$rel <- curve$pred/filter(curve, MismTreat==2)$pred # expressive relative to peak 279 | 280 | RelFit$rel <- RelFit$Fit2/mean(filter(RelFit, MismTreat==2)$Fit2) 281 | 282 | RelFit_means <- Rmisc::summarySE(RelFit, measurevar="rel", groupvars=c("MismTreat")) 283 | #RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_pupa, length)$MotherID # number of caterpillars curve is based on 284 | RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_surv, length)$MotherID # number of caterpillars curve is based on = all 285 | RelFit_means$curve <- curve$rel 286 | head(RelFit_means) 287 | # write.csv(RelFit_means, file="_results/RelFitness_rev.csv", row.names=F) 288 | 289 | p_relfit <- ggplot(data=RelFit, aes(x=MismTreat, y=rel)) + 290 | geom_jitter(size=3, alpha=0.4, height=0, width=0.25, shape=21, fill="dodgerblue2", col="dodgerblue4")+ 291 | geom_point(data=RelFit_means, size=5) + 292 | geom_errorbar(data=RelFit_means, aes(ymax = rel+se, ymin=rel-se), width=0.3) + 293 | #geom_line(data=curve, aes(y=pred), col="darkred", size=1)+ 294 | #geom_smooth(data=curve, se=F, col="red3", size=1)+ # makes it look more like a smooth line, but otherwise exactly the same as using geom_line 295 | geom_text(data=RelFit_means,aes(label=samplesize, y=rel+0.12), col="black", size=5, fontface="bold")+ # number of caterpillars 296 | geom_hline(yintercept=1, linetype="dashed")+ 297 | labs(y="Relative fitness", x="Mismatch with oak budburst date (days)")+ 298 | scale_y_continuous(lim=c(0,1.21), breaks=seq(0,1.6, by=0.2))+ scale_x_continuous(breaks=seq(-4,5, by=1))+ #lim=c(-0.1,1.3) 299 | theme(legend.position="none")+ 300 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 301 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 302 | p_relfit 303 | # ggsave(filename="_results/FitnessCurve_rev.png", plot=p_relfit, device="png", width=200, height=150, units="mm", dpi="print") 304 | 305 | 306 | 307 | 308 | sessionInfo() %>% capture.output(file="_src/env_CatFoodExp2021_analysis.txt") 309 | -------------------------------------------------------------------------------- /04_Reproducible/2_scripts/1a_CatFoodExp2021_analysis_fitness.R: -------------------------------------------------------------------------------- 1 | # Analysis of Phenological mismatch experiment 2021 #### 2 | # Manipulated timing of egg hatching of eggs from wild Mothers caught in 2020 3 | # Either hatching on day of budburst (Day0), before (Day-4 to -1), or after (Day+1 to +5) 4 | # Disentangle effects of photoperiod and food quality: photoperiod treatment (changing or constant) 5 | 6 | # before start download the dataset 'CatFood2021_deposit.csv' 7 | # from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 8 | 9 | # the dataset should be saved in the folder 1_data 10 | 11 | 12 | # Open R project in main folder 13 | 14 | # Restore library 15 | renv::restore() 16 | 17 | # Load packages 18 | #----------------------------------- 19 | library(tidyverse) 20 | library(cowplot) 21 | theme_set(theme_cowplot()) #white background instead of grey -> don't load if want grey grid 22 | library(lme4) 23 | library(lmerTest) 24 | library(Rmisc) 25 | 26 | 27 | # Load data #### 28 | #----------------------------------- 29 | d <- read.csv("1_data/CatFood2021_deposit.csv") 30 | head(d) 31 | 32 | # renaming TubeID as MotherID to match the terminology used in the Statistical section of the paper 33 | d <- rename(d, MotherID = TubeID) 34 | 35 | length(unique(d$MotherID)) # should be 22 mothers 36 | table(d$Treatment) # photoperiod and mismatch treatment coded in one variable 37 | 38 | 39 | # Descriptives 40 | #----------------------------------- 41 | 42 | # N per Area 43 | table(d[!duplicated(d$MotherID), "AreaShortName"]) 44 | 45 | 46 | #--------------------------------------------------------------------------------------------------------------------------- 47 | # Fitness curve #### 48 | #---------------------------------- 49 | # RQ1: What are the fitness consequences of day to day timing (a)synchrony with budburst? #### 50 | 51 | # Survival data #### 52 | d_surv <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment)) %>% 53 | select(MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, DeadAprilDay, PupationAprilDay) %>% 54 | pivot_longer(cols=c(DeadAprilDay, PupationAprilDay), names_to="Info", values_to="TimeOfEvent") %>% 55 | filter(!is.na(TimeOfEvent)) %>% 56 | mutate(Event=ifelse(Info=="DeadAprilDay", 1, 0), Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 57 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 58 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 59 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 60 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 61 | mutate(MismTreat1=MismTreat+5, # no negatives to be able to fit squared term 62 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 63 | # Vidisha coded it as TimeOfEvent=DeadAprilDay or PupationAprilDay, with event=Died or Survived 64 | head(d_surv) 65 | str(d_surv) 66 | table(d_surv$MismTreat2) 67 | 68 | length(unique(d_surv$CaterpillarID)) # should be 976 69 | 70 | 71 | #----------------------------------- 72 | # Survival analysis #### 73 | #----------------------------------- 74 | levels(d_surv$Treatment) 75 | levels(d_surv$PhotoTreat) 76 | levels(d_surv$MismTreatf) # as factor or not? Marcel thinks not #### 77 | levels(d_surv$MotherID) 78 | table(d_surv$TimeOfEvent) 79 | table(d_surv$Event) # this variable corresponds to "survival" as defined in the paper (e.g., the response variable in the first binomial mixed-effect model) 80 | 81 | # Visualize survival probabilities #### 82 | head(d_surv) 83 | 84 | surv_probs <- aggregate(Event~MismTreat + PhotoTreat + MotherID, d_surv, sum) # per mother 85 | surv_probs$samplesize <- aggregate(Info~MismTreat + PhotoTreat + MotherID, d_surv, length)$Info 86 | surv_probs$probs <- 100 - (surv_probs$Event/surv_probs$samplesize*100) # event = death 87 | head(surv_probs) 88 | 89 | surv_avg <- Rmisc::summarySE(surv_probs, measurevar="probs", groupvars=c("MismTreat")) # average of two photoperiod treatments 90 | surv_avg$samplesize <- aggregate(Info~MismTreat, d_surv, length)$Info 91 | surv_avg 92 | 93 | raw_surv <- ggplot(data=surv_avg, aes(x=MismTreat, y=probs))+ 94 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 95 | geom_jitter(data=surv_probs, aes(col=PhotoTreat), alpha=0.3, size=3, height=0.5, width=0.25)+ 96 | geom_point(size=5, col="black") + 97 | geom_errorbar(aes(ymax = probs+se, ymin=probs-se), width=0.3, col="black") + 98 | geom_text(aes(label=samplesize, y=probs+8.3), col="black", size=4,fontface="bold")+ # N caterpillars in each treatment 99 | labs(y="Survival (%)", x="Mismatch with oak budburst date (days)")+ 100 | scale_y_continuous(breaks=seq(0,100, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 101 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 102 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 103 | raw_surv 104 | # ggsave(filename="_results/Survival_raw.png", plot=raw_surv , device="png", width=200, height=150, units="mm", dpi="print") 105 | 106 | 107 | # Fit binomial model #### 108 | #----------------------------------- 109 | head(d_surv) # test if probability of survival differs between treatments 110 | 111 | glm1 <- glmer(Event ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), family=binomial, data=d_surv, 112 | na.action="na.fail", control=glmerControl(calc.derivs=F)) # helps convergence 113 | anova1 <- drop1(glm1,test="Chi") %>% as.data.frame # interaction not significant; the use of Chi-square test to determine statistical significance should be explicitly mention in the paper 114 | anova1$mod <- "glm1" 115 | 116 | glm2 <- update(glm1, ~ . -MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 117 | anova2 <- drop1(glm2,test="Chi") %>% as.data.frame #no effect of PhotoTreatment, but effect of MismTreat and MismTreat^2 118 | anova2$mod <- "glm2" 119 | 120 | # Final model #### 121 | glm_final <- glm2 122 | summary(glm_final)# Estimates are log odds 123 | glm_res <- summary(glm_final)$coefficients %>% as.data.frame 124 | 125 | # write.csv(glm_res, file="_results/output_Surv_glmer.csv", row.names=T) 126 | # write.csv(rbind(anova1, anova2), file="_results/anova_Surv_glmer.csv", row.names=T) 127 | 128 | # Get predictions #### 129 | glm.pred <- d_surv[!duplicated(d_surv[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 130 | glm.pred$pred <- predict(glm_final, newdata=glm.pred, type="response") # predictions are probability of dying now 131 | glm.pred$survprob <- (1-glm.pred$pred) 132 | aggregate(survprob~MismTreat, data=glm.pred, mean) # peak at Day2 133 | glm.pred$rel <- glm.pred$survprob/mean(filter(glm.pred, MismTreat==1)$survprob) # expressive relative to peak 134 | head(glm.pred) 135 | 136 | # Visualize predictions #### 137 | pred <- Rmisc::summarySE(glm.pred, measurevar="survprob", groupvars=c("MismTreat")) # average of two photoperiod treatments 138 | pred$samplesize <- aggregate(CaterpillarID~MismTreat, data=d_surv, length)$CaterpillarID 139 | 140 | # Add predictions to raw data figure 141 | p_surv <- raw_surv + #geom_line(data=pred, aes(y=survprob*100)) + 142 | geom_smooth(data=pred, aes(y=survprob*100), se=F, col="red3") 143 | p_surv 144 | # ggsave(filename="_results/Survival_wpred_rev.png", plot=p_surv, device="png", width=200, height=150, units="mm", dpi="print") 145 | 146 | rm(anova1, anova2, glm_res, glm1, glm2, pred, surv_probs, surv_avg, raw_surv) #cleanup 147 | 148 | 149 | #----------------------------------- 150 | # Pupation weight analysis #### 151 | #----------------------------------- 152 | head(d) 153 | 154 | d_pupa <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment), PupaWeight=PupaWeight_ingrams*1000) %>% 155 | select(ExperimentName, MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, PupationAprilDay, PupaWeight) %>% 156 | filter(!is.na(PupationAprilDay)) %>% 157 | mutate(Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 158 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 159 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 160 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 161 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 162 | mutate(MismTreat1=MismTreat+5, # no negatives 163 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 164 | head(d_pupa) # 346 individuals survived until pupation 165 | nrow(d_pupa)/nrow(d)*100 # ~35% 166 | 167 | 168 | # Visualize #### 169 | weight <- Rmisc::summarySE(d_pupa, measurevar="PupaWeight", groupvars=c("MismTreat", "PhotoTreat")) 170 | weight$pos <- ifelse(is.na(weight$se)==T, 0, weight$se) # position of sample size labels 171 | weight 172 | 173 | raw_weight <- ggplot(data=weight, aes(x=MismTreat, y=PupaWeight, col=PhotoTreat, fill=PhotoTreat))+ 174 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 175 | scale_fill_manual(values=c("grey27", "orangered2"))+ 176 | geom_jitter(data=d_pupa, aes(col=PhotoTreat), alpha=0.3, size=3, height=0, width=0.25)+ #alpha=0.3, size=2, height=0, width=0.25 177 | geom_errorbar(data=filter(weight, PhotoTreat=="Changing"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="black") + 178 | geom_errorbar(data=filter(weight, PhotoTreat=="Constant"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="orangered4") + 179 | geom_point(size=5, shape=21, col="black")+ 180 | #geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-2.3), col="black", size=4, fontface="bold")+ 181 | #geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold")+ 182 | labs(y="Weight at pupation (mg)", x="Mismatch with oak budburst date (days)")+ 183 | scale_y_continuous(breaks=seq(15,75, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 184 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 185 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 186 | raw_weight 187 | # ggsave(filename="_results/PupWeight_raw.png", plot=raw_weight , device="png", width=200, height=150, units="mm", dpi="print") 188 | 189 | 190 | # Fit linear mixed model #### 191 | #----------------------------------- 192 | lm1 <- lmer(PupaWeight ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), data=d_pupa) 193 | anova1 <- anova(lm1) %>% as.data.frame() # interaction not significant 194 | anova1$mod <- "lm1" 195 | 196 | lm2 <- update(lm1, ~ . - MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 197 | anova2 <- anova(lm2) %>% as.data.frame() # Squared mismatch not significant 198 | anova2$mod <- "lm2" 199 | 200 | lm3 <- update(lm2, ~ . - MismTreat2) # simplify model 201 | anova3 <- anova(lm3) %>% as.data.frame() # PhotoTreat and MismTreat significant 202 | anova3$mod <- "lm3" 203 | 204 | # Still there if exclude first time point with low sample size? 205 | lm4 <- lmer(PupaWeight ~ -1 + MismTreat1 + PhotoTreat + (1|MotherID), data=filter(d_pupa, MismTreat!=-4)) 206 | anova(lm4) # yes 207 | 208 | 209 | # Final model #### 210 | lm_final <- lm3 211 | summary(lm_final) 212 | lm_res <- summary(lm_final)$coefficients %>% as.data.frame 213 | 214 | plot(lm_final) #equal variance? ok 215 | qqnorm(resid(lm_final)) #normally distributed? ok 216 | qqline(resid(lm_final)) 217 | 218 | # write.csv(lm_res, file="_results/output_PupaWeight_lmer.csv", row.names=T) 219 | # write.csv(rbind(anova1, anova2, anova3), file="_results/anova_PupaWeight_lmer.csv", row.names=T) 220 | 221 | # Get predictions #### 222 | lm.pred <- d_pupa[!duplicated(d_pupa[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 223 | lm.pred$pred <- predict(lm_final, newdata=lm.pred, type="response") 224 | head(lm.pred) 225 | 226 | # Visualize predictions #### 227 | pred1 <- Rmisc::summarySE(lm.pred, measurevar="pred", groupvars=c("MismTreat", "PhotoTreat")) # significant effect of photoperiod, so show separate means 228 | pred1$samplesize <- weight$N 229 | pred1$pos <- ifelse(is.na(pred1$se)==T, 0, pred1$se) # position of sample size labels 230 | 231 | # add predictions to raw data figure 232 | p_weight <- raw_weight + #geom_line(data=pred1, aes(y=pred)) + 233 | geom_smooth(data=pred1, aes(y=pred, col=PhotoTreat), se=F, method=lm)+ 234 | geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-1.5), col="black", size=4, fontface="bold")+ 235 | geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold") 236 | p_weight 237 | # ggsave(filename="_results/PupWeight_wpred_rev.png", plot=p_weight, device="png", width=200, height=150, units="mm", dpi="print") 238 | 239 | 240 | 241 | #-------------------------------------------- 242 | # Get fitness curve #### 243 | #-------------------------------------------- 244 | 245 | # Don't care about PhotoTreat effect, drop from models #### 246 | glm_fit <- glmer(Event ~ MismTreat1 + MismTreat2 + (1 | MotherID), family="binomial", data=d_surv) 247 | lm_fit <- lmer(PupaWeight ~ MismTreat1 + (1 | MotherID), data=d_pupa) 248 | 249 | # Get predictions to use for curve #### 250 | glm.fit <- d_surv[!duplicated(d_surv[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 251 | glm.fit$pred <- predict(glm_fit, newdata=glm.fit, type="response") # predictions are probability of dying now 252 | glm.fit$survpred <- (1-glm.fit$pred) 253 | 254 | lm.fit <- d_pupa[!duplicated(d_pupa[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 255 | lm.fit$pred <- predict(lm_fit, newdata=lm.fit, type="response") 256 | 257 | head(glm.fit) # pred = probability of dying, survpred=1-pred, 220 observations = 22 mothers * 10 MismTreat groups 258 | head(lm.fit) # pred=predicted weight from lmer, only 154 observations 259 | 260 | 261 | # Fit curve to absolute fitness #### 262 | #----------------------------------- 263 | RelFit <- merge(glm.fit[,c("MotherID", "MismTreat", "survpred")], lm.fit[,c("MotherID", "MismTreat", "pred")], by=c("MotherID", "MismTreat"), all=T) 264 | colnames(RelFit)[c(3,4)] <- c("survpred", "pupwpred") 265 | RelFit$Fit <- RelFit$survpred*RelFit$pupwpred # multiply absolute values 266 | head(RelFit) # can only do for 154 observations, clutches with >=1 caterpillar surviving until pupation 267 | table(RelFit$MismTreat, is.na(RelFit$Fit)) # for the other clutches, fitness = 0 268 | RelFit$Fit2 <- ifelse(is.na(RelFit$Fit)==T, 0, RelFit$Fit) 269 | 270 | # loess model to describe the curve #### 271 | loess_mod <- loess(Fit2~ -1 + MismTreat, data=RelFit) 272 | summary(loess_mod) 273 | 274 | curve <- RelFit[!duplicated(RelFit[,c("MismTreat")]),] %>% select(MismTreat) 275 | curve$pred <- predict(loess_mod, newdata=curve) 276 | curve <- arrange(curve, MismTreat) 277 | curve # peak at day2 278 | curve$rel <- curve$pred/filter(curve, MismTreat==2)$pred # expressive relative to peak 279 | 280 | RelFit$rel <- RelFit$Fit2/mean(filter(RelFit, MismTreat==2)$Fit2) 281 | 282 | RelFit_means <- Rmisc::summarySE(RelFit, measurevar="rel", groupvars=c("MismTreat")) 283 | #RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_pupa, length)$MotherID # number of caterpillars curve is based on 284 | RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_surv, length)$MotherID # number of caterpillars curve is based on = all 285 | RelFit_means$curve <- curve$rel 286 | head(RelFit_means) 287 | # write.csv(RelFit_means, file="_results/RelFitness_rev.csv", row.names=F) 288 | 289 | p_relfit <- ggplot(data=RelFit, aes(x=MismTreat, y=rel)) + 290 | geom_jitter(size=3, alpha=0.4, height=0, width=0.25, shape=21, fill="dodgerblue2", col="dodgerblue4")+ 291 | geom_point(data=RelFit_means, size=5) + 292 | geom_errorbar(data=RelFit_means, aes(ymax = rel+se, ymin=rel-se), width=0.3) + 293 | #geom_line(data=curve, aes(y=pred), col="darkred", size=1)+ 294 | #geom_smooth(data=curve, se=F, col="red3", size=1)+ # makes it look more like a smooth line, but otherwise exactly the same as using geom_line 295 | geom_text(data=RelFit_means,aes(label=samplesize, y=rel+0.12), col="black", size=5, fontface="bold")+ # number of caterpillars 296 | geom_hline(yintercept=1, linetype="dashed")+ 297 | labs(y="Relative fitness", x="Mismatch with oak budburst date (days)")+ 298 | scale_y_continuous(lim=c(0,1.21), breaks=seq(0,1.6, by=0.2))+ scale_x_continuous(breaks=seq(-4,5, by=1))+ #lim=c(-0.1,1.3) 299 | theme(legend.position="none")+ 300 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 301 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 302 | p_relfit 303 | # ggsave(filename="_results/FitnessCurve_rev.png", plot=p_relfit, device="png", width=200, height=150, units="mm", dpi="print") 304 | 305 | 306 | 307 | 308 | sessionInfo() %>% capture.output(file="_src/env_CatFoodExp2021_analysis.txt") 309 | -------------------------------------------------------------------------------- /05_Organization_Structure/2_scripts/1a_CatFoodExp2021_analysis_fitness.R: -------------------------------------------------------------------------------- 1 | # Analysis of Phenological mismatch experiment 2021 #### 2 | # Manipulated timing of egg hatching of eggs from wild Mothers caught in 2020 3 | # Either hatching on day of budburst (Day0), before (Day-4 to -1), or after (Day+1 to +5) 4 | # Disentangle effects of photoperiod and food quality: photoperiod treatment (changing or constant) 5 | 6 | # before start download the dataset 'CatFood2021_deposit.csv' 7 | # from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 8 | 9 | # the dataset should be saved in the folder 1_data 10 | 11 | 12 | # Open R project in main folder 13 | 14 | # Restore library 15 | renv::restore() 16 | 17 | # Load packages 18 | #----------------------------------- 19 | library(tidyverse) 20 | library(cowplot) 21 | theme_set(theme_cowplot()) #white background instead of grey -> don't load if want grey grid 22 | library(lme4) 23 | library(lmerTest) 24 | library(Rmisc) 25 | 26 | 27 | # Load data #### 28 | #----------------------------------- 29 | d <- read.csv("1_data/CatFood2021_deposit.csv") 30 | head(d) 31 | 32 | # renaming TubeID as MotherID to match the terminology used in the Statistical section of the paper 33 | d <- rename(d, MotherID = TubeID) 34 | 35 | length(unique(d$MotherID)) # should be 22 mothers 36 | table(d$Treatment) # photoperiod and mismatch treatment coded in one variable 37 | 38 | 39 | # Descriptives 40 | #----------------------------------- 41 | 42 | # N per Area 43 | table(d[!duplicated(d$MotherID), "AreaShortName"]) 44 | 45 | 46 | #--------------------------------------------------------------------------------------------------------------------------- 47 | # Fitness curve #### 48 | #---------------------------------- 49 | # RQ1: What are the fitness consequences of day to day timing (a)synchrony with budburst? #### 50 | 51 | # Survival data #### 52 | d_surv <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment)) %>% 53 | select(MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, DeadAprilDay, PupationAprilDay) %>% 54 | pivot_longer(cols=c(DeadAprilDay, PupationAprilDay), names_to="Info", values_to="TimeOfEvent") %>% 55 | filter(!is.na(TimeOfEvent)) %>% 56 | mutate(Event=ifelse(Info=="DeadAprilDay", 1, 0), Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 57 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 58 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 59 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 60 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 61 | mutate(MismTreat1=MismTreat+5, # no negatives to be able to fit squared term 62 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 63 | # Vidisha coded it as TimeOfEvent=DeadAprilDay or PupationAprilDay, with event=Died or Survived 64 | head(d_surv) 65 | str(d_surv) 66 | table(d_surv$MismTreat2) 67 | 68 | length(unique(d_surv$CaterpillarID)) # should be 976 69 | 70 | 71 | #----------------------------------- 72 | # Survival analysis #### 73 | #----------------------------------- 74 | levels(d_surv$Treatment) 75 | levels(d_surv$PhotoTreat) 76 | levels(d_surv$MismTreatf) # as factor or not? Marcel thinks not #### 77 | levels(d_surv$MotherID) 78 | table(d_surv$TimeOfEvent) 79 | table(d_surv$Event) # this variable corresponds to "survival" as defined in the paper (e.g., the response variable in the first binomial mixed-effect model) 80 | 81 | # Visualize survival probabilities #### 82 | head(d_surv) 83 | 84 | surv_probs <- aggregate(Event~MismTreat + PhotoTreat + MotherID, d_surv, sum) # per mother 85 | surv_probs$samplesize <- aggregate(Info~MismTreat + PhotoTreat + MotherID, d_surv, length)$Info 86 | surv_probs$probs <- 100 - (surv_probs$Event/surv_probs$samplesize*100) # event = death 87 | head(surv_probs) 88 | 89 | surv_avg <- Rmisc::summarySE(surv_probs, measurevar="probs", groupvars=c("MismTreat")) # average of two photoperiod treatments 90 | surv_avg$samplesize <- aggregate(Info~MismTreat, d_surv, length)$Info 91 | surv_avg 92 | 93 | raw_surv <- ggplot(data=surv_avg, aes(x=MismTreat, y=probs))+ 94 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 95 | geom_jitter(data=surv_probs, aes(col=PhotoTreat), alpha=0.3, size=3, height=0.5, width=0.25)+ 96 | geom_point(size=5, col="black") + 97 | geom_errorbar(aes(ymax = probs+se, ymin=probs-se), width=0.3, col="black") + 98 | geom_text(aes(label=samplesize, y=probs+8.3), col="black", size=4,fontface="bold")+ # N caterpillars in each treatment 99 | labs(y="Survival (%)", x="Mismatch with oak budburst date (days)")+ 100 | scale_y_continuous(breaks=seq(0,100, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 101 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 102 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 103 | raw_surv 104 | # ggsave(filename="_results/Survival_raw.png", plot=raw_surv , device="png", width=200, height=150, units="mm", dpi="print") 105 | 106 | 107 | # Fit binomial model #### 108 | #----------------------------------- 109 | head(d_surv) # test if probability of survival differs between treatments 110 | 111 | glm1 <- glmer(Event ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), family=binomial, data=d_surv, 112 | na.action="na.fail", control=glmerControl(calc.derivs=F)) # helps convergence 113 | anova1 <- drop1(glm1,test="Chi") %>% as.data.frame # interaction not significant; the use of Chi-square test to determine statistical significance should be explicitly mention in the paper 114 | anova1$mod <- "glm1" 115 | 116 | glm2 <- update(glm1, ~ . -MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 117 | anova2 <- drop1(glm2,test="Chi") %>% as.data.frame #no effect of PhotoTreatment, but effect of MismTreat and MismTreat^2 118 | anova2$mod <- "glm2" 119 | 120 | # Final model #### 121 | glm_final <- glm2 122 | summary(glm_final)# Estimates are log odds 123 | glm_res <- summary(glm_final)$coefficients %>% as.data.frame 124 | 125 | # write.csv(glm_res, file="_results/output_Surv_glmer.csv", row.names=T) 126 | # write.csv(rbind(anova1, anova2), file="_results/anova_Surv_glmer.csv", row.names=T) 127 | 128 | # Get predictions #### 129 | glm.pred <- d_surv[!duplicated(d_surv[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 130 | glm.pred$pred <- predict(glm_final, newdata=glm.pred, type="response") # predictions are probability of dying now 131 | glm.pred$survprob <- (1-glm.pred$pred) 132 | aggregate(survprob~MismTreat, data=glm.pred, mean) # peak at Day2 133 | glm.pred$rel <- glm.pred$survprob/mean(filter(glm.pred, MismTreat==1)$survprob) # expressive relative to peak 134 | head(glm.pred) 135 | 136 | # Visualize predictions #### 137 | pred <- Rmisc::summarySE(glm.pred, measurevar="survprob", groupvars=c("MismTreat")) # average of two photoperiod treatments 138 | pred$samplesize <- aggregate(CaterpillarID~MismTreat, data=d_surv, length)$CaterpillarID 139 | 140 | # Add predictions to raw data figure 141 | p_surv <- raw_surv + #geom_line(data=pred, aes(y=survprob*100)) + 142 | geom_smooth(data=pred, aes(y=survprob*100), se=F, col="red3") 143 | p_surv 144 | # ggsave(filename="_results/Survival_wpred_rev.png", plot=p_surv, device="png", width=200, height=150, units="mm", dpi="print") 145 | 146 | rm(anova1, anova2, glm_res, glm1, glm2, pred, surv_probs, surv_avg, raw_surv) #cleanup 147 | 148 | 149 | #----------------------------------- 150 | # Pupation weight analysis #### 151 | #----------------------------------- 152 | head(d) 153 | 154 | d_pupa <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment), PupaWeight=PupaWeight_ingrams*1000) %>% 155 | select(ExperimentName, MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, PupationAprilDay, PupaWeight) %>% 156 | filter(!is.na(PupationAprilDay)) %>% 157 | mutate(Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 158 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 159 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 160 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 161 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 162 | mutate(MismTreat1=MismTreat+5, # no negatives 163 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 164 | head(d_pupa) # 346 individuals survived until pupation 165 | nrow(d_pupa)/nrow(d)*100 # ~35% 166 | 167 | 168 | # Visualize #### 169 | weight <- Rmisc::summarySE(d_pupa, measurevar="PupaWeight", groupvars=c("MismTreat", "PhotoTreat")) 170 | weight$pos <- ifelse(is.na(weight$se)==T, 0, weight$se) # position of sample size labels 171 | weight 172 | 173 | raw_weight <- ggplot(data=weight, aes(x=MismTreat, y=PupaWeight, col=PhotoTreat, fill=PhotoTreat))+ 174 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 175 | scale_fill_manual(values=c("grey27", "orangered2"))+ 176 | geom_jitter(data=d_pupa, aes(col=PhotoTreat), alpha=0.3, size=3, height=0, width=0.25)+ #alpha=0.3, size=2, height=0, width=0.25 177 | geom_errorbar(data=filter(weight, PhotoTreat=="Changing"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="black") + 178 | geom_errorbar(data=filter(weight, PhotoTreat=="Constant"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="orangered4") + 179 | geom_point(size=5, shape=21, col="black")+ 180 | #geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-2.3), col="black", size=4, fontface="bold")+ 181 | #geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold")+ 182 | labs(y="Weight at pupation (mg)", x="Mismatch with oak budburst date (days)")+ 183 | scale_y_continuous(breaks=seq(15,75, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 184 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 185 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 186 | raw_weight 187 | # ggsave(filename="_results/PupWeight_raw.png", plot=raw_weight , device="png", width=200, height=150, units="mm", dpi="print") 188 | 189 | 190 | # Fit linear mixed model #### 191 | #----------------------------------- 192 | lm1 <- lmer(PupaWeight ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), data=d_pupa) 193 | anova1 <- anova(lm1) %>% as.data.frame() # interaction not significant 194 | anova1$mod <- "lm1" 195 | 196 | lm2 <- update(lm1, ~ . - MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 197 | anova2 <- anova(lm2) %>% as.data.frame() # Squared mismatch not significant 198 | anova2$mod <- "lm2" 199 | 200 | lm3 <- update(lm2, ~ . - MismTreat2) # simplify model 201 | anova3 <- anova(lm3) %>% as.data.frame() # PhotoTreat and MismTreat significant 202 | anova3$mod <- "lm3" 203 | 204 | # Still there if exclude first time point with low sample size? 205 | lm4 <- lmer(PupaWeight ~ -1 + MismTreat1 + PhotoTreat + (1|MotherID), data=filter(d_pupa, MismTreat!=-4)) 206 | anova(lm4) # yes 207 | 208 | 209 | # Final model #### 210 | lm_final <- lm3 211 | summary(lm_final) 212 | lm_res <- summary(lm_final)$coefficients %>% as.data.frame 213 | 214 | plot(lm_final) #equal variance? ok 215 | qqnorm(resid(lm_final)) #normally distributed? ok 216 | qqline(resid(lm_final)) 217 | 218 | # write.csv(lm_res, file="_results/output_PupaWeight_lmer.csv", row.names=T) 219 | # write.csv(rbind(anova1, anova2, anova3), file="_results/anova_PupaWeight_lmer.csv", row.names=T) 220 | 221 | # Get predictions #### 222 | lm.pred <- d_pupa[!duplicated(d_pupa[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 223 | lm.pred$pred <- predict(lm_final, newdata=lm.pred, type="response") 224 | head(lm.pred) 225 | 226 | # Visualize predictions #### 227 | pred1 <- Rmisc::summarySE(lm.pred, measurevar="pred", groupvars=c("MismTreat", "PhotoTreat")) # significant effect of photoperiod, so show separate means 228 | pred1$samplesize <- weight$N 229 | pred1$pos <- ifelse(is.na(pred1$se)==T, 0, pred1$se) # position of sample size labels 230 | 231 | # add predictions to raw data figure 232 | p_weight <- raw_weight + #geom_line(data=pred1, aes(y=pred)) + 233 | geom_smooth(data=pred1, aes(y=pred, col=PhotoTreat), se=F, method=lm)+ 234 | geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-1.5), col="black", size=4, fontface="bold")+ 235 | geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold") 236 | p_weight 237 | # ggsave(filename="_results/PupWeight_wpred_rev.png", plot=p_weight, device="png", width=200, height=150, units="mm", dpi="print") 238 | 239 | 240 | 241 | #-------------------------------------------- 242 | # Get fitness curve #### 243 | #-------------------------------------------- 244 | 245 | # Don't care about PhotoTreat effect, drop from models #### 246 | glm_fit <- glmer(Event ~ MismTreat1 + MismTreat2 + (1 | MotherID), family="binomial", data=d_surv) 247 | lm_fit <- lmer(PupaWeight ~ MismTreat1 + (1 | MotherID), data=d_pupa) 248 | 249 | # Get predictions to use for curve #### 250 | glm.fit <- d_surv[!duplicated(d_surv[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 251 | glm.fit$pred <- predict(glm_fit, newdata=glm.fit, type="response") # predictions are probability of dying now 252 | glm.fit$survpred <- (1-glm.fit$pred) 253 | 254 | lm.fit <- d_pupa[!duplicated(d_pupa[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 255 | lm.fit$pred <- predict(lm_fit, newdata=lm.fit, type="response") 256 | 257 | head(glm.fit) # pred = probability of dying, survpred=1-pred, 220 observations = 22 mothers * 10 MismTreat groups 258 | head(lm.fit) # pred=predicted weight from lmer, only 154 observations 259 | 260 | 261 | # Fit curve to absolute fitness #### 262 | #----------------------------------- 263 | RelFit <- merge(glm.fit[,c("MotherID", "MismTreat", "survpred")], lm.fit[,c("MotherID", "MismTreat", "pred")], by=c("MotherID", "MismTreat"), all=T) 264 | colnames(RelFit)[c(3,4)] <- c("survpred", "pupwpred") 265 | RelFit$Fit <- RelFit$survpred*RelFit$pupwpred # multiply absolute values 266 | head(RelFit) # can only do for 154 observations, clutches with >=1 caterpillar surviving until pupation 267 | table(RelFit$MismTreat, is.na(RelFit$Fit)) # for the other clutches, fitness = 0 268 | RelFit$Fit2 <- ifelse(is.na(RelFit$Fit)==T, 0, RelFit$Fit) 269 | 270 | # loess model to describe the curve #### 271 | loess_mod <- loess(Fit2~ -1 + MismTreat, data=RelFit) 272 | summary(loess_mod) 273 | 274 | curve <- RelFit[!duplicated(RelFit[,c("MismTreat")]),] %>% select(MismTreat) 275 | curve$pred <- predict(loess_mod, newdata=curve) 276 | curve <- arrange(curve, MismTreat) 277 | curve # peak at day2 278 | curve$rel <- curve$pred/filter(curve, MismTreat==2)$pred # expressive relative to peak 279 | 280 | RelFit$rel <- RelFit$Fit2/mean(filter(RelFit, MismTreat==2)$Fit2) 281 | 282 | RelFit_means <- Rmisc::summarySE(RelFit, measurevar="rel", groupvars=c("MismTreat")) 283 | #RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_pupa, length)$MotherID # number of caterpillars curve is based on 284 | RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_surv, length)$MotherID # number of caterpillars curve is based on = all 285 | RelFit_means$curve <- curve$rel 286 | head(RelFit_means) 287 | # write.csv(RelFit_means, file="_results/RelFitness_rev.csv", row.names=F) 288 | 289 | p_relfit <- ggplot(data=RelFit, aes(x=MismTreat, y=rel)) + 290 | geom_jitter(size=3, alpha=0.4, height=0, width=0.25, shape=21, fill="dodgerblue2", col="dodgerblue4")+ 291 | geom_point(data=RelFit_means, size=5) + 292 | geom_errorbar(data=RelFit_means, aes(ymax = rel+se, ymin=rel-se), width=0.3) + 293 | #geom_line(data=curve, aes(y=pred), col="darkred", size=1)+ 294 | #geom_smooth(data=curve, se=F, col="red3", size=1)+ # makes it look more like a smooth line, but otherwise exactly the same as using geom_line 295 | geom_text(data=RelFit_means,aes(label=samplesize, y=rel+0.12), col="black", size=5, fontface="bold")+ # number of caterpillars 296 | geom_hline(yintercept=1, linetype="dashed")+ 297 | labs(y="Relative fitness", x="Mismatch with oak budburst date (days)")+ 298 | scale_y_continuous(lim=c(0,1.21), breaks=seq(0,1.6, by=0.2))+ scale_x_continuous(breaks=seq(-4,5, by=1))+ #lim=c(-0.1,1.3) 299 | theme(legend.position="none")+ 300 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 301 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 302 | p_relfit 303 | # ggsave(filename="_results/FitnessCurve_rev.png", plot=p_relfit, device="png", width=200, height=150, units="mm", dpi="print") 304 | 305 | 306 | 307 | 308 | sessionInfo() %>% capture.output(file="_src/env_CatFoodExp2021_analysis.txt") 309 | -------------------------------------------------------------------------------- /06_Other_considerations/2_scripts/1a_CatFoodExp2021_analysis_fitness.R: -------------------------------------------------------------------------------- 1 | # Analysis of Phenological mismatch experiment 2021 #### 2 | # Manipulated timing of egg hatching of eggs from wild Mothers caught in 2020 3 | # Either hatching on day of budburst (Day0), before (Day-4 to -1), or after (Day+1 to +5) 4 | # Disentangle effects of photoperiod and food quality: photoperiod treatment (changing or constant) 5 | 6 | # before start download the dataset 'CatFood2021_deposit.csv' 7 | # from Dryad repository: https://doi.org/10.5061/dryad.m905qfv5p 8 | 9 | # the dataset should be saved in the folder 1_data 10 | 11 | 12 | # Open R project in main folder 13 | 14 | # Restore library 15 | renv::restore() 16 | 17 | # Load packages 18 | #----------------------------------- 19 | library(tidyverse) 20 | library(cowplot) 21 | theme_set(theme_cowplot()) #white background instead of grey -> don't load if want grey grid 22 | library(lme4) 23 | library(lmerTest) 24 | library(Rmisc) 25 | 26 | 27 | # Load data #### 28 | #----------------------------------- 29 | d <- read.csv("1_data/CatFood2021_deposit.csv") 30 | head(d) 31 | 32 | # renaming TubeID as MotherID to match the terminology used in the Statistical section of the paper 33 | d <- rename(d, MotherID = TubeID) 34 | 35 | length(unique(d$MotherID)) # should be 22 mothers 36 | table(d$Treatment) # photoperiod and mismatch treatment coded in one variable 37 | 38 | 39 | # Descriptives 40 | #----------------------------------- 41 | 42 | # N per Area 43 | table(d[!duplicated(d$MotherID), "AreaShortName"]) 44 | 45 | 46 | #--------------------------------------------------------------------------------------------------------------------------- 47 | # Fitness curve #### 48 | #---------------------------------- 49 | # RQ1: What are the fitness consequences of day to day timing (a)synchrony with budburst? #### 50 | 51 | # Survival data #### 52 | d_surv <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment)) %>% 53 | select(MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, DeadAprilDay, PupationAprilDay) %>% 54 | pivot_longer(cols=c(DeadAprilDay, PupationAprilDay), names_to="Info", values_to="TimeOfEvent") %>% 55 | filter(!is.na(TimeOfEvent)) %>% 56 | mutate(Event=ifelse(Info=="DeadAprilDay", 1, 0), Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 57 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 58 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 59 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 60 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 61 | mutate(MismTreat1=MismTreat+5, # no negatives to be able to fit squared term 62 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 63 | # Vidisha coded it as TimeOfEvent=DeadAprilDay or PupationAprilDay, with event=Died or Survived 64 | head(d_surv) 65 | str(d_surv) 66 | table(d_surv$MismTreat2) 67 | 68 | length(unique(d_surv$CaterpillarID)) # should be 976 69 | 70 | 71 | #----------------------------------- 72 | # Survival analysis #### 73 | #----------------------------------- 74 | levels(d_surv$Treatment) 75 | levels(d_surv$PhotoTreat) 76 | levels(d_surv$MismTreatf) # as factor or not? Marcel thinks not #### 77 | levels(d_surv$MotherID) 78 | table(d_surv$TimeOfEvent) 79 | table(d_surv$Event) # this variable corresponds to "survival" as defined in the paper (e.g., the response variable in the first binomial mixed-effect model) 80 | 81 | # Visualize survival probabilities #### 82 | head(d_surv) 83 | 84 | surv_probs <- aggregate(Event~MismTreat + PhotoTreat + MotherID, d_surv, sum) # per mother 85 | surv_probs$samplesize <- aggregate(Info~MismTreat + PhotoTreat + MotherID, d_surv, length)$Info 86 | surv_probs$probs <- 100 - (surv_probs$Event/surv_probs$samplesize*100) # event = death 87 | head(surv_probs) 88 | 89 | surv_avg <- Rmisc::summarySE(surv_probs, measurevar="probs", groupvars=c("MismTreat")) # average of two photoperiod treatments 90 | surv_avg$samplesize <- aggregate(Info~MismTreat, d_surv, length)$Info 91 | surv_avg 92 | 93 | raw_surv <- ggplot(data=surv_avg, aes(x=MismTreat, y=probs))+ 94 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 95 | geom_jitter(data=surv_probs, aes(col=PhotoTreat), alpha=0.3, size=3, height=0.5, width=0.25)+ 96 | geom_point(size=5, col="black") + 97 | geom_errorbar(aes(ymax = probs+se, ymin=probs-se), width=0.3, col="black") + 98 | geom_text(aes(label=samplesize, y=probs+8.3), col="black", size=4,fontface="bold")+ # N caterpillars in each treatment 99 | labs(y="Survival (%)", x="Mismatch with oak budburst date (days)")+ 100 | scale_y_continuous(breaks=seq(0,100, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 101 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 102 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 103 | raw_surv 104 | # ggsave(filename="_results/Survival_raw.png", plot=raw_surv , device="png", width=200, height=150, units="mm", dpi="print") 105 | 106 | 107 | # Fit binomial model #### 108 | #----------------------------------- 109 | head(d_surv) # test if probability of survival differs between treatments 110 | 111 | glm1 <- glmer(Event ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), family=binomial, data=d_surv, 112 | na.action="na.fail", control=glmerControl(calc.derivs=F)) # helps convergence 113 | anova1 <- drop1(glm1,test="Chi") %>% as.data.frame # interaction not significant; the use of Chi-square test to determine statistical significance should be explicitly mention in the paper 114 | anova1$mod <- "glm1" 115 | 116 | glm2 <- update(glm1, ~ . -MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 117 | anova2 <- drop1(glm2,test="Chi") %>% as.data.frame #no effect of PhotoTreatment, but effect of MismTreat and MismTreat^2 118 | anova2$mod <- "glm2" 119 | 120 | # Final model #### 121 | glm_final <- glm2 122 | summary(glm_final)# Estimates are log odds 123 | glm_res <- summary(glm_final)$coefficients %>% as.data.frame 124 | 125 | # write.csv(glm_res, file="_results/output_Surv_glmer.csv", row.names=T) 126 | # write.csv(rbind(anova1, anova2), file="_results/anova_Surv_glmer.csv", row.names=T) 127 | 128 | # Get predictions #### 129 | glm.pred <- d_surv[!duplicated(d_surv[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 130 | glm.pred$pred <- predict(glm_final, newdata=glm.pred, type="response") # predictions are probability of dying now 131 | glm.pred$survprob <- (1-glm.pred$pred) 132 | aggregate(survprob~MismTreat, data=glm.pred, mean) # peak at Day2 133 | glm.pred$rel <- glm.pred$survprob/mean(filter(glm.pred, MismTreat==1)$survprob) # expressive relative to peak 134 | head(glm.pred) 135 | 136 | # Visualize predictions #### 137 | pred <- Rmisc::summarySE(glm.pred, measurevar="survprob", groupvars=c("MismTreat")) # average of two photoperiod treatments 138 | pred$samplesize <- aggregate(CaterpillarID~MismTreat, data=d_surv, length)$CaterpillarID 139 | 140 | # Add predictions to raw data figure 141 | p_surv <- raw_surv + #geom_line(data=pred, aes(y=survprob*100)) + 142 | geom_smooth(data=pred, aes(y=survprob*100), se=F, col="red3") 143 | p_surv 144 | # ggsave(filename="_results/Survival_wpred_rev.png", plot=p_surv, device="png", width=200, height=150, units="mm", dpi="print") 145 | 146 | rm(anova1, anova2, glm_res, glm1, glm2, pred, surv_probs, surv_avg, raw_surv) #cleanup 147 | 148 | 149 | #----------------------------------- 150 | # Pupation weight analysis #### 151 | #----------------------------------- 152 | head(d) 153 | 154 | d_pupa <- d %>% mutate(PhotoTreat=gsub("(\\w+)Day.+","\\1",Treatment), MismTreat=gsub("\\w+(Day.+)","\\1",Treatment), PupaWeight=PupaWeight_ingrams*1000) %>% 155 | select(ExperimentName, MotherID, Treatment, PhotoTreat, MismTreat, CaterpillarID, PupationAprilDay, PupaWeight) %>% 156 | filter(!is.na(PupationAprilDay)) %>% 157 | mutate(Treatment=as.factor(Treatment), PhotoTreat=as.factor(ifelse(PhotoTreat=="Chang", "Changing", "Constant")), MismTreatf=as.factor(MismTreat), MotherID=as.factor(MotherID)) %>% 158 | mutate(Treatment=factor(Treatment, levels=c("ChangDay-4", "ChangDay-3", "ChangDay-2", "ChangDay-1", "ChangDay0", "ChangDay+1", "ChangDay+2", "ChangDay+3", "ChangDay+4", 159 | "ChangDay+5", "ConstDay-4", "ConstDay-2", "ConstDay0", "ConstDay+2", "ConstDay+4")), 160 | MismTreatf=factor(MismTreat, levels=c("Day-4", "Day-3", "Day-2", "Day-1", "Day0", "Day+1", "Day+2", "Day+3", "Day+4", "Day+5")), 161 | MismTreat=as.numeric(gsub("Day(.+)","\\1",MismTreat))) %>% 162 | mutate(MismTreat1=MismTreat+5, # no negatives 163 | MismTreat2=(MismTreat+5)^2) # squared term to add in model 164 | head(d_pupa) # 346 individuals survived until pupation 165 | nrow(d_pupa)/nrow(d)*100 # ~35% 166 | 167 | 168 | # Visualize #### 169 | weight <- Rmisc::summarySE(d_pupa, measurevar="PupaWeight", groupvars=c("MismTreat", "PhotoTreat")) 170 | weight$pos <- ifelse(is.na(weight$se)==T, 0, weight$se) # position of sample size labels 171 | weight 172 | 173 | raw_weight <- ggplot(data=weight, aes(x=MismTreat, y=PupaWeight, col=PhotoTreat, fill=PhotoTreat))+ 174 | scale_colour_manual(values=c("grey27", "orangered2"))+ #"dodgerblue4" 175 | scale_fill_manual(values=c("grey27", "orangered2"))+ 176 | geom_jitter(data=d_pupa, aes(col=PhotoTreat), alpha=0.3, size=3, height=0, width=0.25)+ #alpha=0.3, size=2, height=0, width=0.25 177 | geom_errorbar(data=filter(weight, PhotoTreat=="Changing"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="black") + 178 | geom_errorbar(data=filter(weight, PhotoTreat=="Constant"), aes(ymax = PupaWeight+se, ymin=PupaWeight-se), width=0.3, col="orangered4") + 179 | geom_point(size=5, shape=21, col="black")+ 180 | #geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-2.3), col="black", size=4, fontface="bold")+ 181 | #geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold")+ 182 | labs(y="Weight at pupation (mg)", x="Mismatch with oak budburst date (days)")+ 183 | scale_y_continuous(breaks=seq(15,75, by=10))+ scale_x_continuous(breaks=seq(-4, 5, by=1))+ 184 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 185 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 186 | raw_weight 187 | # ggsave(filename="_results/PupWeight_raw.png", plot=raw_weight , device="png", width=200, height=150, units="mm", dpi="print") 188 | 189 | 190 | # Fit linear mixed model #### 191 | #----------------------------------- 192 | lm1 <- lmer(PupaWeight ~ (MismTreat1 + MismTreat2)*PhotoTreat + (1|MotherID), data=d_pupa) 193 | anova1 <- anova(lm1) %>% as.data.frame() # interaction not significant 194 | anova1$mod <- "lm1" 195 | 196 | lm2 <- update(lm1, ~ . - MismTreat1:PhotoTreat - MismTreat2:PhotoTreat) # simplify model 197 | anova2 <- anova(lm2) %>% as.data.frame() # Squared mismatch not significant 198 | anova2$mod <- "lm2" 199 | 200 | lm3 <- update(lm2, ~ . - MismTreat2) # simplify model 201 | anova3 <- anova(lm3) %>% as.data.frame() # PhotoTreat and MismTreat significant 202 | anova3$mod <- "lm3" 203 | 204 | # Still there if exclude first time point with low sample size? 205 | lm4 <- lmer(PupaWeight ~ -1 + MismTreat1 + PhotoTreat + (1|MotherID), data=filter(d_pupa, MismTreat!=-4)) 206 | anova(lm4) # yes 207 | 208 | 209 | # Final model #### 210 | lm_final <- lm3 211 | summary(lm_final) 212 | lm_res <- summary(lm_final)$coefficients %>% as.data.frame 213 | 214 | plot(lm_final) #equal variance? ok 215 | qqnorm(resid(lm_final)) #normally distributed? ok 216 | qqline(resid(lm_final)) 217 | 218 | # write.csv(lm_res, file="_results/output_PupaWeight_lmer.csv", row.names=T) 219 | # write.csv(rbind(anova1, anova2, anova3), file="_results/anova_PupaWeight_lmer.csv", row.names=T) 220 | 221 | # Get predictions #### 222 | lm.pred <- d_pupa[!duplicated(d_pupa[,c("MotherID", "Treatment")]),] # each replicate assigned same prediction, so remove duplicates 223 | lm.pred$pred <- predict(lm_final, newdata=lm.pred, type="response") 224 | head(lm.pred) 225 | 226 | # Visualize predictions #### 227 | pred1 <- Rmisc::summarySE(lm.pred, measurevar="pred", groupvars=c("MismTreat", "PhotoTreat")) # significant effect of photoperiod, so show separate means 228 | pred1$samplesize <- weight$N 229 | pred1$pos <- ifelse(is.na(pred1$se)==T, 0, pred1$se) # position of sample size labels 230 | 231 | # add predictions to raw data figure 232 | p_weight <- raw_weight + #geom_line(data=pred1, aes(y=pred)) + 233 | geom_smooth(data=pred1, aes(y=pred, col=PhotoTreat), se=F, method=lm)+ 234 | geom_text(data=filter(weight, PhotoTreat=="Changing"),aes(label=N, y=PupaWeight-pos-1.5), col="black", size=4, fontface="bold")+ 235 | geom_text(data=filter(weight, PhotoTreat=="Constant"),aes(label=N, y=PupaWeight+pos+2.3), col="black", size=4, fontface="bold") 236 | p_weight 237 | # ggsave(filename="_results/PupWeight_wpred_rev.png", plot=p_weight, device="png", width=200, height=150, units="mm", dpi="print") 238 | 239 | 240 | 241 | #-------------------------------------------- 242 | # Get fitness curve #### 243 | #-------------------------------------------- 244 | 245 | # Don't care about PhotoTreat effect, drop from models #### 246 | glm_fit <- glmer(Event ~ MismTreat1 + MismTreat2 + (1 | MotherID), family="binomial", data=d_surv) 247 | lm_fit <- lmer(PupaWeight ~ MismTreat1 + (1 | MotherID), data=d_pupa) 248 | 249 | # Get predictions to use for curve #### 250 | glm.fit <- d_surv[!duplicated(d_surv[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 251 | glm.fit$pred <- predict(glm_fit, newdata=glm.fit, type="response") # predictions are probability of dying now 252 | glm.fit$survpred <- (1-glm.fit$pred) 253 | 254 | lm.fit <- d_pupa[!duplicated(d_pupa[,c("MotherID", "MismTreatf")]),] # each replicate assigned same prediction, so remove duplicates 255 | lm.fit$pred <- predict(lm_fit, newdata=lm.fit, type="response") 256 | 257 | head(glm.fit) # pred = probability of dying, survpred=1-pred, 220 observations = 22 mothers * 10 MismTreat groups 258 | head(lm.fit) # pred=predicted weight from lmer, only 154 observations 259 | 260 | 261 | # Fit curve to absolute fitness #### 262 | #----------------------------------- 263 | RelFit <- merge(glm.fit[,c("MotherID", "MismTreat", "survpred")], lm.fit[,c("MotherID", "MismTreat", "pred")], by=c("MotherID", "MismTreat"), all=T) 264 | colnames(RelFit)[c(3,4)] <- c("survpred", "pupwpred") 265 | RelFit$Fit <- RelFit$survpred*RelFit$pupwpred # multiply absolute values 266 | head(RelFit) # can only do for 154 observations, clutches with >=1 caterpillar surviving until pupation 267 | table(RelFit$MismTreat, is.na(RelFit$Fit)) # for the other clutches, fitness = 0 268 | RelFit$Fit2 <- ifelse(is.na(RelFit$Fit)==T, 0, RelFit$Fit) 269 | 270 | # loess model to describe the curve #### 271 | loess_mod <- loess(Fit2~ -1 + MismTreat, data=RelFit) 272 | summary(loess_mod) 273 | 274 | curve <- RelFit[!duplicated(RelFit[,c("MismTreat")]),] %>% select(MismTreat) 275 | curve$pred <- predict(loess_mod, newdata=curve) 276 | curve <- arrange(curve, MismTreat) 277 | curve # peak at day2 278 | curve$rel <- curve$pred/filter(curve, MismTreat==2)$pred # expressive relative to peak 279 | 280 | RelFit$rel <- RelFit$Fit2/mean(filter(RelFit, MismTreat==2)$Fit2) 281 | 282 | RelFit_means <- Rmisc::summarySE(RelFit, measurevar="rel", groupvars=c("MismTreat")) 283 | #RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_pupa, length)$MotherID # number of caterpillars curve is based on 284 | RelFit_means$samplesize <- aggregate(MotherID~MismTreat, data=d_surv, length)$MotherID # number of caterpillars curve is based on = all 285 | RelFit_means$curve <- curve$rel 286 | head(RelFit_means) 287 | # write.csv(RelFit_means, file="_results/RelFitness_rev.csv", row.names=F) 288 | 289 | p_relfit <- ggplot(data=RelFit, aes(x=MismTreat, y=rel)) + 290 | geom_jitter(size=3, alpha=0.4, height=0, width=0.25, shape=21, fill="dodgerblue2", col="dodgerblue4")+ 291 | geom_point(data=RelFit_means, size=5) + 292 | geom_errorbar(data=RelFit_means, aes(ymax = rel+se, ymin=rel-se), width=0.3) + 293 | #geom_line(data=curve, aes(y=pred), col="darkred", size=1)+ 294 | #geom_smooth(data=curve, se=F, col="red3", size=1)+ # makes it look more like a smooth line, but otherwise exactly the same as using geom_line 295 | geom_text(data=RelFit_means,aes(label=samplesize, y=rel+0.12), col="black", size=5, fontface="bold")+ # number of caterpillars 296 | geom_hline(yintercept=1, linetype="dashed")+ 297 | labs(y="Relative fitness", x="Mismatch with oak budburst date (days)")+ 298 | scale_y_continuous(lim=c(0,1.21), breaks=seq(0,1.6, by=0.2))+ scale_x_continuous(breaks=seq(-4,5, by=1))+ #lim=c(-0.1,1.3) 299 | theme(legend.position="none")+ 300 | theme(axis.title.y=element_text(size=18, vjust=2), axis.title.x=element_text(size=18, vjust=-0.5), 301 | axis.text=element_text(size=16), legend.text = element_text(size=16), legend.title=element_text(size=17)) 302 | p_relfit 303 | # ggsave(filename="_results/FitnessCurve_rev.png", plot=p_relfit, device="png", width=200, height=150, units="mm", dpi="print") 304 | 305 | 306 | 307 | 308 | sessionInfo() %>% capture.output(file="_src/env_CatFoodExp2021_analysis.txt") 309 | --------------------------------------------------------------------------------