├── .github ├── .gitignore └── workflows │ └── R-CMD-check.yaml ├── data └── web.rda ├── inst ├── models │ ├── .gitignore │ ├── Young2021.stan │ ├── sampling_effort.stan │ └── varying_preferences.stan └── CITATION ├── .gitignore ├── _pkgdown.yml ├── docs ├── reference │ ├── plot_counts_obs-1.png │ ├── plot_counts_obs-2.png │ ├── plot_counts_obs-3.png │ ├── figures │ │ ├── README-unnamed-chunk-4-1.png │ │ ├── README-unnamed-chunk-7-1.png │ │ ├── README-unnamed-chunk-7-2.png │ │ ├── README-unnamed-chunk-9-1.png │ │ ├── README-unnamed-chunk-10-1.png │ │ ├── README-unnamed-chunk-11-1.png │ │ └── README-unnamed-chunk-12-1.png │ ├── BayesianWebs.html │ ├── web.html │ ├── BayesianWebs-package.html │ ├── index.html │ ├── get_seed.html │ ├── plot_counts_obs.html │ ├── check_model.html │ ├── predict_counts.html │ ├── plot_interaction_prob.html │ ├── plot_counts_pred.html │ ├── plot_residuals.html │ ├── fit_model.html │ ├── prepare_data.html │ ├── plot_prior.html │ ├── get_posterior.html │ └── plot_counts_pred_obs.html ├── deps │ ├── font-awesome-6.5.2 │ │ └── webfonts │ │ │ ├── fa-brands-400.ttf │ │ │ ├── fa-regular-400.ttf │ │ │ ├── fa-solid-900.ttf │ │ │ ├── fa-solid-900.woff2 │ │ │ ├── fa-brands-400.woff2 │ │ │ ├── fa-regular-400.woff2 │ │ │ ├── fa-v4compatibility.ttf │ │ │ └── fa-v4compatibility.woff2 │ ├── headroom-0.11.0 │ │ ├── jQuery.headroom.min.js │ │ └── headroom.min.js │ ├── data-deps.txt │ ├── bootstrap-toc-1.0.1 │ │ └── bootstrap-toc.min.js │ └── clipboard.js-2.0.11 │ │ └── clipboard.min.js ├── pkgdown.yml ├── katex-auto.js ├── link.svg ├── sitemap.xml ├── lightswitch.js ├── 404.html ├── authors.html └── pkgdown.js ├── man ├── figures │ ├── README-unnamed-chunk-10-1.png │ ├── README-unnamed-chunk-11-1.png │ ├── README-unnamed-chunk-12-1.png │ ├── README-unnamed-chunk-4-1.png │ ├── README-unnamed-chunk-7-1.png │ ├── README-unnamed-chunk-7-2.png │ └── README-unnamed-chunk-9-1.png ├── get_seed.Rd ├── web.Rd ├── predict_counts.Rd ├── BayesianWebs-package.Rd ├── check_model.Rd ├── plot_counts_obs.Rd ├── prepare_data.Rd ├── plot_interaction_prob.Rd ├── plot_counts_pred.Rd ├── plot_residuals.Rd ├── get_posterior.Rd ├── plot_prior.Rd ├── fit_model.Rd └── plot_counts_pred_obs.Rd ├── R ├── BayesianWebs-package.R ├── globals.R ├── get_seed.R ├── is_there_link.R ├── datasets.R ├── plot_counts_obs.R ├── plot_counts_pred.R ├── plot_interaction_prob.R ├── predict_counts.R ├── check_model.R ├── plot_residuals.R ├── prepare_data.R ├── fit_model.R ├── plot_counts_pred_obs.R ├── plot_prior.R └── get_posterior.R ├── .Rbuildignore ├── data-raw └── DATASET.R ├── NAMESPACE ├── BayesianWebs.Rproj ├── DESCRIPTION ├── README.Rmd └── README.md /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /data/web.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/data/web.rda -------------------------------------------------------------------------------- /inst/models/.gitignore: -------------------------------------------------------------------------------- 1 | model_effort 2 | sampling_effort 3 | varying_preferences 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .Rdata 4 | .httr-oauth 5 | .DS_Store 6 | .quarto 7 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | template: 2 | bootstrap: 5 3 | url: https://pakillo.github.io/BayesianWebs/ 4 | -------------------------------------------------------------------------------- /docs/reference/plot_counts_obs-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/reference/plot_counts_obs-1.png -------------------------------------------------------------------------------- /docs/reference/plot_counts_obs-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/reference/plot_counts_obs-2.png -------------------------------------------------------------------------------- /docs/reference/plot_counts_obs-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/reference/plot_counts_obs-3.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/man/figures/README-unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/man/figures/README-unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-12-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/man/figures/README-unnamed-chunk-12-1.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/man/figures/README-unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/man/figures/README-unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-7-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/man/figures/README-unnamed-chunk-7-2.png -------------------------------------------------------------------------------- /man/figures/README-unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/man/figures/README-unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /R/BayesianWebs-package.R: -------------------------------------------------------------------------------- 1 | #' @keywords internal 2 | "_PACKAGE" 3 | 4 | ## usethis namespace: start 5 | ## usethis namespace: end 6 | NULL 7 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^BayesianWebs\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^README\.Rmd$ 4 | ^LICENSE\.md$ 5 | ^data-raw$ 6 | docs/ 7 | ^\.github$ 8 | _pkgdown.yml 9 | -------------------------------------------------------------------------------- /docs/reference/figures/README-unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/reference/figures/README-unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README-unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/reference/figures/README-unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README-unnamed-chunk-7-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/reference/figures/README-unnamed-chunk-7-2.png -------------------------------------------------------------------------------- /docs/reference/figures/README-unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/reference/figures/README-unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README-unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/reference/figures/README-unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README-unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/reference/figures/README-unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /docs/reference/figures/README-unnamed-chunk-12-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/reference/figures/README-unnamed-chunk-12-1.png -------------------------------------------------------------------------------- /docs/deps/font-awesome-6.5.2/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/deps/font-awesome-6.5.2/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /docs/deps/font-awesome-6.5.2/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/deps/font-awesome-6.5.2/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /docs/deps/font-awesome-6.5.2/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/deps/font-awesome-6.5.2/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /docs/deps/font-awesome-6.5.2/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/deps/font-awesome-6.5.2/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /docs/deps/font-awesome-6.5.2/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/deps/font-awesome-6.5.2/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /docs/deps/font-awesome-6.5.2/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/deps/font-awesome-6.5.2/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /docs/deps/font-awesome-6.5.2/webfonts/fa-v4compatibility.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/deps/font-awesome-6.5.2/webfonts/fa-v4compatibility.ttf -------------------------------------------------------------------------------- /docs/deps/font-awesome-6.5.2/webfonts/fa-v4compatibility.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pakillo/BayesianWebs/HEAD/docs/deps/font-awesome-6.5.2/webfonts/fa-v4compatibility.woff2 -------------------------------------------------------------------------------- /docs/pkgdown.yml: -------------------------------------------------------------------------------- 1 | pandoc: '3.2' 2 | pkgdown: 2.1.1 3 | pkgdown_sha: ~ 4 | articles: {} 5 | last_built: 2024-12-17T19:02Z 6 | urls: 7 | reference: https://pakillo.github.io/BayesianWebs/reference 8 | article: https://pakillo.github.io/BayesianWebs/articles 9 | -------------------------------------------------------------------------------- /R/globals.R: -------------------------------------------------------------------------------- 1 | utils::globalVariables(c(".chain", ".draw", ".lower", ".upper", 2 | "Animal", "Count.obs", "Count.pred", "Plant", "Q", 3 | "Visits", "animal.abund", "count", "effort", 4 | "int.prob", "lp__", "plant.abund", "preference", 5 | "prior", "r", "rho", "sigma", "tau")) 6 | -------------------------------------------------------------------------------- /data-raw/DATASET.R: -------------------------------------------------------------------------------- 1 | ## code to prepare `DATASET` dataset goes here 2 | 3 | dt <- read.table("https://raw.githubusercontent.com/jg-you/plant-pollinator-inference/master/example_matrix.txt") 4 | web <- apply(dt, c(1,2), as.integer) 5 | rownames(web) <- paste0("P", 1:nrow(web)) 6 | colnames(web) <- paste0("A", 1:ncol(web)) 7 | 8 | usethis::use_data(web, overwrite = TRUE) 9 | -------------------------------------------------------------------------------- /docs/reference/BayesianWebs.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(check_model) 4 | export(fit_model) 5 | export(get_posterior) 6 | export(get_seed) 7 | export(plot_counts_obs) 8 | export(plot_counts_pred) 9 | export(plot_counts_pred_obs) 10 | export(plot_interaction_prob) 11 | export(plot_prior) 12 | export(plot_residuals) 13 | export(predict_counts) 14 | export(prepare_data) 15 | import(cmdstanr) 16 | -------------------------------------------------------------------------------- /R/get_seed.R: -------------------------------------------------------------------------------- 1 | #' Get seed used to fit a model 2 | #' 3 | #' @param fit A fitted model 4 | #' 5 | #' @return A number 6 | #' @export 7 | #' 8 | #' @examplesIf interactive() 9 | #' data(web) 10 | #' dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 11 | #' fit <- fit_model(dt, refresh = 0) 12 | #' get_seed(fit) 13 | 14 | get_seed <- function(fit = NULL) { 15 | seed <- fit$metadata()$seed 16 | stopifnot(is.numeric(seed)) 17 | return(seed) 18 | } 19 | -------------------------------------------------------------------------------- /R/is_there_link.R: -------------------------------------------------------------------------------- 1 | #' Is there a link? 2 | #' 3 | #' @param df A dataframe containing posterior interaction probabilities, as 4 | #' generated from [get_posterior()] 5 | #' 6 | #' @return A data frame with a new column `link` taking values of 0 (no link) 7 | #' and 1 (link). 8 | #' @noRd 9 | #' 10 | 11 | is_there_link <- function(df = NULL) { 12 | 13 | stopifnot("int.prob" %in% names(df)) 14 | df |> 15 | dplyr::mutate(link = stats::rbinom(1, size = 1, prob = int.prob)) 16 | } 17 | -------------------------------------------------------------------------------- /BayesianWebs.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 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 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | LineEndingConversion: Posix 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch --with-keep.source 22 | PackageRoxygenize: rd,collate,namespace 23 | -------------------------------------------------------------------------------- /R/datasets.R: -------------------------------------------------------------------------------- 1 | #' Plant-pollinator network 2 | #' 3 | #' An example bipartite network of 8 plant species and 21 pollinators, 4 | #' from [Kaiser-Bunbury et al. 2017](https://doi.org/10.1038/nature21071). 5 | #' 6 | #' @format ## `web` 7 | #' A numeric (integer) matrix with 8 rows (representing plants) and 21 columns 8 | #' (representing animals) 9 | #' @source Kaiser-Bunbury, C., Mougal, J., Whittington, A. et al. 10 | #' Ecosystem restoration strengthens pollination network resilience and function. 11 | #' Nature 542, 223–227 (2017). https://doi.org/10.1038/nature21071 12 | "web" 13 | -------------------------------------------------------------------------------- /docs/deps/headroom-0.11.0/jQuery.headroom.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * headroom.js v0.9.4 - Give your page some headroom. Hide your header until you need it 3 | * Copyright (c) 2017 Nick Williams - http://wicky.nillia.ms/headroom.js 4 | * License: MIT 5 | */ 6 | 7 | !function(a){a&&(a.fn.headroom=function(b){return this.each(function(){var c=a(this),d=c.data("headroom"),e="object"==typeof b&&b;e=a.extend(!0,{},Headroom.options,e),d||(d=new Headroom(this,e),d.init(),c.data("headroom",d)),"string"==typeof b&&(d[b](),"destroy"===b&&c.removeData("headroom"))})},a("[data-headroom]").each(function(){var b=a(this);b.headroom(b.data())}))}(window.Zepto||window.jQuery); -------------------------------------------------------------------------------- /man/get_seed.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_seed.R 3 | \name{get_seed} 4 | \alias{get_seed} 5 | \title{Get seed used to fit a model} 6 | \usage{ 7 | get_seed(fit = NULL) 8 | } 9 | \arguments{ 10 | \item{fit}{A fitted model} 11 | } 12 | \value{ 13 | A number 14 | } 15 | \description{ 16 | Get seed used to fit a model 17 | } 18 | \examples{ 19 | \dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} 20 | data(web) 21 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 22 | fit <- fit_model(dt, refresh = 0) 23 | get_seed(fit) 24 | \dontshow{\}) # examplesIf} 25 | } 26 | -------------------------------------------------------------------------------- /docs/katex-auto.js: -------------------------------------------------------------------------------- 1 | // https://github.com/jgm/pandoc/blob/29fa97ab96b8e2d62d48326e1b949a71dc41f47a/src/Text/Pandoc/Writers/HTML.hs#L332-L345 2 | document.addEventListener("DOMContentLoaded", function () { 3 | var mathElements = document.getElementsByClassName("math"); 4 | var macros = []; 5 | for (var i = 0; i < mathElements.length; i++) { 6 | var texText = mathElements[i].firstChild; 7 | if (mathElements[i].tagName == "SPAN") { 8 | katex.render(texText.data, mathElements[i], { 9 | displayMode: mathElements[i].classList.contains("display"), 10 | throwOnError: false, 11 | macros: macros, 12 | fleqn: false 13 | }); 14 | }}}); 15 | -------------------------------------------------------------------------------- /R/plot_counts_obs.R: -------------------------------------------------------------------------------- 1 | #' Plot heatmap of observed counts 2 | #' 3 | #' @param mat A matrix with count data reporting interaction frequency 4 | #' (e.g. visits to flowers, number of fruits consumed per plant or species). 5 | #' Plants must be in rows, Animals must be in columns. 6 | #' @param ... Further arguments for [network.tools::plot_web_heatmap()]. 7 | #' 8 | #' @return A ggplot object 9 | #' @export 10 | #' 11 | #' @examples 12 | #' data(web) 13 | #' plot_counts_obs(web) 14 | #' plot_counts_obs(web, sort = FALSE) 15 | #' plot_counts_obs(web, zero.na = FALSE, sort = FALSE) 16 | 17 | plot_counts_obs <- function(mat = NULL, ...) { 18 | 19 | mat |> 20 | network.tools::wide2long() |> 21 | network.tools::plot_web_heatmap(...) + 22 | ggplot2::labs(title = "Observed counts", fill = "") 23 | 24 | } 25 | -------------------------------------------------------------------------------- /man/web.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/datasets.R 3 | \docType{data} 4 | \name{web} 5 | \alias{web} 6 | \title{Plant-pollinator network} 7 | \format{ 8 | \subsection{\code{web}}{ 9 | 10 | A numeric (integer) matrix with 8 rows (representing plants) and 21 columns 11 | (representing animals) 12 | } 13 | } 14 | \source{ 15 | Kaiser-Bunbury, C., Mougal, J., Whittington, A. et al. 16 | Ecosystem restoration strengthens pollination network resilience and function. 17 | Nature 542, 223–227 (2017). https://doi.org/10.1038/nature21071 18 | } 19 | \usage{ 20 | web 21 | } 22 | \description{ 23 | An example bipartite network of 8 plant species and 21 pollinators, 24 | from \href{https://doi.org/10.1038/nature21071}{Kaiser-Bunbury et al. 2017}. 25 | } 26 | \keyword{datasets} 27 | -------------------------------------------------------------------------------- /man/predict_counts.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/predict_counts.R 3 | \name{predict_counts} 4 | \alias{predict_counts} 5 | \title{Predict interaction counts} 6 | \usage{ 7 | predict_counts(fit = NULL, data = NULL) 8 | } 9 | \arguments{ 10 | \item{fit}{Fitted model} 11 | 12 | \item{data}{Data list} 13 | } 14 | \value{ 15 | A data frame 16 | } 17 | \description{ 18 | Generate the posterior predictive distribution of counts for every pairwise 19 | interaction. 20 | } 21 | \examples{ 22 | \dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} 23 | data(web) 24 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 25 | fit <- fit_model(dt, refresh = 0) 26 | predict_counts(fit, dt) 27 | \dontshow{\}) # examplesIf} 28 | } 29 | -------------------------------------------------------------------------------- /man/BayesianWebs-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/BayesianWebs-package.R 3 | \docType{package} 4 | \name{BayesianWebs-package} 5 | \alias{BayesianWebs} 6 | \alias{BayesianWebs-package} 7 | \title{BayesianWebs: Bayesian Modelling of Bipartite Networks} 8 | \description{ 9 | Bayesian modelling of bipartite network structure, following the approach of Young et al. \doi{10.1038/s41467-021-24149-x}. 10 | } 11 | \seealso{ 12 | Useful links: 13 | \itemize{ 14 | \item \url{https://pakillo.github.io/BayesianWebs/} 15 | \item Report bugs at \url{https://github.com/Pakillo/BayesianWebs/issues} 16 | } 17 | 18 | } 19 | \author{ 20 | \strong{Maintainer}: Francisco Rodriguez-Sanchez \email{f.rodriguez.sanc@gmail.com} (\href{https://orcid.org/0000-0002-7981-1599}{ORCID}) 21 | 22 | } 23 | \keyword{internal} 24 | -------------------------------------------------------------------------------- /docs/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | -------------------------------------------------------------------------------- /man/check_model.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/check_model.R 3 | \name{check_model} 4 | \alias{check_model} 5 | \title{Check fitted model} 6 | \usage{ 7 | check_model(fit = NULL, data = NULL) 8 | } 9 | \arguments{ 10 | \item{fit}{A fitted model, as obtained from \code{\link[=fit_model]{fit_model()}}.} 11 | 12 | \item{data}{Data list (from \code{\link[=prepare_data]{prepare_data()}}).} 13 | } 14 | \value{ 15 | Model checks on console and graphical window. 16 | } 17 | \description{ 18 | Check fitted model 19 | } 20 | \examples{ 21 | \dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} 22 | data(web) 23 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 24 | fit <- fit_model(dt, refresh = 0) 25 | check_model(fit, data = data) 26 | \dontshow{\}) # examplesIf} 27 | } 28 | -------------------------------------------------------------------------------- /R/plot_counts_pred.R: -------------------------------------------------------------------------------- 1 | #' Plot heatmap of predicted counts 2 | #' 3 | #' @param pred.df A data frame containing the predicted counts, as generated by 4 | #' [predict_counts()] 5 | #' @param ... Further arguments for [network.tools::plot_web_heatmap()]. 6 | #' 7 | #' @return A ggplot object 8 | #' @export 9 | #' 10 | #' @examplesIf interactive() 11 | #' data(web) 12 | #' dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 13 | #' fit <- fit_model(dt, refresh = 0) 14 | #' pred.df <- predict_counts(fit, dt) 15 | #' plot_counts_pred(pred.df) 16 | #' plot_counts_pred(pred.df, sort = FALSE) 17 | 18 | plot_counts_pred <- function(pred.df = NULL, ...) { 19 | 20 | pred.df |> 21 | dplyr::select(Plant, Animal, count) |> 22 | tidybayes::mean_qi() |> 23 | network.tools::plot_web_heatmap(int.var = "count", ...) + 24 | ggplot2::labs(title = "Predicted counts", fill = "") 25 | } 26 | -------------------------------------------------------------------------------- /man/plot_counts_obs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_counts_obs.R 3 | \name{plot_counts_obs} 4 | \alias{plot_counts_obs} 5 | \title{Plot heatmap of observed counts} 6 | \usage{ 7 | plot_counts_obs(mat = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{mat}{A matrix with count data reporting interaction frequency 11 | (e.g. visits to flowers, number of fruits consumed per plant or species). 12 | Plants must be in rows, Animals must be in columns.} 13 | 14 | \item{...}{Further arguments for \code{\link[network.tools:plot_web_heatmap]{network.tools::plot_web_heatmap()}}.} 15 | } 16 | \value{ 17 | A ggplot object 18 | } 19 | \description{ 20 | Plot heatmap of observed counts 21 | } 22 | \examples{ 23 | data(web) 24 | plot_counts_obs(web) 25 | plot_counts_obs(web, sort = FALSE) 26 | plot_counts_obs(web, zero.na = FALSE, sort = FALSE) 27 | } 28 | -------------------------------------------------------------------------------- /R/plot_interaction_prob.R: -------------------------------------------------------------------------------- 1 | #' Plot heatmap of interaction probabilities 2 | #' 3 | #' Plot a heatmap of average interaction probabilities 4 | #' 5 | #' @param post Data frame containing the posterior probabilities, as generated 6 | #' from `get_posterior()`. 7 | #' 8 | #' @return A ggplot object 9 | #' @export 10 | #' 11 | #' @examplesIf interactive() 12 | #' data(web) 13 | #' dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 14 | #' fit <- fit_model(dt, refresh = 0) 15 | #' post <- get_posterior(fit, dt) 16 | #' plot_interaction_prob(post) 17 | 18 | plot_interaction_prob <- function(post = NULL) { 19 | post |> 20 | dplyr::select(Plant, Animal, int.prob) |> 21 | tidybayes::mean_qi() |> 22 | network.tools::plot_web_heatmap(int.var = "int.prob", sort = FALSE) + 23 | ggplot2::labs(title = "Mean interaction probability", 24 | fill = "Probability") 25 | } 26 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: BayesianWebs 2 | Title: Bayesian Modelling of Bipartite Networks 3 | Version: 0.0.7 4 | Authors@R: 5 | c( 6 | person("Francisco", "Rodriguez-Sanchez", , "f.rodriguez.sanc@gmail.com", role = c("aut", "cre"), 7 | comment = c(ORCID = "0000-0002-7981-1599")) 8 | ) 9 | Description: Bayesian modelling of bipartite network structure, following the approach 10 | of Young et al.An example bipartite network of 8 plant species and 21 pollinators, 39 | from Kaiser-Bunbury et al. 2017.
40 |R/BayesianWebs-package.R
34 | BayesianWebs-package.RdBayesian modelling of bipartite network structure, following the approach of Young et al. doi:10.1038/s41467-021-24149-x 39 | .
40 |Useful links:
Report bugs at https://github.com/Pakillo/BayesianWebs/issues
Maintainer: Francisco Rodriguez-Sanchez f.rodriguez.sanc@gmail.com (ORCID)
52 |check_model()
47 |
48 | fit_model()
53 |
54 | get_posterior()
59 |
60 | get_seed()
65 |
66 | plot_counts_obs()
71 |
72 | plot_counts_pred()
77 |
78 | plot_counts_pred_obs()
83 |
84 | plot_interaction_prob()
89 |
90 | plot_prior()
95 |
96 | plot_residuals()
101 |
102 | predict_counts()
107 |
108 | prepare_data()
113 |
114 | web
119 |
120 | Get seed used to fit a model
37 |if (FALSE) { # interactive()
60 | data(web)
61 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web)))
62 | fit <- fit_model(dt, refresh = 0)
63 | get_seed(fit)
64 | }
65 | R/plot_counts_obs.R
32 | plot_counts_obs.RdPlot heatmap of observed counts
37 |A matrix with count data reporting interaction frequency 50 | (e.g. visits to flowers, number of fruits consumed per plant or species). 51 | Plants must be in rows, Animals must be in columns.
Further arguments for network.tools::plot_web_heatmap().
data(web)
66 | plot_counts_obs(web)
67 |
68 | plot_counts_obs(web, sort = FALSE)
69 |
70 | plot_counts_obs(web, zero.na = FALSE, sort = FALSE)
71 |
72 | Check fitted model
37 |A fitted model, as obtained from fit_model().
Data list (from prepare_data()).
if (FALSE) { # interactive()
64 | data(web)
65 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web)))
66 | fit <- fit_model(dt, refresh = 0)
67 | check_model(fit, data = data)
68 | }
69 | Generate the posterior predictive distribution of counts for every pairwise 39 | interaction.
40 |if (FALSE) { # interactive()
67 | data(web)
68 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web)))
69 | fit <- fit_model(dt, refresh = 0)
70 | predict_counts(fit, dt)
71 | }
72 | R/plot_interaction_prob.R
32 | plot_interaction_prob.RdPlot a heatmap of average interaction probabilities
37 |Data frame containing the posterior probabilities, as generated
50 | from get_posterior().
if (FALSE) { # interactive()
61 | data(web)
62 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web)))
63 | fit <- fit_model(dt, refresh = 0)
64 | post <- get_posterior(fit, dt)
65 | plot_interaction_prob(post)
66 | }
67 | R/plot_counts_pred.R
32 | plot_counts_pred.RdPlot heatmap of predicted counts
37 |A data frame containing the predicted counts, as generated by
50 | predict_counts()
Further arguments for network.tools::plot_web_heatmap().
if (FALSE) { # interactive()
65 | data(web)
66 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web)))
67 | fit <- fit_model(dt, refresh = 0)
68 | pred.df <- predict_counts(fit, dt)
69 | plot_counts_pred(pred.df)
70 | plot_counts_pred(pred.df, sort = FALSE)
71 | }
72 | Plot heatmap of residuals (observed - predicted counts).
37 |A data frame containing the predicted counts, as generated by
50 | predict_counts()
Data list (from prepare_data())
Further arguments for network.tools::plot_web_heatmap().
if (FALSE) { # interactive()
69 | data(web)
70 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web)))
71 | fit <- fit_model(dt, refresh = 0)
72 | pred.df <- predict_counts(fit, dt)
73 | plot_residuals(pred.df, dt)
74 | plot_residuals(pred.df, dt, sort = FALSE)
75 | }
76 | Fit model
37 |fit_model(
42 | data = NULL,
43 | model = c("sampling_effort", "Young2021", "varying_preferences"),
44 | beta = 0.01,
45 | ...
46 | )A named list containing the required data, as obtained from
55 | prepare_data().
character. One of "Young2021", "sampling_effort", or 60 | "varying_preferences", or a path to a file describing the Stan model in case 61 | you want to use a modified Stan model.
Rate of exponential prior on r (preference) parameter.
66 | Default beta is 0.01. Increase it if you have large count numbers
67 | (can examine the resultant prior using plot_prior()).
Further arguments for cmdstanr::sample(), like iter_warmup,
72 | iter_sampling, or thin, among others. It is recommended to increase the
73 | number of iterations (e.g. iter_sampling = 10000).
A fitted model (cmdstanr::CmdStanMCMC() object).
if (FALSE) { # interactive()
84 | data(web)
85 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web)))
86 | fit <- fit_model(dt)
87 | }
88 |
88 |
89 | First, prepare the data for modelling. Here we assume constant sampling
90 | effort among plants:
91 |
92 | ``` r
93 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web)))
94 | ```
95 |
96 | Now fit the model. There are several models available: the original
97 | model used in Young et al. (2021), a model that takes into account
98 | varying sampling effort among plants, and a model that allows for
99 | varying preferences among animals. The user can also provide a
100 | customised Stan model. See `fit_model()`.
101 |
102 | Here we run 4 parallel chains:
103 |
104 | ``` r
105 | set.seed(1)
106 | options(mc.cores = 4)
107 | fit <- fit_model(dt, refresh = 0)
108 | #> Running MCMC with 4 parallel chains...
109 | #>
110 | #> Chain 1 finished in 2.9 seconds.
111 | #> Chain 4 finished in 2.9 seconds.
112 | #> Chain 2 finished in 3.0 seconds.
113 | #> Chain 3 finished in 3.1 seconds.
114 | #>
115 | #> All 4 chains finished successfully.
116 | #> Mean chain execution time: 2.9 seconds.
117 | #> Total execution time: 3.4 seconds.
118 | ```
119 |
120 | Check model:
121 |
122 | ``` r
123 | check_model(fit, data = dt)
124 | #> Processing csv files: /tmp/Rtmpq9vAYS/sampling_effort-202412172000-1-400f5e.csv, /tmp/Rtmpq9vAYS/sampling_effort-202412172000-2-400f5e.csv, /tmp/Rtmpq9vAYS/sampling_effort-202412172000-3-400f5e.csv, /tmp/Rtmpq9vAYS/sampling_effort-202412172000-4-400f5e.csv
125 | #>
126 | #> Checking sampler transitions treedepth.
127 | #> Treedepth satisfactory for all transitions.
128 | #>
129 | #> Checking sampler transitions for divergences.
130 | #> No divergent transitions found.
131 | #>
132 | #> Checking E-BFMI - sampler transitions HMC potential energy.
133 | #> E-BFMI satisfactory.
134 | #>
135 | #> Effective sample size satisfactory.
136 | #>
137 | #> Split R-hat values satisfactory all parameters.
138 | #>
139 | #> Processing complete, no problems detected.
140 | ```
141 |
142 | 
143 |
144 | Get the posteriors:
145 |
146 | ``` r
147 | post <- get_posterior(fit, data = dt)
148 | head(post)
149 | #> # A tibble: 6 × 11
150 | #> # Groups: Plant, Animal [6]
151 | #> Plant Animal .chain .iteration .draw connectance preference plant.abund
152 | #>
167 |
168 | Predict interaction counts:
169 |
170 | ``` r
171 | pred.df <- predict_counts(fit, data = dt)
172 | plot_counts_pred(pred.df, sort = FALSE)
173 | ```
174 |
175 |
176 |
177 | Compare observed and predicted counts:
178 |
179 | ``` r
180 | plot_counts_pred_obs(pred.df, data = dt)
181 | ```
182 |
183 |
184 |
185 | Plot residuals:
186 |
187 | ``` r
188 | plot_residuals(pred.df, data = dt, sort = FALSE)
189 | ```
190 |
191 |
192 |
193 | ## Citation
194 |
195 | If you use `BayesianWebs` please cite it:
196 |
197 | ``` r
198 | citation("BayesianWebs")
199 | If you use BayesianWebs, please cite both Young et al. (2021) and the
200 | package as:
201 |
202 | Young J, Valdovinos F, Newman M (2021). "Reconstruction of
203 | plant–pollinator networks from observational data." _Nature
204 | Communications_, *12*, 3911. doi:10.1038/s41467-021-24149-x
205 | Prepare the data for modelling
37 |An integer matrix containing quantitative (not qualitative or binary) 50 | count data con interaction frequency (e.g. visits to flowers, number of fruits 51 | consumed per plant or species). Plants must be in rows, Animals must be in columns.
A numeric vector with the sampling effort (e.g. observation hours) 56 | spent on each plant.
data(web)
67 | prepare_data(web, sampl.eff = rep(20, nrow(web)))
68 | #> $M
69 | #> A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21
70 | #> P1 0 0 3 1 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0
71 | #> P2 0 0 12 0 0 0 0 0 0 0 0 0 0 8 0 1 0 0 0 0 1
72 | #> P3 0 0 0 0 1 0 7 0 0 0 0 0 0 2 0 0 5 3 0 0 0
73 | #> P4 0 0 2 0 3 0 0 1 0 0 0 0 0 30 0 0 0 0 0 0 0
74 | #> P5 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0
75 | #> P6 0 0 0 4 1 0 1 0 0 0 1 5 2 0 0 0 0 0 0 0 0
76 | #> P7 3 0 33 0 0 2 6 0 2 0 0 0 0 27 0 0 0 0 0 0 2
77 | #> P8 0 1 1 1 2 0 11 0 0 6 0 0 0 1 2 0 0 0 0 1 0
78 | #>
79 | #> $n_p
80 | #> [1] 8
81 | #>
82 | #> $n_a
83 | #> [1] 21
84 | #>
85 | #> $C
86 | #> [1] 20 20 20 20 20 20 20 20
87 | #>
88 | R/plot_prior.R
40 | plot_prior.RdThe r (preference) parameter in Young et al. model takes a prior
45 | exponential distribution with rate = beta. Use this function to
46 | visualise the prior distribution of r given the chosen beta.
47 | Alternatively, if providing the fitted model, a plot comparing the
48 | prior versus posterior preference(s) will be produced.
A number > 0. Rate of the exponential distribution.
A fitted model, as obtained from fit_model().
Data list (from prepare_data()).
if (FALSE) { # interactive()
80 | ## Providing value for beta
81 | plot_prior(beta = 0.01)
82 | plot_prior(beta = 0.001)
83 |
84 | ## Providing fitted model
85 | data(web)
86 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web)))
87 | fit <- fit_model(dt, refresh = 0)
88 | plot_prior(fit = fit, data = dt)
89 | }
90 | Get posterior values
37 |get_posterior(
42 | fit = NULL,
43 | data = NULL,
44 | param = c("all", "connectance", "preference", "plant.abund", "animal.abund",
45 | "int.prob", "link")
46 | )Fitted model (from fit_model())
Data list (from prepare_data())
character. Name of the parameter to retrieve the posterior samples.
if (FALSE) { # interactive()
73 | data(web)
74 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web)))
75 | fit <- fit_model(dt, refresh = 0)
76 | get_posterior(fit, dt, param = "connectance")
77 |
78 | int.prob <- get_posterior(fit, dt, param = "int.prob")
79 | int.prob
80 | int.prob |> tidybayes::mean_qi() # mean edge probability
81 |
82 | # all posteriors
83 | get_posterior(fit, dt, param = "all")
84 | }
85 | R/plot_counts_pred_obs.R
32 | plot_counts_pred_obs.RdPlot predicted versus observed counts
37 |plot_counts_pred_obs(
42 | pred.df = NULL,
43 | data = NULL,
44 | byplant = FALSE,
45 | width = 0.95,
46 | ...
47 | )A data frame containing the predicted counts, as generated by
56 | predict_counts()
Data list (from prepare_data())
Logical. If TRUE, show predicted and observed counts per plant
65 | (using ggplot2::facet_wrap()). If FALSE, show all interactions in the same plot.
width of the credible interval (default = 0.95).
Further arguments to be passed to ggplot2::facet_wrap() if
74 | byplant = TRUE, or to tidybayes::geom_pointinterval() if byplant = FALSE.
if (FALSE) { # interactive()
85 | data(web)
86 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web)))
87 | fit <- fit_model(dt, refresh = 0)
88 | pred.df <- predict_counts(fit, dt)
89 | plot_counts_pred_obs(pred.df, dt)
90 | plot_counts_pred_obs(pred.df, dt, fatten_point = 3)
91 | plot_counts_pred_obs(pred.df, dt, byplant = TRUE)
92 | plot_counts_pred_obs(pred.df, dt, byplant = TRUE, scale = "free")
93 | }
94 |