├── .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 | 5 | 8 | 12 | 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. . 11 | License: GPL (>= 3) 12 | Encoding: UTF-8 13 | Roxygen: list(markdown = TRUE) 14 | RoxygenNote: 7.3.2 15 | URL: https://pakillo.github.io/BayesianWebs/ 16 | BugReports: https://github.com/Pakillo/BayesianWebs/issues 17 | Imports: 18 | cmdstanr, 19 | dplyr, 20 | ggplot2, 21 | network.tools, 22 | tidybayes 23 | Remotes: 24 | stan-dev/cmdstanr, 25 | Pakillo/network.tools 26 | Depends: 27 | R (>= 4.1) 28 | LazyData: true 29 | -------------------------------------------------------------------------------- /man/prepare_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/prepare_data.R 3 | \name{prepare_data} 4 | \alias{prepare_data} 5 | \title{Prepare the data for modelling} 6 | \usage{ 7 | prepare_data(mat = NULL, sampl.eff = NULL) 8 | } 9 | \arguments{ 10 | \item{mat}{An integer matrix containing quantitative (not qualitative or binary) 11 | count data con interaction frequency (e.g. visits to flowers, number of fruits 12 | consumed per plant or species). Plants must be in rows, Animals must be in columns.} 13 | 14 | \item{sampl.eff}{A numeric vector with the sampling effort (e.g. observation hours) 15 | spent on each plant.} 16 | } 17 | \value{ 18 | A named list with all the data required to run the model. 19 | } 20 | \description{ 21 | Prepare the data for modelling 22 | } 23 | \examples{ 24 | data(web) 25 | prepare_data(web, sampl.eff = rep(20, nrow(web))) 26 | } 27 | -------------------------------------------------------------------------------- /man/plot_interaction_prob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_interaction_prob.R 3 | \name{plot_interaction_prob} 4 | \alias{plot_interaction_prob} 5 | \title{Plot heatmap of interaction probabilities} 6 | \usage{ 7 | plot_interaction_prob(post = NULL) 8 | } 9 | \arguments{ 10 | \item{post}{Data frame containing the posterior probabilities, as generated 11 | from \code{get_posterior()}.} 12 | } 13 | \value{ 14 | A ggplot object 15 | } 16 | \description{ 17 | Plot a heatmap of average interaction probabilities 18 | } 19 | \examples{ 20 | \dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} 21 | data(web) 22 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 23 | fit <- fit_model(dt, refresh = 0) 24 | post <- get_posterior(fit, dt) 25 | plot_interaction_prob(post) 26 | \dontshow{\}) # examplesIf} 27 | } 28 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | citHeader("If you use BayesianWebs, please cite both Young et al. (2021) and the package as:") 2 | 3 | bibentry( 4 | bibtype = "Article", 5 | title = "Reconstruction of plant–pollinator networks from observational data", 6 | author = c( 7 | person("Jean-Gabriel", "Young"), 8 | person("Fernanda S.", "Valdovinos"), 9 | person("M.E.J.", "Newman") 10 | ), 11 | journal = "Nature Communications", 12 | year = 2021, 13 | volume = 12, 14 | pages = 3911, 15 | doi = "https://doi.org/10.1038/s41467-021-24149-x" 16 | ) 17 | 18 | 19 | bibentry( 20 | bibtype = "Manual", 21 | title = "BayesianWebs: Bayesian Modelling of Bipartite Networks", 22 | author = c( 23 | person("Francisco", "Rodriguez-Sanchez") 24 | ), 25 | year = 2024, 26 | url = "https://pakillo.github.io/BayesianWebs/" 27 | ) 28 | -------------------------------------------------------------------------------- /docs/deps/data-deps.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /man/plot_counts_pred.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_counts_pred.R 3 | \name{plot_counts_pred} 4 | \alias{plot_counts_pred} 5 | \title{Plot heatmap of predicted counts} 6 | \usage{ 7 | plot_counts_pred(pred.df = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{pred.df}{A data frame containing the predicted counts, as generated by 11 | \code{\link[=predict_counts]{predict_counts()}}} 12 | 13 | \item{...}{Further arguments for \code{\link[network.tools:plot_web_heatmap]{network.tools::plot_web_heatmap()}}.} 14 | } 15 | \value{ 16 | A ggplot object 17 | } 18 | \description{ 19 | Plot heatmap of predicted counts 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 | pred.df <- predict_counts(fit, dt) 27 | plot_counts_pred(pred.df) 28 | plot_counts_pred(pred.df, sort = FALSE) 29 | \dontshow{\}) # examplesIf} 30 | } 31 | -------------------------------------------------------------------------------- /R/predict_counts.R: -------------------------------------------------------------------------------- 1 | #' Predict interaction counts 2 | #' 3 | #' Generate the posterior predictive distribution of counts for every pairwise 4 | #' interaction. 5 | #' 6 | #' @param fit Fitted model 7 | #' @param data Data list 8 | #' 9 | #' @return A data frame 10 | #' @export 11 | #' 12 | #' @examplesIf interactive() 13 | #' data(web) 14 | #' dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 15 | #' fit <- fit_model(dt, refresh = 0) 16 | #' predict_counts(fit, dt) 17 | 18 | predict_counts <- function(fit = NULL, data = NULL) { 19 | 20 | ## generate posteriors 21 | post <- get_posterior(fit, data, param = "all") 22 | 23 | ## add sampling effort per plant 24 | C <- data.frame(Plant = rownames(data$M), effort = data$C) 25 | post <- dplyr::left_join(post, C, by = "Plant") 26 | 27 | ## calculate predicted counts 28 | post <- dplyr::mutate(post, 29 | count = (1 - int.prob) * effort * plant.abund * animal.abund + 30 | int.prob * effort * plant.abund * animal.abund * (1 + preference)) 31 | 32 | return(post) 33 | 34 | } 35 | -------------------------------------------------------------------------------- /R/check_model.R: -------------------------------------------------------------------------------- 1 | #' Check fitted model 2 | #' 3 | #' @param fit A fitted model, as obtained from [fit_model()]. 4 | #' @param data Data list (from [prepare_data()]). 5 | #' 6 | #' @return Model checks on console and graphical window. 7 | #' @export 8 | #' @import cmdstanr 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 | #' check_model(fit, data = data) 15 | 16 | check_model <- function(fit = NULL, data = NULL) { 17 | 18 | fit$diagnostic_summary() 19 | 20 | fit$cmdstan_diagnose() 21 | 22 | print(plot_prior(fit = fit, data = data)) 23 | 24 | check_lp(fit) 25 | 26 | } 27 | 28 | 29 | # Check log posterior across chains 30 | check_lp <- function(fit = NULL) { 31 | lp <- fit$draws("lp__", format = "df") 32 | 33 | gg <- ggplot2::ggplot(lp, ggplot2::aes(.draw, lp__, colour = as.factor(.chain))) + 34 | ggplot2::geom_point() + 35 | ggplot2::theme_minimal() + 36 | ggplot2::labs(title = "Log posterior across chains") 37 | 38 | gg 39 | 40 | } 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /man/plot_residuals.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_residuals.R 3 | \name{plot_residuals} 4 | \alias{plot_residuals} 5 | \title{Plot heatmap of residuals} 6 | \usage{ 7 | plot_residuals(pred.df = NULL, data = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{pred.df}{A data frame containing the predicted counts, as generated by 11 | \code{\link[=predict_counts]{predict_counts()}}} 12 | 13 | \item{data}{Data list (from \code{prepare_data()})} 14 | 15 | \item{...}{Further arguments for \code{\link[network.tools:plot_web_heatmap]{network.tools::plot_web_heatmap()}}.} 16 | } 17 | \value{ 18 | A ggplot object 19 | } 20 | \description{ 21 | Plot heatmap of residuals (observed - predicted counts). 22 | } 23 | \examples{ 24 | \dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} 25 | data(web) 26 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 27 | fit <- fit_model(dt, refresh = 0) 28 | pred.df <- predict_counts(fit, dt) 29 | plot_residuals(pred.df, dt) 30 | plot_residuals(pred.df, dt, sort = FALSE) 31 | \dontshow{\}) # examplesIf} 32 | } 33 | -------------------------------------------------------------------------------- /man/get_posterior.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_posterior.R 3 | \name{get_posterior} 4 | \alias{get_posterior} 5 | \title{Get posterior values} 6 | \usage{ 7 | get_posterior( 8 | fit = NULL, 9 | data = NULL, 10 | param = c("all", "connectance", "preference", "plant.abund", "animal.abund", 11 | "int.prob", "link") 12 | ) 13 | } 14 | \arguments{ 15 | \item{fit}{Fitted model (from \code{\link[=fit_model]{fit_model()}})} 16 | 17 | \item{data}{Data list (from \code{\link[=prepare_data]{prepare_data()}})} 18 | 19 | \item{param}{character. Name of the parameter to retrieve the posterior samples.} 20 | } 21 | \value{ 22 | A data frame 23 | } 24 | \description{ 25 | Get posterior values 26 | } 27 | \examples{ 28 | \dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} 29 | data(web) 30 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 31 | fit <- fit_model(dt, refresh = 0) 32 | get_posterior(fit, dt, param = "connectance") 33 | 34 | int.prob <- get_posterior(fit, dt, param = "int.prob") 35 | int.prob 36 | int.prob |> tidybayes::mean_qi() # mean edge probability 37 | 38 | # all posteriors 39 | get_posterior(fit, dt, param = "all") 40 | \dontshow{\}) # examplesIf} 41 | } 42 | -------------------------------------------------------------------------------- /man/plot_prior.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_prior.R 3 | \name{plot_prior} 4 | \alias{plot_prior} 5 | \title{Plot prior distribution for r (preference) parameter} 6 | \usage{ 7 | plot_prior(beta = NULL, fit = NULL, data = NULL) 8 | } 9 | \arguments{ 10 | \item{beta}{A number > 0. Rate of the exponential distribution.} 11 | 12 | \item{fit}{A fitted model, as obtained from \code{fit_model()}.} 13 | 14 | \item{data}{Data list (from \code{\link[=prepare_data]{prepare_data()}}).} 15 | } 16 | \value{ 17 | A plot 18 | } 19 | \description{ 20 | The \code{r} (preference) parameter in Young et al. model takes a prior 21 | exponential distribution with rate = beta. Use this function to 22 | visualise the prior distribution of \code{r} given the chosen beta. 23 | Alternatively, if providing the fitted model, a plot comparing the 24 | prior versus posterior preference(s) will be produced. 25 | } 26 | \examples{ 27 | \dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} 28 | ## Providing value for beta 29 | plot_prior(beta = 0.01) 30 | plot_prior(beta = 0.001) 31 | 32 | ## Providing fitted model 33 | data(web) 34 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 35 | fit <- fit_model(dt, refresh = 0) 36 | plot_prior(fit = fit, data = dt) 37 | \dontshow{\}) # examplesIf} 38 | } 39 | -------------------------------------------------------------------------------- /R/plot_residuals.R: -------------------------------------------------------------------------------- 1 | #' Plot heatmap of residuals 2 | #' 3 | #' Plot heatmap of residuals (observed - predicted counts). 4 | #' 5 | #' @param pred.df A data frame containing the predicted counts, as generated by 6 | #' [predict_counts()] 7 | #' @param data Data list (from `prepare_data()`) 8 | #' @param ... Further arguments for [network.tools::plot_web_heatmap()]. 9 | #' 10 | #' @return A ggplot object 11 | #' @export 12 | #' 13 | #' @examplesIf interactive() 14 | #' data(web) 15 | #' dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 16 | #' fit <- fit_model(dt, refresh = 0) 17 | #' pred.df <- predict_counts(fit, dt) 18 | #' plot_residuals(pred.df, dt) 19 | #' plot_residuals(pred.df, dt, sort = FALSE) 20 | 21 | plot_residuals <- function(pred.df = NULL, data = NULL, ...) { 22 | 23 | obs <- data$M |> 24 | network.tools::wide2long() 25 | 26 | pred <- pred.df |> 27 | dplyr::select(Plant, Animal, count) |> 28 | tidybayes::mean_qi() |> 29 | dplyr::select(Plant, Animal, count) |> 30 | dplyr::left_join(obs, by = c("Plant", "Animal")) |> 31 | dplyr::mutate(resid = Visits - count) 32 | 33 | max.resid <- max(abs(pred$resid)) 34 | 35 | suppressMessages( 36 | pred |> 37 | network.tools::plot_web_heatmap(int.var = "resid", ...) + 38 | ggplot2::scale_fill_distiller(palette = "RdBu", limits = c(-max.resid, max.resid), direction = 1) + 39 | ggplot2::labs(title = "Residuals", fill = "") 40 | ) 41 | 42 | } 43 | -------------------------------------------------------------------------------- /R/prepare_data.R: -------------------------------------------------------------------------------- 1 | #' Prepare the data for modelling 2 | #' 3 | #' @param mat An integer matrix containing quantitative (not qualitative or binary) 4 | #' count data con interaction frequency (e.g. visits to flowers, number of fruits 5 | #' consumed per plant or species). Plants must be in rows, Animals must be in columns. 6 | #' @param sampl.eff A numeric vector with the sampling effort (e.g. observation hours) 7 | #' spent on each plant. 8 | #' 9 | #' @return A named list with all the data required to run the model. 10 | #' @export 11 | #' 12 | #' @examples 13 | #' data(web) 14 | #' prepare_data(web, sampl.eff = rep(20, nrow(web))) 15 | 16 | prepare_data <- function(mat = NULL, sampl.eff = NULL) { 17 | 18 | ## Checks 19 | 20 | stopifnot(is.matrix(mat)) 21 | stopifnot(is.integer(mat)) 22 | if (min(mat) < 0) { 23 | stop("There cannot be negative counts") 24 | } 25 | if (max(mat) == 1) { 26 | warning("mat must be a quantitative (not qualitative/binary) matrix with count data. Are you sure the maximum observed count is 1?") 27 | } 28 | 29 | stopifnot(length(sampl.eff) == nrow(mat)) 30 | stopifnot(is.numeric(sampl.eff)) 31 | if (max(sampl.eff) > 100) { 32 | warning("sampl.eff takes large values, which could hinder model convergence. Consider using different units (e.g. hours instead of minutes) to obtain smaller numbers") 33 | } 34 | 35 | ## 36 | 37 | ## Data list 38 | dt <- list(M = mat, n_p = nrow(mat), n_a = ncol(mat), C = sampl.eff) 39 | # dt <- tidybayes::compose_data(M = mat, n_p = nrow(mat), n_a = ncol(mat), C = sampl.eff) 40 | 41 | dt 42 | 43 | } 44 | -------------------------------------------------------------------------------- /man/fit_model.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fit_model.R 3 | \name{fit_model} 4 | \alias{fit_model} 5 | \title{Fit model} 6 | \usage{ 7 | fit_model( 8 | data = NULL, 9 | model = c("sampling_effort", "Young2021", "varying_preferences"), 10 | beta = 0.01, 11 | ... 12 | ) 13 | } 14 | \arguments{ 15 | \item{data}{A named list containing the required data, as obtained from 16 | \code{\link[=prepare_data]{prepare_data()}}.} 17 | 18 | \item{model}{character. One of "Young2021", "sampling_effort", or 19 | "varying_preferences", or a path to a file describing the Stan model in case 20 | you want to use a modified Stan model.} 21 | 22 | \item{beta}{Rate of exponential prior on \code{r} (preference) parameter. 23 | Default beta is 0.01. Increase it if you have large count numbers 24 | (can examine the resultant prior using \code{\link[=plot_prior]{plot_prior()}}).} 25 | 26 | \item{...}{Further arguments for \code{\link[cmdstanr:model-method-sample]{cmdstanr::sample()}}, like \code{iter_warmup}, 27 | \code{iter_sampling}, or \code{thin}, among others. It is recommended to increase the 28 | number of iterations (e.g. iter_sampling = 10000).} 29 | } 30 | \value{ 31 | A fitted model (\code{\link[cmdstanr:CmdStanMCMC]{cmdstanr::CmdStanMCMC()}} object). 32 | } 33 | \description{ 34 | Fit model 35 | } 36 | \examples{ 37 | \dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} 38 | data(web) 39 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 40 | fit <- fit_model(dt) 41 | \dontshow{\}) # examplesIf} 42 | } 43 | -------------------------------------------------------------------------------- /man/plot_counts_pred_obs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_counts_pred_obs.R 3 | \name{plot_counts_pred_obs} 4 | \alias{plot_counts_pred_obs} 5 | \title{Plot predicted versus observed counts} 6 | \usage{ 7 | plot_counts_pred_obs( 8 | pred.df = NULL, 9 | data = NULL, 10 | byplant = FALSE, 11 | width = 0.95, 12 | ... 13 | ) 14 | } 15 | \arguments{ 16 | \item{pred.df}{A data frame containing the predicted counts, as generated by 17 | \code{predict_counts()}} 18 | 19 | \item{data}{Data list (from \code{prepare_data()})} 20 | 21 | \item{byplant}{Logical. If TRUE, show predicted and observed counts per plant 22 | (using \code{ggplot2::facet_wrap()}). If FALSE, show all interactions in the same plot.} 23 | 24 | \item{width}{width of the credible interval (default = 0.95).} 25 | 26 | \item{...}{Further arguments to be passed to \code{ggplot2::facet_wrap()} if 27 | \code{byplant = TRUE}, or to \code{tidybayes::geom_pointinterval()} if \code{byplant = FALSE}.} 28 | } 29 | \value{ 30 | A ggplot object 31 | } 32 | \description{ 33 | Plot predicted versus observed counts 34 | } 35 | \examples{ 36 | \dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} 37 | data(web) 38 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 39 | fit <- fit_model(dt, refresh = 0) 40 | pred.df <- predict_counts(fit, dt) 41 | plot_counts_pred_obs(pred.df, dt) 42 | plot_counts_pred_obs(pred.df, dt, fatten_point = 3) 43 | plot_counts_pred_obs(pred.df, dt, byplant = TRUE) 44 | plot_counts_pred_obs(pred.df, dt, byplant = TRUE, scale = "free") 45 | \dontshow{\}) # examplesIf} 46 | } 47 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: R-CMD-check 10 | 11 | permissions: read-all 12 | 13 | jobs: 14 | R-CMD-check: 15 | timeout-minutes: 10 16 | runs-on: ${{ matrix.config.os }} 17 | 18 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 19 | 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | config: 24 | - {os: macos-latest, r: 'release'} 25 | - {os: windows-latest, r: 'release'} 26 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 27 | - {os: ubuntu-latest, r: 'release'} 28 | - {os: ubuntu-latest, r: 'oldrel-1'} 29 | 30 | env: 31 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 32 | R_KEEP_PKG_SOURCE: yes 33 | 34 | steps: 35 | - uses: actions/checkout@v4 36 | 37 | - uses: r-lib/actions/setup-pandoc@v2 38 | 39 | - uses: r-lib/actions/setup-r@v2 40 | with: 41 | r-version: ${{ matrix.config.r }} 42 | http-user-agent: ${{ matrix.config.http-user-agent }} 43 | use-public-rspm: true 44 | 45 | - uses: r-lib/actions/setup-r-dependencies@v2 46 | with: 47 | extra-packages: any::rcmdcheck 48 | needs: check 49 | 50 | - uses: r-lib/actions/check-r-package@v2 51 | with: 52 | upload-snapshots: true 53 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' 54 | -------------------------------------------------------------------------------- /docs/sitemap.xml: -------------------------------------------------------------------------------- 1 | 2 | https://pakillo.github.io/BayesianWebs/404.html 3 | https://pakillo.github.io/BayesianWebs/LICENSE.html 4 | https://pakillo.github.io/BayesianWebs/authors.html 5 | https://pakillo.github.io/BayesianWebs/index.html 6 | https://pakillo.github.io/BayesianWebs/reference/BayesianWebs-package.html 7 | https://pakillo.github.io/BayesianWebs/reference/check_model.html 8 | https://pakillo.github.io/BayesianWebs/reference/fit_model.html 9 | https://pakillo.github.io/BayesianWebs/reference/get_posterior.html 10 | https://pakillo.github.io/BayesianWebs/reference/get_seed.html 11 | https://pakillo.github.io/BayesianWebs/reference/index.html 12 | https://pakillo.github.io/BayesianWebs/reference/plot_counts_obs.html 13 | https://pakillo.github.io/BayesianWebs/reference/plot_counts_pred.html 14 | https://pakillo.github.io/BayesianWebs/reference/plot_counts_pred_obs.html 15 | https://pakillo.github.io/BayesianWebs/reference/plot_interaction_prob.html 16 | https://pakillo.github.io/BayesianWebs/reference/plot_prior.html 17 | https://pakillo.github.io/BayesianWebs/reference/plot_residuals.html 18 | https://pakillo.github.io/BayesianWebs/reference/predict_counts.html 19 | https://pakillo.github.io/BayesianWebs/reference/prepare_data.html 20 | https://pakillo.github.io/BayesianWebs/reference/web.html 21 | 22 | 23 | -------------------------------------------------------------------------------- /R/fit_model.R: -------------------------------------------------------------------------------- 1 | #' Fit model 2 | #' 3 | #' @param data A named list containing the required data, as obtained from 4 | #' [prepare_data()]. 5 | #' @param model character. One of "Young2021", "sampling_effort", or 6 | #' "varying_preferences", or a path to a file describing the Stan model in case 7 | #' you want to use a modified Stan model. 8 | #' @param beta Rate of exponential prior on `r` (preference) parameter. 9 | #' Default beta is 0.01. Increase it if you have large count numbers 10 | #' (can examine the resultant prior using [plot_prior()]). 11 | #' @param ... Further arguments for [cmdstanr::sample()], like `iter_warmup`, 12 | #' `iter_sampling`, or `thin`, among others. It is recommended to increase the 13 | #' number of iterations (e.g. iter_sampling = 10000). 14 | #' 15 | #' @return A fitted model ([cmdstanr::CmdStanMCMC()] object). 16 | #' @export 17 | #' @import cmdstanr 18 | #' 19 | #' @examplesIf interactive() 20 | #' data(web) 21 | #' dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 22 | #' fit <- fit_model(dt) 23 | 24 | fit_model <- function(data = NULL, 25 | model = c("sampling_effort", "Young2021", "varying_preferences"), 26 | beta = 0.01, 27 | ...) { 28 | 29 | if (is.null(data)) { 30 | stop("Please provide the data as produced by 'prepare_data()'") 31 | } 32 | 33 | model <- match.arg(model) # TODO: remove this later to allow for user models 34 | 35 | if (model %in% c("sampling_effort", "Young2021", "varying_preferences")) { 36 | mod.stan <- system.file(paste0("models/", model, ".stan"), package = "BayesianWebs") 37 | } else { 38 | mod.stan <- model 39 | } 40 | 41 | ## Add beta to data file 42 | stopifnot(beta > 0) 43 | data$beta <- beta 44 | 45 | 46 | ## compile model 47 | model.eff <- cmdstanr::cmdstan_model(mod.stan) 48 | 49 | fit <- model.eff$sample(data, ...) 50 | 51 | } 52 | -------------------------------------------------------------------------------- /inst/models/Young2021.stan: -------------------------------------------------------------------------------- 1 | data { 2 | // Dimensions of the data matrix, and matrix itself. 3 | int n_p; 4 | int n_a; 5 | array[n_p, n_a] int M; 6 | } 7 | transformed data { 8 | // Pre-compute the marginals of M to save computation in the model loop. 9 | array[n_p] int M_rows = rep_array(0, n_p); 10 | array[n_a] int M_cols = rep_array(0, n_a); 11 | int M_tot = 0; 12 | for (i in 1:n_p) { 13 | for (j in 1:n_a) { 14 | M_rows[i] += M[i, j]; 15 | M_cols[j] += M[i, j]; 16 | M_tot += M[i, j]; 17 | } 18 | } 19 | } 20 | parameters { 21 | real C; 22 | real r; 23 | simplex[n_p] sigma; 24 | simplex[n_a] tau; 25 | real rho; 26 | } 27 | model { 28 | // Prior 29 | r ~ exponential(0.01); 30 | 31 | // Global sums and parameters 32 | target += M_tot * log(C) - C; 33 | // Weighted marginals of the data matrix 34 | for (i in 1:n_p) { 35 | target += M_rows[i] * log(sigma[i]); 36 | } 37 | for (j in 1:n_a) { 38 | target += M_cols[j] * log(tau[j]); 39 | } 40 | // Pairwise loop 41 | for (i in 1:n_p) { 42 | for (j in 1:n_a) { 43 | real nu_ij_0 = log(1 - rho); 44 | real nu_ij_1 = log(rho) + M[i,j] * log(1 + r) - C * r * sigma[i] * tau[j]; 45 | if (nu_ij_0 > nu_ij_1) 46 | target += nu_ij_0 + log1p_exp(nu_ij_1 - nu_ij_0); 47 | else 48 | target += nu_ij_1 + log1p_exp(nu_ij_0 - nu_ij_1); 49 | } 50 | } 51 | } 52 | generated quantities { 53 | // Posterior edge probability matrix 54 | array[n_p, n_a] real Q; 55 | for (i in 1:n_p) { 56 | for (j in 1:n_a) { 57 | real nu_ij_0 = log(1 - rho); 58 | real nu_ij_1 = log(rho) + M[i,j] * log(1 + r) - C * r * sigma[i] * tau[j]; 59 | if (nu_ij_1 > 0) 60 | Q[i, j] = 1 / (1+ exp(nu_ij_0 - nu_ij_1)); 61 | else 62 | Q[i, j] = exp(nu_ij_1) / (exp(nu_ij_0) + exp(nu_ij_1)); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /inst/models/sampling_effort.stan: -------------------------------------------------------------------------------- 1 | data { 2 | // Dimensions of the data matrix, and matrix itself. 3 | int n_p; 4 | int n_a; 5 | array[n_p, n_a] int M; 6 | vector [n_p] C; 7 | real beta; // rate for exponential prior on r parameter 8 | } 9 | 10 | transformed data { 11 | // Pre-compute the marginals of M to save computation in the model loop. 12 | array[n_p] int M_rows = rep_array(0, n_p); 13 | array[n_a] int M_cols = rep_array(0, n_a); 14 | int M_tot = 0; 15 | for (i in 1:n_p) { 16 | for (j in 1:n_a) { 17 | M_rows[i] += M[i, j]; 18 | M_cols[j] += M[i, j]; 19 | M_tot += M[i, j]; 20 | } 21 | } 22 | } 23 | parameters { 24 | // real C; 25 | real r; 26 | simplex[n_p] sigma; 27 | simplex[n_a] tau; 28 | real rho; 29 | } 30 | model { 31 | // Prior 32 | r ~ exponential(beta); 33 | 34 | // Global sums and parameters 35 | target += M_tot * log(C) - C; 36 | // Weighted marginals of the data matrix 37 | for (i in 1:n_p) { 38 | target += M_rows[i] * log(sigma[i]); 39 | } 40 | for (j in 1:n_a) { 41 | target += M_cols[j] * log(tau[j]); 42 | } 43 | // Pairwise loop 44 | for (i in 1:n_p) { 45 | for (j in 1:n_a) { 46 | real nu_ij_0 = log(1 - rho); 47 | real nu_ij_1 = log(rho) + M[i,j] * log(1 + r) - C[i] * r * sigma[i] * tau[j]; 48 | if (nu_ij_0 > nu_ij_1) 49 | target += nu_ij_0 + log1p_exp(nu_ij_1 - nu_ij_0); 50 | else 51 | target += nu_ij_1 + log1p_exp(nu_ij_0 - nu_ij_1); 52 | } 53 | } 54 | } 55 | generated quantities { 56 | // Posterior edge probability matrix 57 | array[n_p, n_a] real Q; 58 | for (i in 1:n_p) { 59 | for (j in 1:n_a) { 60 | real nu_ij_0 = log(1 - rho); 61 | real nu_ij_1 = log(rho) + M[i,j] * log(1 + r) - C[i] * r * sigma[i] * tau[j]; 62 | if (nu_ij_1 > 0) 63 | Q[i, j] = 1 / (1+ exp(nu_ij_0 - nu_ij_1)); 64 | else 65 | Q[i, j] = exp(nu_ij_1) / (exp(nu_ij_0) + exp(nu_ij_1)); 66 | } 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /docs/deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Table of Contents v1.0.1 (http://afeld.github.io/bootstrap-toc/) 3 | * Copyright 2015 Aidan Feldman 4 | * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ 5 | !function(a){"use strict";window.Toc={helpers:{findOrFilter:function(e,t){var n=e.find(t);return e.filter(t).add(n).filter(":not([data-toc-skip])")},generateUniqueIdBase:function(e){return a(e).text().trim().replace(/\'/gi,"").replace(/[& +$,:;=?@"#{}|^~[`%!'<>\]\.\/\(\)\*\\\n\t\b\v]/g,"-").replace(/-{2,}/g,"-").substring(0,64).replace(/^-+|-+$/gm,"").toLowerCase()||e.tagName.toLowerCase()},generateUniqueId:function(e){for(var t=this.generateUniqueIdBase(e),n=0;;n++){var r=t;if(0')},createChildNavList:function(e){var t=this.createNavList();return e.append(t),t},generateNavEl:function(e,t){var n=a('');n.attr("href","#"+e),n.text(t);var r=a("
  • ");return r.append(n),r},generateNavItem:function(e){var t=this.generateAnchor(e),n=a(e),r=n.data("toc-text")||n.text();return this.generateNavEl(t,r)},getTopLevel:function(e){for(var t=1;t<=6;t++){if(1 n_p; 4 | int n_a; 5 | array[n_p, n_a] int M; 6 | vector [n_p] C; 7 | real beta; // rate for exponential prior on r parameter 8 | } 9 | 10 | transformed data { 11 | // Pre-compute the marginals of M to save computation in the model loop. 12 | array[n_p] int M_rows = rep_array(0, n_p); 13 | array[n_a] int M_cols = rep_array(0, n_a); 14 | int M_tot = 0; 15 | for (i in 1:n_p) { 16 | for (j in 1:n_a) { 17 | M_rows[i] += M[i, j]; 18 | M_cols[j] += M[i, j]; 19 | M_tot += M[i, j]; 20 | } 21 | } 22 | } 23 | parameters { 24 | // real C; 25 | vector [n_a] r; 26 | simplex[n_p] sigma; 27 | simplex[n_a] tau; 28 | real rho; 29 | } 30 | model { 31 | // Prior 32 | for (j in 1:n_a) { 33 | r[j] ~ exponential(beta); 34 | } 35 | 36 | // Global sums and parameters 37 | target += M_tot * log(C) - C; 38 | // Weighted marginals of the data matrix 39 | for (i in 1:n_p) { 40 | target += M_rows[i] * log(sigma[i]); 41 | } 42 | for (j in 1:n_a) { 43 | target += M_cols[j] * log(tau[j]); 44 | } 45 | // Pairwise loop 46 | for (i in 1:n_p) { 47 | for (j in 1:n_a) { 48 | real nu_ij_0 = log(1 - rho); 49 | real nu_ij_1 = log(rho) + M[i,j] * log(1 + r[j]) - C[i] * r[j] * sigma[i] * tau[j]; 50 | if (nu_ij_0 > nu_ij_1) 51 | target += nu_ij_0 + log1p_exp(nu_ij_1 - nu_ij_0); 52 | else 53 | target += nu_ij_1 + log1p_exp(nu_ij_0 - nu_ij_1); 54 | } 55 | } 56 | } 57 | generated quantities { 58 | // Posterior edge probability matrix 59 | array[n_p, n_a] real Q; 60 | for (i in 1:n_p) { 61 | for (j in 1:n_a) { 62 | real nu_ij_0 = log(1 - rho); 63 | real nu_ij_1 = log(rho) + M[i,j] * log(1 + r[j]) - C[i] * r[j] * sigma[i] * tau[j]; 64 | if (nu_ij_1 > 0) 65 | Q[i, j] = 1 / (1+ exp(nu_ij_0 - nu_ij_1)); 66 | else 67 | Q[i, j] = exp(nu_ij_1) / (exp(nu_ij_0) + exp(nu_ij_1)); 68 | } 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /R/plot_counts_pred_obs.R: -------------------------------------------------------------------------------- 1 | #' Plot predicted versus observed counts 2 | #' 3 | #' @param pred.df A data frame containing the predicted counts, as generated by 4 | #' `predict_counts()` 5 | #' @param data Data list (from `prepare_data()`) 6 | #' @param byplant Logical. If TRUE, show predicted and observed counts per plant 7 | #' (using `ggplot2::facet_wrap()`). If FALSE, show all interactions in the same plot. 8 | #' @param width width of the credible interval (default = 0.95). 9 | #' @param ... Further arguments to be passed to `ggplot2::facet_wrap()` if 10 | #' `byplant = TRUE`, or to `tidybayes::geom_pointinterval()` if `byplant = FALSE`. 11 | #' 12 | #' @return A ggplot object 13 | #' @export 14 | #' 15 | #' @examplesIf interactive() 16 | #' data(web) 17 | #' dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 18 | #' fit <- fit_model(dt, refresh = 0) 19 | #' pred.df <- predict_counts(fit, dt) 20 | #' plot_counts_pred_obs(pred.df, dt) 21 | #' plot_counts_pred_obs(pred.df, dt, fatten_point = 3) 22 | #' plot_counts_pred_obs(pred.df, dt, byplant = TRUE) 23 | #' plot_counts_pred_obs(pred.df, dt, byplant = TRUE, scale = "free") 24 | 25 | plot_counts_pred_obs <- function(pred.df = NULL, data = NULL, byplant = FALSE, width = 0.95, ...) { 26 | 27 | obs <- data$M |> 28 | network.tools::wide2long(int.name = "Count.obs") 29 | 30 | pred <- pred.df |> 31 | dplyr::select(Plant, Animal, Count.pred = count) |> 32 | tidybayes::mean_qi(.width = width) |> 33 | dplyr::left_join(obs, by = c("Plant", "Animal")) 34 | 35 | gg <- ggplot2::ggplot(pred) + 36 | ggplot2::geom_abline(intercept = 0, slope = 1, lty = 2) + 37 | ggplot2::labs(x = "Observed counts", y = "Predicted counts") 38 | 39 | if (isTRUE(byplant)) { 40 | gg <- gg + 41 | tidybayes::geom_pointinterval(ggplot2::aes(x = Count.obs, y = Count.pred, 42 | ymin = .lower, ymax = .upper)) + 43 | ggplot2::facet_wrap(~Plant, ...) 44 | } else { 45 | gg <- gg + 46 | tidybayes::geom_pointinterval(ggplot2::aes(x = Count.obs, y = Count.pred, 47 | ymin = .lower, ymax = .upper), 48 | ...) 49 | } 50 | 51 | return(gg) 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /docs/lightswitch.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/) 4 | * Copyright 2011-2023 The Bootstrap Authors 5 | * Licensed under the Creative Commons Attribution 3.0 Unported License. 6 | * Updates for {pkgdown} by the {bslib} authors, also licensed under CC-BY-3.0. 7 | */ 8 | 9 | const getStoredTheme = () => localStorage.getItem('theme') 10 | const setStoredTheme = theme => localStorage.setItem('theme', theme) 11 | 12 | const getPreferredTheme = () => { 13 | const storedTheme = getStoredTheme() 14 | if (storedTheme) { 15 | return storedTheme 16 | } 17 | 18 | return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' 19 | } 20 | 21 | const setTheme = theme => { 22 | if (theme === 'auto') { 23 | document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')) 24 | } else { 25 | document.documentElement.setAttribute('data-bs-theme', theme) 26 | } 27 | } 28 | 29 | function bsSetupThemeToggle () { 30 | 'use strict' 31 | 32 | const showActiveTheme = (theme, focus = false) => { 33 | var activeLabel, activeIcon; 34 | 35 | document.querySelectorAll('[data-bs-theme-value]').forEach(element => { 36 | const buttonTheme = element.getAttribute('data-bs-theme-value') 37 | const isActive = buttonTheme == theme 38 | 39 | element.classList.toggle('active', isActive) 40 | element.setAttribute('aria-pressed', isActive) 41 | 42 | if (isActive) { 43 | activeLabel = element.textContent; 44 | activeIcon = element.querySelector('span').classList.value; 45 | } 46 | }) 47 | 48 | const themeSwitcher = document.querySelector('#dropdown-lightswitch') 49 | if (!themeSwitcher) { 50 | return 51 | } 52 | 53 | themeSwitcher.setAttribute('aria-label', activeLabel) 54 | themeSwitcher.querySelector('span').classList.value = activeIcon; 55 | 56 | if (focus) { 57 | themeSwitcher.focus() 58 | } 59 | } 60 | 61 | window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { 62 | const storedTheme = getStoredTheme() 63 | if (storedTheme !== 'light' && storedTheme !== 'dark') { 64 | setTheme(getPreferredTheme()) 65 | } 66 | }) 67 | 68 | window.addEventListener('DOMContentLoaded', () => { 69 | showActiveTheme(getPreferredTheme()) 70 | 71 | document 72 | .querySelectorAll('[data-bs-theme-value]') 73 | .forEach(toggle => { 74 | toggle.addEventListener('click', () => { 75 | const theme = toggle.getAttribute('data-bs-theme-value') 76 | setTheme(theme) 77 | setStoredTheme(theme) 78 | showActiveTheme(theme, true) 79 | }) 80 | }) 81 | }) 82 | } 83 | 84 | setTheme(getPreferredTheme()); 85 | bsSetupThemeToggle(); 86 | -------------------------------------------------------------------------------- /R/plot_prior.R: -------------------------------------------------------------------------------- 1 | #' Plot prior distribution for r (preference) parameter 2 | #' 3 | #' The `r` (preference) parameter in Young et al. model takes a prior 4 | #' exponential distribution with rate = beta. Use this function to 5 | #' visualise the prior distribution of `r` given the chosen beta. 6 | #' Alternatively, if providing the fitted model, a plot comparing the 7 | #' prior versus posterior preference(s) will be produced. 8 | #' 9 | #' @param beta A number > 0. Rate of the exponential distribution. 10 | #' @param fit A fitted model, as obtained from `fit_model()`. 11 | #' @param data Data list (from [prepare_data()]). 12 | #' 13 | #' @return A plot 14 | #' @export 15 | #' 16 | #' @examplesIf interactive() 17 | #' ## Providing value for beta 18 | #' plot_prior(beta = 0.01) 19 | #' plot_prior(beta = 0.001) 20 | #' 21 | #' ## Providing fitted model 22 | #' data(web) 23 | #' dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 24 | #' fit <- fit_model(dt, refresh = 0) 25 | #' plot_prior(fit = fit, data = dt) 26 | 27 | plot_prior <- function(beta = NULL, fit = NULL, data = NULL) { 28 | 29 | if (is.null(fit)) { 30 | if (is.null(beta)) { 31 | stop("Please provide either a value for beta or a fitted model") 32 | } 33 | df <- data.frame(prior = stats::rexp(10000, rate = beta)) 34 | gg <- ggplot2::ggplot(df) + 35 | ggplot2::geom_density(ggplot2::aes(prior), bounds = c(0, Inf), fill = "grey40") + 36 | ggplot2::theme_minimal() + 37 | ggplot2::labs(title = paste0("Prior probability for r (preference) parameter ", 38 | "with beta = ", beta), 39 | x = "") 40 | } 41 | 42 | if (!is.null(fit)) { 43 | if (is.null(data)) { 44 | stop("Please provide the data list used to fit the model") 45 | } 46 | beta.model <- get_beta(fit) 47 | if (is.numeric(beta) && !identical(beta, beta.model)) { 48 | warning("The beta used to fit the model is ", beta.model, ", not ", beta) 49 | } 50 | df.prior <- data.frame(prior = stats::rexp(10000, rate = beta.model)) 51 | df.post <- get_posterior(fit, param = "preference", data = data) 52 | 53 | gg <- ggplot2::ggplot(df.prior) + 54 | ggplot2::geom_density(ggplot2::aes(prior), bounds = c(0, Inf), fill = "grey40") + 55 | ggplot2::theme_minimal() + 56 | ggplot2::labs(title = "Preference (r) parameter: prior (dark grey) vs posterior (light grey) distribution", 57 | x = "") 58 | 59 | if ("Animal" %in% names(df.post)) { 60 | gg <- gg + 61 | ggplot2::geom_density(ggplot2::aes(preference, group = Animal), 62 | bounds = c(0, Inf), fill = NA, 63 | data = df.post) 64 | } else { 65 | gg <- gg + 66 | ggplot2::geom_density(ggplot2::aes(preference), 67 | bounds = c(0, Inf), fill = "grey90", 68 | data = df.post, alpha = 0.5) 69 | 70 | 71 | } 72 | 73 | } 74 | 75 | return(gg) 76 | 77 | } 78 | 79 | 80 | 81 | get_beta <- function(fit = NULL) { 82 | datafile <- readLines(fit$data_file()) # reading json 83 | beta.info <- datafile[grep("beta", datafile)] 84 | beta <- as.numeric(gsub('.*beta\": ', "", beta.info)) 85 | return(beta) 86 | } 87 | -------------------------------------------------------------------------------- /R/get_posterior.R: -------------------------------------------------------------------------------- 1 | #' Get posterior values 2 | #' 3 | #' @param fit Fitted model (from [fit_model()]) 4 | #' @param data Data list (from [prepare_data()]) 5 | #' @param param character. Name of the parameter to retrieve the posterior samples. 6 | #' 7 | #' @return A data frame 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 | #' get_posterior(fit, dt, param = "connectance") 15 | #' 16 | #' int.prob <- get_posterior(fit, dt, param = "int.prob") 17 | #' int.prob 18 | #' int.prob |> tidybayes::mean_qi() # mean edge probability 19 | #' 20 | #' # all posteriors 21 | #' get_posterior(fit, dt, param = "all") 22 | 23 | get_posterior <- function(fit = NULL, 24 | data = NULL, 25 | param = c("all", 26 | "connectance", 27 | "preference", 28 | "plant.abund", 29 | "animal.abund", 30 | "int.prob", 31 | "link")) { 32 | 33 | # r = avg. visits from mutualists (preference) 34 | # rho = connectance 35 | # sigma = plant.abund 36 | # tau = animal.abund 37 | # Q = interaction probability 38 | 39 | param <- match.arg(param) 40 | 41 | params_all <- function(fit) { 42 | if (fit$metadata()$model_name == "varying_preferences_model") { 43 | out <- tidybayes::spread_draws(fit, rho, r[Animal], sigma[Plant], tau[Animal], Q[Plant, Animal]) 44 | } else { 45 | out <- tidybayes::spread_draws(fit, rho, r, sigma[Plant], tau[Animal], Q[Plant, Animal]) 46 | } 47 | return(out) 48 | } 49 | 50 | params_preference <- function(fit) { 51 | if (fit$metadata()$model_name == "varying_preferences_model") { 52 | out <- tidybayes::spread_draws(fit, r[Animal]) 53 | } else { 54 | out <- tidybayes::spread_draws(fit, r) 55 | } 56 | return(out) 57 | } 58 | 59 | 60 | post <- switch( 61 | param, 62 | all = params_all(fit), 63 | connectance = tidybayes::spread_draws(fit, rho), 64 | preference = params_preference(fit), 65 | plant.abund = tidybayes::spread_draws(fit, sigma[Plant]), 66 | animal.abund = tidybayes::spread_draws(fit, tau[Animal]), 67 | int.prob = tidybayes::spread_draws(fit, Q[Plant, Animal]), 68 | link = tidybayes::spread_draws(fit, Q[Plant, Animal]), 69 | ) 70 | 71 | # use more informative names 72 | param.names <- c( 73 | connectance = "rho", 74 | preference = "r", 75 | plant.abund = "sigma", 76 | animal.abund = "tau", 77 | int.prob = "Q") 78 | 79 | post <- dplyr::rename(post, dplyr::any_of(param.names)) 80 | 81 | ## generate posteriors of link existence 82 | if (param == "all" | param == "link") { 83 | post <- is_there_link(post) 84 | } 85 | 86 | 87 | 88 | ## rename plants and animals with original labels 89 | 90 | if ("Animal" %in% names(post)) { 91 | animals <- data.frame(Animal = 1:ncol(data$M), Animal.name = colnames(data$M)) 92 | post <- post |> 93 | dplyr::mutate(Animal = animals$Animal.name[match(Animal, animals$Animal)]) |> 94 | dplyr::relocate(Animal) 95 | } 96 | 97 | if ("Plant" %in% names(post)) { 98 | plants <- data.frame(Plant = 1:nrow(data$M), Plant.name = rownames(data$M)) 99 | post <- post |> 100 | dplyr::mutate(Plant = plants$Plant.name[match(Plant, plants$Plant)]) |> 101 | dplyr::relocate(Plant) 102 | } 103 | 104 | return(post) 105 | 106 | 107 | } 108 | -------------------------------------------------------------------------------- /docs/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Page not found (404) • BayesianWebs 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Skip to contents 17 | 18 | 19 |
    45 |
    46 |
    51 | 52 | Content not found. Please use links in the navbar. 53 | 54 |
    55 |
    56 | 57 | 58 |
    61 | 62 | 65 | 66 |
    67 |
    68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | ```{r, include = FALSE} 8 | knitr::opts_chunk$set( 9 | collapse = TRUE, 10 | comment = "#>", 11 | fig.path = "man/figures/README-", 12 | out.width = "100%" 13 | ) 14 | ``` 15 | 16 | # BayesianWebs 17 | 18 | 19 | ![](https://img.shields.io/github/r-package/v/Pakillo/BayesianWebs) 20 | [![R-CMD-check](https://github.com/Pakillo/BayesianWebs/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/Pakillo/BayesianWebs/actions/workflows/R-CMD-check.yaml) 21 | `r badger::badge_lifecycle("stable")` 22 | `r badger::badge_repostatus("Active")` 23 | [![HitCount](https://hits.dwyl.com/Pakillo/BayesianWebs.svg?style=flat-square)](https://hits.dwyl.com/Pakillo/BayesianWebs) 24 | [![HitCount](https://hits.dwyl.com/Pakillo/BayesianWebs.svg?style=flat-square&show=unique)](https://hits.dwyl.com/Pakillo/BayesianWebs) 25 | 26 | 27 | The BayesianWebs R package facilitates modelling bipartite networks (like pollination, frugivory, or herbivory networks) using the Bayesian framework developed by [Young et al. (2021)](https://doi.org/10.1038/s41467-021-24149-x). 28 | 29 | Inferring the structure of bipartite networks from field (observational) data is a challenging task. Interaction data are hard to collect and require typically large sampling efforts, particularly to characterize infrequent interactions. Inferred network structure is highly sensitive to sampling design, effort, and completeness. Comparing networks from different studies without accounting for these sampling effects may lead to mistaken inferences. 30 | 31 | This package uses Bayesian modelling to infer the posterior probability of each pairwise interaction in bipartite networks, accounting for sampling completeness and the inherent stochasticity of field observation data. 32 | 33 | ## Installation 34 | 35 | You can install the development version of BayesianWebs from [GitHub](https://github.com/) with: 36 | 37 | ``` r 38 | # install.packages("remotes") 39 | remotes::install_github("Pakillo/BayesianWebs") 40 | ``` 41 | 42 | The package requires a working installation of [Stan](https://mc-stan.org/). If you don't have `CmdStan` installed, after installing `BayesianWebs` run: 43 | 44 | ```r 45 | cmdstanr::install_cmdstan() 46 | ``` 47 | 48 | 49 | ## Example 50 | 51 | ```{r example} 52 | library(BayesianWebs) 53 | ``` 54 | 55 | Let's infer the structure of an example dataset from [Kaiser-Bunbury et al. 2017](https://doi.org/10.1038/nature21071) as in Young et al. 2021: 56 | 57 | ```{r} 58 | data(web) 59 | ``` 60 | 61 | This is an adjacency matrix collecting the number of visits of 21 animals on 8 plants: 62 | 63 | ```{r} 64 | web 65 | ``` 66 | 67 | ```{r} 68 | plot_counts_obs(web, sort = FALSE) 69 | ``` 70 | 71 | First, prepare the data for modelling. Here we assume constant sampling effort among plants: 72 | 73 | ```{r} 74 | dt <- prepare_data(mat = web, sampl.eff = rep(20, nrow(web))) 75 | ``` 76 | 77 | Now fit the model. There are several models available: the original model used in Young et al. (2021), a model that takes into account varying sampling effort among plants, and a model that allows for varying preferences among animals. The user can also provide a customised Stan model. See `fit_model()`. 78 | 79 | Here we run 4 parallel chains: 80 | 81 | ```{r} 82 | set.seed(1) 83 | options(mc.cores = 4) 84 | fit <- fit_model(dt, refresh = 0) 85 | ``` 86 | 87 | Check model: 88 | 89 | ```{r} 90 | check_model(fit, data = dt) 91 | ``` 92 | 93 | Get the posteriors: 94 | 95 | ```{r} 96 | post <- get_posterior(fit, data = dt) 97 | head(post) 98 | ``` 99 | 100 | ```{r} 101 | plot_interaction_prob(post) 102 | ``` 103 | 104 | Predict interaction counts: 105 | 106 | ```{r} 107 | pred.df <- predict_counts(fit, data = dt) 108 | plot_counts_pred(pred.df, sort = FALSE) 109 | ``` 110 | 111 | Compare observed and predicted counts: 112 | 113 | ```{r} 114 | plot_counts_pred_obs(pred.df, data = dt) 115 | ``` 116 | 117 | Plot residuals: 118 | 119 | ```{r} 120 | plot_residuals(pred.df, data = dt, sort = FALSE) 121 | ``` 122 | 123 | 124 | ## Citation 125 | 126 | If you use `BayesianWebs` please cite it: 127 | 128 | ```{r comment=NA} 129 | citation("BayesianWebs") 130 | ``` 131 | 132 | 133 | -------------------------------------------------------------------------------- /docs/deps/headroom-0.11.0/headroom.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * headroom.js v0.11.0 - Give your page some headroom. Hide your header until you need it 3 | * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js 4 | * License: MIT 5 | */ 6 | 7 | !function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=ls.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t,n){n=n||{},Object.assign(this,o.options,n),this.classes=Object.assign({},o.options.classes,n.classes),this.elem=t,this.tolerance=function(t){return t===Object(t)?t:{down:t,up:t}}(this.tolerance),this.initialised=!1,this.frozen=!1}return o.prototype={constructor:o,init:function(){return o.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},o.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},o.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),o}); -------------------------------------------------------------------------------- /docs/authors.html: -------------------------------------------------------------------------------- 1 | 2 | Authors and Citation • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    32 | 33 |
    34 |

    Authors

    35 | 36 |
    • 37 |

      Francisco Rodriguez-Sanchez. Author, maintainer. 38 |

      39 |
    • 40 |
    41 | 42 |
    43 |

    Citation

    44 |

    Source: inst/CITATION

    45 | 46 |

    Young J, Valdovinos F, Newman M (2021). 47 | “Reconstruction of plant–pollinator networks from observational data.” 48 | Nature Communications, 12, 3911. 49 | doi:10.1038/s41467-021-24149-x. 50 |

    51 |
    @Article{,
    52 |   title = {Reconstruction of plant–pollinator networks from observational data},
    53 |   author = {Jean-Gabriel Young and Fernanda S. Valdovinos and M.E.J. Newman},
    54 |   journal = {Nature Communications},
    55 |   year = {2021},
    56 |   volume = {12},
    57 |   pages = {3911},
    58 |   doi = {https://doi.org/10.1038/s41467-021-24149-x},
    59 | }
    60 |

    Rodriguez-Sanchez F (2024). 61 | BayesianWebs: Bayesian Modelling of Bipartite Networks. 62 | https://pakillo.github.io/BayesianWebs/. 63 |

    64 |
    @Manual{,
    65 |   title = {BayesianWebs: Bayesian Modelling of Bipartite Networks},
    66 |   author = {Francisco Rodriguez-Sanchez},
    67 |   year = {2024},
    68 |   url = {https://pakillo.github.io/BayesianWebs/},
    69 | }
    70 |
    71 | 72 |
    74 | 75 | 76 |
    79 | 80 | 83 | 84 |
    85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /docs/reference/web.html: -------------------------------------------------------------------------------- 1 | 2 | Plant-pollinator network — web • BayesianWebs 5 | Skip to contents 6 | 7 | 8 |
    29 |
    30 |
    36 | 37 |
    38 |

    An example bipartite network of 8 plant species and 21 pollinators, 39 | from Kaiser-Bunbury et al. 2017.

    40 |
    41 | 42 |
    43 |

    Usage

    44 |
    web
    45 |
    46 | 47 |
    48 |

    Format

    49 | 50 |
    51 |

    web

    52 | 53 | 54 |

    A numeric (integer) matrix with 8 rows (representing plants) and 21 columns 55 | (representing animals)

    56 |
    57 | 58 |
    59 |
    60 |

    Source

    61 |

    Kaiser-Bunbury, C., Mougal, J., Whittington, A. et al. 62 | Ecosystem restoration strengthens pollination network resilience and function. 63 | Nature 542, 223–227 (2017). https://doi.org/10.1038/nature21071

    64 |
    65 | 66 |
    68 | 69 | 70 |
    73 | 74 | 77 | 78 |
    79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /docs/reference/BayesianWebs-package.html: -------------------------------------------------------------------------------- 1 | 2 | BayesianWebs: Bayesian Modelling of Bipartite Networks — BayesianWebs-package • BayesianWebs 5 | Skip to contents 6 | 7 | 8 |
    29 |
    30 |
    36 | 37 |
    38 |

    Bayesian modelling of bipartite network structure, following the approach of Young et al. doi:10.1038/s41467-021-24149-x 39 | .

    40 |
    41 | 42 | 43 |
    44 |

    See also

    45 | 48 |
    49 |
    50 |

    Author

    51 |

    Maintainer: Francisco Rodriguez-Sanchez f.rodriguez.sanc@gmail.com (ORCID)

    52 |
    53 | 54 |
    56 | 57 | 58 |
    61 | 62 | 65 | 66 |
    67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /docs/pkgdown.js: -------------------------------------------------------------------------------- 1 | /* http://gregfranko.com/blog/jquery-best-practices/ */ 2 | (function($) { 3 | $(function() { 4 | 5 | $('nav.navbar').headroom(); 6 | 7 | Toc.init({ 8 | $nav: $("#toc"), 9 | $scope: $("main h2, main h3, main h4, main h5, main h6") 10 | }); 11 | 12 | if ($('#toc').length) { 13 | $('body').scrollspy({ 14 | target: '#toc', 15 | offset: $("nav.navbar").outerHeight() + 1 16 | }); 17 | } 18 | 19 | // Activate popovers 20 | $('[data-bs-toggle="popover"]').popover({ 21 | container: 'body', 22 | html: true, 23 | trigger: 'focus', 24 | placement: "top", 25 | sanitize: false, 26 | }); 27 | 28 | $('[data-bs-toggle="tooltip"]').tooltip(); 29 | 30 | /* Clipboard --------------------------*/ 31 | 32 | function changeTooltipMessage(element, msg) { 33 | var tooltipOriginalTitle=element.getAttribute('data-bs-original-title'); 34 | element.setAttribute('data-bs-original-title', msg); 35 | $(element).tooltip('show'); 36 | element.setAttribute('data-bs-original-title', tooltipOriginalTitle); 37 | } 38 | 39 | if(ClipboardJS.isSupported()) { 40 | $(document).ready(function() { 41 | var copyButton = ""; 42 | 43 | $("div.sourceCode").addClass("hasCopyButton"); 44 | 45 | // Insert copy buttons: 46 | $(copyButton).prependTo(".hasCopyButton"); 47 | 48 | // Initialize tooltips: 49 | $('.btn-copy-ex').tooltip({container: 'body'}); 50 | 51 | // Initialize clipboard: 52 | var clipboard = new ClipboardJS('[data-clipboard-copy]', { 53 | text: function(trigger) { 54 | return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); 55 | } 56 | }); 57 | 58 | clipboard.on('success', function(e) { 59 | changeTooltipMessage(e.trigger, 'Copied!'); 60 | e.clearSelection(); 61 | }); 62 | 63 | clipboard.on('error', function(e) { 64 | changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); 65 | }); 66 | 67 | }); 68 | } 69 | 70 | /* Search marking --------------------------*/ 71 | var url = new URL(window.location.href); 72 | var toMark = url.searchParams.get("q"); 73 | var mark = new Mark("main#main"); 74 | if (toMark) { 75 | mark.mark(toMark, { 76 | accuracy: { 77 | value: "complementary", 78 | limiters: [",", ".", ":", "/"], 79 | } 80 | }); 81 | } 82 | 83 | /* Search --------------------------*/ 84 | /* Adapted from https://github.com/rstudio/bookdown/blob/2d692ba4b61f1e466c92e78fd712b0ab08c11d31/inst/resources/bs4_book/bs4_book.js#L25 */ 85 | // Initialise search index on focus 86 | var fuse; 87 | $("#search-input").focus(async function(e) { 88 | if (fuse) { 89 | return; 90 | } 91 | 92 | $(e.target).addClass("loading"); 93 | var response = await fetch($("#search-input").data("search-index")); 94 | var data = await response.json(); 95 | 96 | var options = { 97 | keys: ["what", "text", "code"], 98 | ignoreLocation: true, 99 | threshold: 0.1, 100 | includeMatches: true, 101 | includeScore: true, 102 | }; 103 | fuse = new Fuse(data, options); 104 | 105 | $(e.target).removeClass("loading"); 106 | }); 107 | 108 | // Use algolia autocomplete 109 | var options = { 110 | autoselect: true, 111 | debug: true, 112 | hint: false, 113 | minLength: 2, 114 | }; 115 | var q; 116 | async function searchFuse(query, callback) { 117 | await fuse; 118 | 119 | var items; 120 | if (!fuse) { 121 | items = []; 122 | } else { 123 | q = query; 124 | var results = fuse.search(query, { limit: 20 }); 125 | items = results 126 | .filter((x) => x.score <= 0.75) 127 | .map((x) => x.item); 128 | if (items.length === 0) { 129 | items = [{dir:"Sorry 😿",previous_headings:"",title:"No results found.",what:"No results found.",path:window.location.href}]; 130 | } 131 | } 132 | callback(items); 133 | } 134 | $("#search-input").autocomplete(options, [ 135 | { 136 | name: "content", 137 | source: searchFuse, 138 | templates: { 139 | suggestion: (s) => { 140 | if (s.title == s.what) { 141 | return `${s.dir} >
    ${s.title}
    `; 142 | } else if (s.previous_headings == "") { 143 | return `${s.dir} >
    ${s.title}
    > ${s.what}`; 144 | } else { 145 | return `${s.dir} >
    ${s.title}
    > ${s.previous_headings} > ${s.what}`; 146 | } 147 | }, 148 | }, 149 | }, 150 | ]).on('autocomplete:selected', function(event, s) { 151 | window.location.href = s.path + "?q=" + q + "#" + s.id; 152 | }); 153 | }); 154 | })(window.jQuery || window.$) 155 | 156 | document.addEventListener('keydown', function(event) { 157 | // Check if the pressed key is '/' 158 | if (event.key === '/') { 159 | event.preventDefault(); // Prevent any default action associated with the '/' key 160 | document.getElementById('search-input').focus(); // Set focus to the search input 161 | } 162 | }); 163 | -------------------------------------------------------------------------------- /docs/reference/index.html: -------------------------------------------------------------------------------- 1 | 2 | Package index • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    32 | 33 |
    34 |

    All functions

    35 | 36 | 37 | 38 | 39 |
    40 | 41 | 42 | 43 | 44 |
    45 | 46 | check_model() 47 | 48 |
    49 |
    Check fitted model
    50 |
    51 | 52 | fit_model() 53 | 54 |
    55 |
    Fit model
    56 |
    57 | 58 | get_posterior() 59 | 60 |
    61 |
    Get posterior values
    62 |
    63 | 64 | get_seed() 65 | 66 |
    67 |
    Get seed used to fit a model
    68 |
    69 | 70 | plot_counts_obs() 71 | 72 |
    73 |
    Plot heatmap of observed counts
    74 |
    75 | 76 | plot_counts_pred() 77 | 78 |
    79 |
    Plot heatmap of predicted counts
    80 |
    81 | 82 | plot_counts_pred_obs() 83 | 84 |
    85 |
    Plot predicted versus observed counts
    86 |
    87 | 88 | plot_interaction_prob() 89 | 90 |
    91 |
    Plot heatmap of interaction probabilities
    92 |
    93 | 94 | plot_prior() 95 | 96 |
    97 |
    Plot prior distribution for r (preference) parameter
    98 |
    99 | 100 | plot_residuals() 101 | 102 |
    103 |
    Plot heatmap of residuals
    104 |
    105 | 106 | predict_counts() 107 | 108 |
    109 |
    Predict interaction counts
    110 |
    111 | 112 | prepare_data() 113 | 114 |
    115 |
    Prepare the data for modelling
    116 |
    117 | 118 | web 119 | 120 |
    121 |
    Plant-pollinator network
    122 |
    123 |
    124 | 125 | 126 |
    129 | 130 | 133 | 134 |
    135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /docs/reference/get_seed.html: -------------------------------------------------------------------------------- 1 | 2 | Get seed used to fit a model — get_seed • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    34 | 35 |
    36 |

    Get seed used to fit a model

    37 |
    38 | 39 |
    40 |

    Usage

    41 |
    get_seed(fit = NULL)
    42 |
    43 | 44 |
    45 |

    Arguments

    46 | 47 | 48 |
    fit
    49 |

    A fitted model

    50 | 51 |
    52 |
    53 |

    Value

    54 |

    A number

    55 |
    56 | 57 |
    58 |

    Examples

    59 |
    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 | 
    66 |
    67 |
    69 | 70 | 71 |
    74 | 75 | 78 | 79 |
    80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /docs/reference/plot_counts_obs.html: -------------------------------------------------------------------------------- 1 | 2 | Plot heatmap of observed counts — plot_counts_obs • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    34 | 35 |
    36 |

    Plot heatmap of observed counts

    37 |
    38 | 39 |
    40 |

    Usage

    41 |
    plot_counts_obs(mat = NULL, ...)
    42 |
    43 | 44 |
    45 |

    Arguments

    46 | 47 | 48 |
    mat
    49 |

    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.

    52 | 53 | 54 |
    ...
    55 |

    Further arguments for network.tools::plot_web_heatmap().

    56 | 57 |
    58 |
    59 |

    Value

    60 |

    A ggplot object

    61 |
    62 | 63 |
    64 |

    Examples

    65 |
    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 | 
    73 |
    74 |
    76 | 77 | 78 |
    81 | 82 | 85 | 86 |
    87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /docs/reference/check_model.html: -------------------------------------------------------------------------------- 1 | 2 | Check fitted model — check_model • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    34 | 35 |
    36 |

    Check fitted model

    37 |
    38 | 39 |
    40 |

    Usage

    41 |
    check_model(fit = NULL, data = NULL)
    42 |
    43 | 44 |
    45 |

    Arguments

    46 | 47 | 48 |
    fit
    49 |

    A fitted model, as obtained from fit_model().

    50 | 51 | 52 |
    data
    53 |

    Data list (from prepare_data()).

    54 | 55 |
    56 |
    57 |

    Value

    58 |

    Model checks on console and graphical window.

    59 |
    60 | 61 |
    62 |

    Examples

    63 |
    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 | 
    70 |
    71 |
    73 | 74 | 75 |
    78 | 79 | 82 | 83 |
    84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /docs/reference/predict_counts.html: -------------------------------------------------------------------------------- 1 | 2 | Predict interaction counts — predict_counts • BayesianWebs 5 | Skip to contents 6 | 7 | 8 |
    29 |
    30 |
    36 | 37 |
    38 |

    Generate the posterior predictive distribution of counts for every pairwise 39 | interaction.

    40 |
    41 | 42 |
    43 |

    Usage

    44 |
    predict_counts(fit = NULL, data = NULL)
    45 |
    46 | 47 |
    48 |

    Arguments

    49 | 50 | 51 |
    fit
    52 |

    Fitted model

    53 | 54 | 55 |
    data
    56 |

    Data list

    57 | 58 |
    59 |
    60 |

    Value

    61 |

    A data frame

    62 |
    63 | 64 |
    65 |

    Examples

    66 |
    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 | 
    73 |
    74 |
    76 | 77 | 78 |
    81 | 82 | 85 | 86 |
    87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /docs/reference/plot_interaction_prob.html: -------------------------------------------------------------------------------- 1 | 2 | Plot heatmap of interaction probabilities — plot_interaction_prob • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    34 | 35 |
    36 |

    Plot a heatmap of average interaction probabilities

    37 |
    38 | 39 |
    40 |

    Usage

    41 |
    plot_interaction_prob(post = NULL)
    42 |
    43 | 44 |
    45 |

    Arguments

    46 | 47 | 48 |
    post
    49 |

    Data frame containing the posterior probabilities, as generated 50 | from get_posterior().

    51 | 52 |
    53 |
    54 |

    Value

    55 |

    A ggplot object

    56 |
    57 | 58 |
    59 |

    Examples

    60 |
    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 | 
    68 |
    69 |
    71 | 72 | 73 |
    76 | 77 | 80 | 81 |
    82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /docs/reference/plot_counts_pred.html: -------------------------------------------------------------------------------- 1 | 2 | Plot heatmap of predicted counts — plot_counts_pred • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    34 | 35 |
    36 |

    Plot heatmap of predicted counts

    37 |
    38 | 39 |
    40 |

    Usage

    41 |
    plot_counts_pred(pred.df = NULL, ...)
    42 |
    43 | 44 |
    45 |

    Arguments

    46 | 47 | 48 |
    pred.df
    49 |

    A data frame containing the predicted counts, as generated by 50 | predict_counts()

    51 | 52 | 53 |
    ...
    54 |

    Further arguments for network.tools::plot_web_heatmap().

    55 | 56 |
    57 |
    58 |

    Value

    59 |

    A ggplot object

    60 |
    61 | 62 |
    63 |

    Examples

    64 |
    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 | 
    73 |
    74 |
    76 | 77 | 78 |
    81 | 82 | 85 | 86 |
    87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /docs/reference/plot_residuals.html: -------------------------------------------------------------------------------- 1 | 2 | Plot heatmap of residuals — plot_residuals • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    34 | 35 |
    36 |

    Plot heatmap of residuals (observed - predicted counts).

    37 |
    38 | 39 |
    40 |

    Usage

    41 |
    plot_residuals(pred.df = NULL, data = NULL, ...)
    42 |
    43 | 44 |
    45 |

    Arguments

    46 | 47 | 48 |
    pred.df
    49 |

    A data frame containing the predicted counts, as generated by 50 | predict_counts()

    51 | 52 | 53 |
    data
    54 |

    Data list (from prepare_data())

    55 | 56 | 57 |
    ...
    58 |

    Further arguments for network.tools::plot_web_heatmap().

    59 | 60 |
    61 |
    62 |

    Value

    63 |

    A ggplot object

    64 |
    65 | 66 |
    67 |

    Examples

    68 |
    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 | 
    77 |
    78 |
    80 | 81 | 82 |
    85 | 86 | 89 | 90 |
    91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /docs/reference/fit_model.html: -------------------------------------------------------------------------------- 1 | 2 | Fit model — fit_model • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    34 | 35 |
    36 |

    Fit model

    37 |
    38 | 39 |
    40 |

    Usage

    41 |
    fit_model(
     42 |   data = NULL,
     43 |   model = c("sampling_effort", "Young2021", "varying_preferences"),
     44 |   beta = 0.01,
     45 |   ...
     46 | )
    47 |
    48 | 49 |
    50 |

    Arguments

    51 | 52 | 53 |
    data
    54 |

    A named list containing the required data, as obtained from 55 | prepare_data().

    56 | 57 | 58 |
    model
    59 |

    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.

    62 | 63 | 64 |
    beta
    65 |

    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()).

    68 | 69 | 70 |
    ...
    71 |

    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).

    74 | 75 |
    76 |
    77 |

    Value

    78 |

    A fitted model (cmdstanr::CmdStanMCMC() object).

    79 |
    80 | 81 |
    82 |

    Examples

    83 |
    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 | 
    89 |
    90 |
    92 | 93 | 94 |
    97 | 98 | 101 | 102 |
    103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # BayesianWebs 5 | 6 | 7 | 8 | ![](https://img.shields.io/github/r-package/v/Pakillo/BayesianWebs) 9 | [![R-CMD-check](https://github.com/Pakillo/BayesianWebs/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/Pakillo/BayesianWebs/actions/workflows/R-CMD-check.yaml) 10 | [![](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable) 11 | [![Project Status: Active - The project has reached a stable, usable 12 | state and is being actively 13 | developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) 14 | [![HitCount](https://hits.dwyl.com/Pakillo/BayesianWebs.svg?style=flat-square)](https://hits.dwyl.com/Pakillo/BayesianWebs) 15 | [![HitCount](https://hits.dwyl.com/Pakillo/BayesianWebs.svg?style=flat-square&show=unique)](https://hits.dwyl.com/Pakillo/BayesianWebs) 16 | 17 | 18 | The BayesianWebs R package facilitates modelling bipartite networks 19 | (like pollination, frugivory, or herbivory networks) using the Bayesian 20 | framework developed by [Young et 21 | al. (2021)](https://doi.org/10.1038/s41467-021-24149-x). 22 | 23 | Inferring the structure of bipartite networks from field (observational) 24 | data is a challenging task. Interaction data are hard to collect and 25 | require typically large sampling efforts, particularly to characterize 26 | infrequent interactions. Inferred network structure is highly sensitive 27 | to sampling design, effort, and completeness. Comparing networks from 28 | different studies without accounting for these sampling effects may lead 29 | to mistaken inferences. 30 | 31 | This package uses Bayesian modelling to infer the posterior probability 32 | of each pairwise interaction in bipartite networks, accounting for 33 | sampling completeness and the inherent stochasticity of field 34 | observation data. 35 | 36 | ## Installation 37 | 38 | You can install the development version of BayesianWebs from 39 | [GitHub](https://github.com/) with: 40 | 41 | ``` r 42 | # install.packages("remotes") 43 | remotes::install_github("Pakillo/BayesianWebs") 44 | ``` 45 | 46 | The package requires a working installation of 47 | [Stan](https://mc-stan.org/). If you don’t have `CmdStan` installed, 48 | after installing `BayesianWebs` run: 49 | 50 | ``` r 51 | cmdstanr::install_cmdstan() 52 | ``` 53 | 54 | ## Example 55 | 56 | ``` r 57 | library(BayesianWebs) 58 | ``` 59 | 60 | Let’s infer the structure of an example dataset from [Kaiser-Bunbury et 61 | al. 2017](https://doi.org/10.1038/nature21071) as in Young et al. 2021: 62 | 63 | ``` r 64 | data(web) 65 | ``` 66 | 67 | This is an adjacency matrix collecting the number of visits of 21 68 | animals on 8 plants: 69 | 70 | ``` r 71 | web 72 | #> A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 A14 A15 A16 A17 A18 A19 A20 A21 73 | #> P1 0 0 3 1 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 74 | #> P2 0 0 12 0 0 0 0 0 0 0 0 0 0 8 0 1 0 0 0 0 1 75 | #> P3 0 0 0 0 1 0 7 0 0 0 0 0 0 2 0 0 5 3 0 0 0 76 | #> P4 0 0 2 0 3 0 0 1 0 0 0 0 0 30 0 0 0 0 0 0 0 77 | #> P5 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 78 | #> P6 0 0 0 4 1 0 1 0 0 0 1 5 2 0 0 0 0 0 0 0 0 79 | #> P7 3 0 33 0 0 2 6 0 2 0 0 0 0 27 0 0 0 0 0 0 2 80 | #> P8 0 1 1 1 2 0 11 0 0 6 0 0 0 1 2 0 0 0 0 1 0 81 | ``` 82 | 83 | ``` r 84 | plot_counts_obs(web, sort = FALSE) 85 | ``` 86 | 87 | 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 | #> 153 | #> 1 P1 A1 1 1 1 0.299 33.0 0.0185 154 | #> 2 P1 A2 1 1 1 0.299 33.0 0.0185 155 | #> 3 P1 A3 1 1 1 0.299 33.0 0.0185 156 | #> 4 P1 A4 1 1 1 0.299 33.0 0.0185 157 | #> 5 P1 A5 1 1 1 0.299 33.0 0.0185 158 | #> 6 P1 A6 1 1 1 0.299 33.0 0.0185 159 | #> # ℹ 3 more variables: animal.abund , int.prob , link 160 | ``` 161 | 162 | ``` r 163 | plot_interaction_prob(post) 164 | ``` 165 | 166 | 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 | . 206 | 207 | Rodriguez-Sanchez F (2024). _BayesianWebs: Bayesian Modelling of 208 | Bipartite Networks_. . 209 | 210 | To see these entries in BibTeX format, use 'print(, 211 | bibtex=TRUE)', 'toBibtex(.)', or set 212 | 'options(citation.bibtex.max=999)'. 213 | ``` 214 | -------------------------------------------------------------------------------- /docs/reference/prepare_data.html: -------------------------------------------------------------------------------- 1 | 2 | Prepare the data for modelling — prepare_data • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    34 | 35 |
    36 |

    Prepare the data for modelling

    37 |
    38 | 39 |
    40 |

    Usage

    41 |
    prepare_data(mat = NULL, sampl.eff = NULL)
    42 |
    43 | 44 |
    45 |

    Arguments

    46 | 47 | 48 |
    mat
    49 |

    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.

    52 | 53 | 54 |
    sampl.eff
    55 |

    A numeric vector with the sampling effort (e.g. observation hours) 56 | spent on each plant.

    57 | 58 |
    59 |
    60 |

    Value

    61 |

    A named list with all the data required to run the model.

    62 |
    63 | 64 |
    65 |

    Examples

    66 |
    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 | 
    89 |
    90 |
    92 | 93 | 94 |
    97 | 98 | 101 | 102 |
    103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /docs/deps/clipboard.js-2.0.11/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v2.0.11 3 | * https://clipboardjs.com/ 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1 2 | Plot prior distribution for r (preference) parameter — plot_prior • BayesianWebs 11 | Skip to contents 12 | 13 | 14 |
    35 |
    36 |
    42 | 43 |
    44 |

    The 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.

    49 |
    50 | 51 |
    52 |

    Usage

    53 |
    plot_prior(beta = NULL, fit = NULL, data = NULL)
    54 |
    55 | 56 |
    57 |

    Arguments

    58 | 59 | 60 |
    beta
    61 |

    A number > 0. Rate of the exponential distribution.

    62 | 63 | 64 |
    fit
    65 |

    A fitted model, as obtained from fit_model().

    66 | 67 | 68 |
    data
    69 |

    Data list (from prepare_data()).

    70 | 71 |
    72 |
    73 |

    Value

    74 |

    A plot

    75 |
    76 | 77 |
    78 |

    Examples

    79 |
    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 | 
    91 |
    92 |
    94 | 95 | 96 |
    99 | 100 | 103 | 104 |
    105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /docs/reference/get_posterior.html: -------------------------------------------------------------------------------- 1 | 2 | Get posterior values — get_posterior • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    34 | 35 |
    36 |

    Get posterior values

    37 |
    38 | 39 |
    40 |

    Usage

    41 |
    get_posterior(
     42 |   fit = NULL,
     43 |   data = NULL,
     44 |   param = c("all", "connectance", "preference", "plant.abund", "animal.abund",
     45 |     "int.prob", "link")
     46 | )
    47 |
    48 | 49 |
    50 |

    Arguments

    51 | 52 | 53 |
    fit
    54 |

    Fitted model (from fit_model())

    55 | 56 | 57 |
    data
    58 |

    Data list (from prepare_data())

    59 | 60 | 61 |
    param
    62 |

    character. Name of the parameter to retrieve the posterior samples.

    63 | 64 |
    65 |
    66 |

    Value

    67 |

    A data frame

    68 |
    69 | 70 |
    71 |

    Examples

    72 |
    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 | 
    86 |
    87 |
    89 | 90 | 91 |
    94 | 95 | 98 | 99 |
    100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /docs/reference/plot_counts_pred_obs.html: -------------------------------------------------------------------------------- 1 | 2 | Plot predicted versus observed counts — plot_counts_pred_obs • BayesianWebs 3 | Skip to contents 4 | 5 | 6 |
    27 |
    28 |
    34 | 35 |
    36 |

    Plot predicted versus observed counts

    37 |
    38 | 39 |
    40 |

    Usage

    41 |
    plot_counts_pred_obs(
     42 |   pred.df = NULL,
     43 |   data = NULL,
     44 |   byplant = FALSE,
     45 |   width = 0.95,
     46 |   ...
     47 | )
    48 |
    49 | 50 |
    51 |

    Arguments

    52 | 53 | 54 |
    pred.df
    55 |

    A data frame containing the predicted counts, as generated by 56 | predict_counts()

    57 | 58 | 59 |
    data
    60 |

    Data list (from prepare_data())

    61 | 62 | 63 |
    byplant
    64 |

    Logical. If TRUE, show predicted and observed counts per plant 65 | (using ggplot2::facet_wrap()). If FALSE, show all interactions in the same plot.

    66 | 67 | 68 |
    width
    69 |

    width of the credible interval (default = 0.95).

    70 | 71 | 72 |
    ...
    73 |

    Further arguments to be passed to ggplot2::facet_wrap() if 74 | byplant = TRUE, or to tidybayes::geom_pointinterval() if byplant = FALSE.

    75 | 76 |
    77 |
    78 |

    Value

    79 |

    A ggplot object

    80 |
    81 | 82 |
    83 |

    Examples

    84 |
    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 | 
    95 |
    96 |
    98 | 99 | 100 |
    109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | --------------------------------------------------------------------------------