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

```

