--- title: "Generating Realised Food Webs" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Generating Realised Food Webs} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- # Introduction The metaweb contains all trait-compatible interactions, but real ecological networks typically contain far fewer links. To simulate realistic food webs, PFWIM provides the function `powerlaw_prey()`, which downsamples interactions from the metaweb according to a power-law prey degree distribution. This vignette demonstrates how to: * Generate a metaweb edgelist * Downsample interactions to create realised webs * Compare the metaweb and realised networks using igraph ```{r, message=FALSE, warning=FALSE} library(pfwim) library(dplyr) library(igraph) data("traits", package = "pfwim") data("feeding_rules", package = "pfwim") ``` # Generate the Metaweb ```{r, message=FALSE, warning=FALSE} metaweb_el <- infer_edgelist( data = traits, cat_combo_list = feeding_rules, col_taxon = "species", certainty_req = "all", hide_printout = TRUE ) ``` # Generating Multiple Realised Webs The function `powerlaw_prey()` randomly samples prey for each consumer according to a power-law distribution, producing networks that more closely resemble empirical food webs. Because realised webs are generated via stochastic downsampling, it is often useful to generate multiple network realisations. This allows users to explore variability in network structure and perform simulation-based analyses. The argument `n_samp` controls how many realised webs are generated. ```{r, message=FALSE, warning=FALSE} realised_webs <- powerlaw_prey( el = metaweb_el, n_samp = 5, y = 2.5 ) ``` The result is a list of edgelists, where each element represents one simulated realised food web. ```{r, message=FALSE, warning=FALSE} length(realised_webs) ``` Each entry in the list can be accessed individually. ```{r} realised_webs[[1]] realised_webs[[2]] ``` # Creating a consensus Realised Web When generating multiple realised food webs, it can be useful to construct a single representative network that summarises the interactions observed across all simulations. This can be done by counting how frequently each interaction occurs across the simulated webs. First, combine all realised edgelists into one table. Here the `.id` column identifies which realised web each interaction came from. ```{r} library(dplyr) combined_edges <- dplyr::bind_rows( lapply(realised_webs, as.data.frame), .id = "web_id" ) head(combined_edges) ``` Next, count how often each interaction appears across the simulations. The column `freq` indicates the number of realised webs in which each interaction occurs. ```{r} edge_frequency <- combined_edges %>% count(resource, consumer, name = "freq") edge_frequency ``` A simple consensus rule is to keep interactions that appear in at least half of the simulations. This produces a consensus realised web. ```{r} consensus_el <- edge_frequency %>% filter(freq >= 3) ``` # Visualising the Consensus Web ```{r} library(igraph) consensus_graph <- graph_from_data_frame( consensus_el, directed = TRUE ) plot( consensus_graph, vertex.size = 35, vertex.label.cex = 0.7, edge.arrow.size = 0.3, main = "Consensus Realised Web" ) ``` # Weighted Consensus Web Instead of filtering interactions, one can construct a weighted network where edge weights represent interaction frequency. In this case, the `freq` column becomes the edge weight, representing how consistently each interaction occurs across simulations. ```{r} weighted_graph <- graph_from_data_frame( edge_frequency, directed = TRUE ) plot( weighted_graph, vertex.size = 35, vertex.label.cex = 0.7, edge.width = E(weighted_graph)$freq, edge.arrow.size = 0.3, main = "Weighted Realised Web" ) ```