# Generating Realised Food Webs

# 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

    library(pfwim)
    library(dplyr)
    library(igraph)

    data("traits", package = "pfwim")
    data("feeding_rules", package = "pfwim")

# Generate the Metaweb

    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.

    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.

    length(realised_webs)

    ## [1] 5

Each entry in the list can be accessed individually.

    realised_webs[[1]]

    ##      resource   consumer
    ## 9    plankton        cod
    ## 11    plant_1       deer
    ## 18        rat       lynx
    ## 21       seal       orca
    ## 16 polar_bear       orca
    ## 19        rat polar_bear
    ## 12    plant_1        rat
    ## 13    plant_1       seal
    ## 10   plankton       seal

    realised_webs[[2]]

    ##      resource   consumer
    ## 9    plankton        cod
    ## 14    plant_2       deer
    ## 11    plant_1       deer
    ## 5        lynx       lynx
    ## 1         cod       orca
    ## 8        orca polar_bear
    ## 2         cod polar_bear
    ## 19        rat polar_bear
    ## 4        deer polar_bear
    ## 22       seal polar_bear
    ## 6        lynx polar_bear
    ## 17 polar_bear polar_bear
    ## 12    plant_1        rat
    ## 10   plankton       seal

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

    library(dplyr)

    combined_edges <- dplyr::bind_rows(
      lapply(realised_webs, as.data.frame),
      .id = "web_id"
    )

    head(combined_edges)

    ##   web_id   resource   consumer
    ## 1  web_1   plankton        cod
    ## 2  web_1    plant_1       deer
    ## 3  web_1        rat       lynx
    ## 4  web_1       seal       orca
    ## 5  web_1 polar_bear       orca
    ## 6  web_1        rat polar_bear

Next, count how often each interaction appears across the simulations. The column `freq` indicates the number of realised webs in which each interaction occurs.

    edge_frequency <- combined_edges %>%
      count(resource, consumer, name = "freq")

    edge_frequency

    ##      resource   consumer freq
    ## 1         cod       orca    4
    ## 2         cod polar_bear    3
    ## 3        deer       lynx    3
    ## 4        deer polar_bear    3
    ## 5        lynx       lynx    2
    ## 6        lynx polar_bear    3
    ## 7        orca       orca    1
    ## 8        orca polar_bear    4
    ## 9    plankton        cod    5
    ## 10   plankton       seal    3
    ## 11    plant_1       deer    4
    ## 12    plant_1        rat    5
    ## 13    plant_1       seal    4
    ## 14    plant_2       deer    3
    ## 15    plant_2       seal    1
    ## 16 polar_bear       orca    2
    ## 17 polar_bear polar_bear    3
    ## 18        rat       lynx    2
    ## 19        rat polar_bear    4
    ## 20       seal       lynx    2
    ## 21       seal       orca    2
    ## 22       seal polar_bear    3

A simple consensus rule is to keep interactions that appear in at least half of the simulations. This produces a consensus realised web.

    consensus_el <- edge_frequency %>%
      filter(freq >= 3)

# Visualising the Consensus Web

    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.

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