Skip to content

Commit

Permalink
✨ bodymass-ratio
Browse files Browse the repository at this point in the history
  • Loading branch information
TanyaS08 committed Jun 24, 2024
1 parent b31ca4d commit c91c559
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 3 deletions.
39 changes: 39 additions & 0 deletions 02_bodymass_ratio.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,47 @@ This concept of using body mass ratios to determine potential feeding links betw

## Methods

Core idea relates to the ratio between consumer and resource body sizes - which supposedly stems from niche theory (still trying to reconcile that myself). The probability of a link existing between a consumer and resource (in its most basic form) is defined as follows:

$$
P_{ij} = \frac{p}{1+p}
$$

where

$$
p = exp[\alpha + \beta log(\frac{M_{i}}{M_{j}}) + \gamma log^{2}(\frac{M_{i}}{M_{j}})]
$${#eq-bodymass}
The original latent-trait model developed by @rohr2010 also included an additional latent trait term $v_{i} \delta f_{j}$ however for simplicity we will use @eq-bodymass as per @yeakel2014. Based on @rohr2010 it is possible to estimate the parameters $\alpha$, $\delta$, and $\gamma$ using a GLM but we will use the parameters from @yeakel2014, which was 'trained' on the Serengeti food web data and are as follows: $\alpha = 1.41$, $\delta = 3.75$, and $\gamma = 1.87$.
## Example
```{julia}
using CSV
using DataFrames
include("lib/bodymass/bodymass.jl")
# set seed
import Random
Random.seed!(66)
# import the mock dataset
df = DataFrame(CSV.File("data/toarcian_subset.csv"))
# were going to create some interim bodymass values
using Distributions
bodymass = rand(Truncated(Normal(0, 1), 0, 1), nrow(df))
bodymass_network = bmratio(df.species, bodymass)
# this is a probabilistic network by default we can make it binary using the random draws function
randomdraws(bodymass_network)
```
## References {.unnumbered}
::: {#refs}
Expand Down
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a"
SpeciesInteractionNetworks = "49e116ef-912f-4766-9e56-896a49944adc"
12 changes: 12 additions & 0 deletions _freeze/02_bodymass_ratio/execute-results/html.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"hash": "225aa7d0971f1d13a486b74649325c8e",
"result": {
"engine": "jupyter",
"markdown": "---\ntitle: \"Bodymass-ratio\"\ndate: last-modified\nformat:\n html:\n embed-resources: true\ntitle-block-banner: true\nbibliography: references.bib\n---\n\n## Overview\n\nThis concept of using body mass ratios to determine potential feeding links between species was primarily developed by @rohr2010 and has become quite popular in paleo settings [@yeakel2014; @pires2015]\n\n## Methods\n\nCore idea relates to the ratio between consumer and resource body sizes - which supposedly stems from niche theory (still trying to reconcile that myself). The probability of a link existing between a consumer and resource (in its most basic form) is defined as follows:\n\n$$\nP_{ij} = \\frac{p}{1+p}\n$$\n\nwhere\n\n$$\np = exp[\\alpha + \\beta log(\\frac{M_{i}}{M_{j}}) + \\gamma log^{2}(\\frac{M_{i}}{M_{j}})]\n$${#eq-bodymass}\n\nThe original latent-trait model developed by @rohr2010 also included an additional latent trait term $v_{i} \\delta f_{j}$ however for simplicity we will use @eq-bodymass as per @yeakel2014. Based on @rohr2010 it is possible to estimate the parameters $\\alpha$, $\\delta$, and $\\gamma$ using a GLM but we will use the parameters from @yeakel2014, which was 'trained' on the Serengeti food web data and are as follows: $\\alpha = 1.41$, $\\delta = 3.75$, and $\\gamma = 1.87$.\n\n## Example\n\n::: {#782a14ec .cell execution_count=1}\n``` {.julia .cell-code}\nusing CSV\nusing DataFrames\n\ninclude(\"lib/bodymass/bodymass.jl\")\n\n# set seed\nimport Random\nRandom.seed!(66)\n\n# import the mock dataset\ndf = DataFrame(CSV.File(\"data/toarcian_subset.csv\"))\n\n# were going to create some interim bodymass values\nusing Distributions\nbodymass = rand(Truncated(Normal(0, 1), 0, 1), nrow(df))\n\nbodymass_network = bmratio(df.species, bodymass)\n\n# this is a probabilistic network by default we can make it binary using the random draws function\nrandomdraws(bodymass_network)\n```\n\n::: {.cell-output .cell-output-display execution_count=2}\n```\nA binary unipartite network\n → 8 interactions\n → 12 species\n```\n:::\n:::\n\n\n## References {.unnumbered}\n\n::: {#refs}\n:::\n\n",
"supporting": [
"02_bodymass_ratio_files/figure-html"
],
"filters": [],
"includes": {}
}
}
6 changes: 3 additions & 3 deletions _freeze/04_PFIM/execute-results/html.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"hash": "e617860d0e7f4ddf3e20a7f12a6f5e5b",
"hash": "f8c10c5682f5950389a3da38281b8291",
"result": {
"engine": "jupyter",
"markdown": "---\ntitle: \"PFIM\"\ndate: last-modified\nformat:\n html:\n embed-resources: true\ntitle-block-banner: true\nbibliography: references.bib\n---\n\n## Overview\n\n> @fricke2022 methods discuss how in the *\"using functional traits (especially binary or categorical traits), one can overestimate the ecological similarity of species, and thus the similarity of interaction patterns\"*. \n\nThe Paleo Food web Inference Model (PFIM, @shaw2024) uses a series of rules for a set of trait categories (such as habitat and body size) to determine if an interaction can feasibly occur between a species pair.\n\n## Methods\n\n## Example\n\n\n::: {#79f5c86c .cell execution_count=2}\n``` {.julia .cell-code}\n# set seed\nimport Random\nRandom.seed!(66)\n\n# import the mock dataset\ndf = DataFrame(CSV.File(\"data/toarcian_subset.csv\"))\n\n# this is a probabilistic network\npfim_network = PFIM(df)\n\n# this is a probabilistic network by default we can make it binary using the random draws function\nrandomdraws(pfim_network)\n\n```\n\n::: {.cell-output .cell-output-display execution_count=3}\n```\nA binary unipartite network\n → 9 interactions\n → 12 species\n```\n:::\n:::\n\n\n## References {.unnumbered}\n\n::: {#refs}\n:::\n\n",
"markdown": "---\ntitle: \"PFIM\"\ndate: last-modified\nformat:\n html:\n embed-resources: true\ntitle-block-banner: true\nbibliography: references.bib\n---\n\n## Overview\n\n> @fricke2022 methods discuss how in the *\"using functional traits (especially binary or categorical traits), one can overestimate the ecological similarity of species, and thus the similarity of interaction patterns\"*. \n\nThe Paleo Food web Inference Model (PFIM, @shaw2024) uses a series of rules for a set of trait categories (such as habitat and body size) to determine if an interaction can feasibly occur between a species pair.\n\n## Methods\n\n## Example\n\n::: {#e1b56af1 .cell execution_count=1}\n``` {.julia .cell-code}\nusing CSV\nusing DataFrames\n\ninclude(\"lib/pfim/pfim.jl\")\n\n# set seed\nimport Random\nRandom.seed!(66)\n\n# import the mock dataset\ndf = DataFrame(CSV.File(\"data/toarcian_subset.csv\"))\n\n# this is a probabilistic network\npfim_network = PFIM(df)\n\n# this is a probabilistic network by default we can make it binary using the random draws function\nrandomdraws(pfim_network)\n\n```\n\n::: {.cell-output .cell-output-display execution_count=2}\n```\nA binary unipartite network\n → 9 interactions\n → 12 species\n```\n:::\n:::\n\n\n## References {.unnumbered}\n\n::: {#refs}\n:::\n\n",
"supporting": [
"04_PFIM_files"
"04_PFIM_files/figure-html"
],
"filters": [],
"includes": {}
Expand Down
34 changes: 34 additions & 0 deletions lib/bodymass/bodymass.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using DataFrames
using SpeciesInteractionNetworks

function bmratio(
species::Any,
bodymass::Vector{Float64};
α::Float64 = 1.41,
β::Float64 = 3.73,
γ::Float64 = 1.87)

S = length(species)

prob_matrix = zeros(AbstractFloat, (S, S))
for i in 1:S
for j in 1:S
MR = bodymass[i]/bodymass[j]
if MR == 0
p = exp(α)
else
p = exp+ β*log(MR) + γ*log(MR)^2)
end
if p/(1-p) >= 0.0
prob_matrix[i,j] = p/(1-p)
end
end
end

# make probabanilistic
prob_matrix = prob_matrix./maximum(prob_matrix)

edges = Probabilistic(prob_matrix)
nodes = Unipartite(Symbol.(species))
return SpeciesInteractionNetwork(nodes, edges)
end

0 comments on commit c91c559

Please sign in to comment.