
Compute invasion fitness \(\lambda_{is}\) for multiple model options
Source:R/compute_invasion_fitness.R
compute_invasion_fitness.Rdcompute_invasion_fitness() evaluates the invasion-fitness surface
\(\lambda_{is}\) over sites (\(s\)) and invaders (\(i\)) using the
three standardized predictors:
Abiotic suitability \(r^{(z)}_{is}\) (alignment between invader traits and local environment),
Niche crowding \(C^{(z)}_{is}\) (overlap with resident trait space weighted by composition),
Resident competition \(S^{(z)}_{is}\) (site-only saturation).
It supports five published/useful variants: A: \(\gamma=1\), B: global \(\theta_0\), C: trait-varying \(\theta_i\), D: site-varying \(\Gamma_{is}\) and \(\alpha_{is}\), E: signed \(S\) effect. Optionally, it calibrates an offset \(\kappa\) so the mean resident \(\lambda\) is approximately zero on the same scale (when resident standardized matrices are supplied).
Usage
compute_invasion_fitness(
r_is_z,
C_is_z,
S_is_z,
option = c("A", "B", "C", "D", "E"),
alpha_i = NULL,
beta_i = NULL,
theta0 = 1,
theta_i = NULL,
Gamma_is = NULL,
alpha_is = NULL,
beta_signed_i = NULL,
calibrate_kappa = FALSE,
r_js_z = NULL,
C_js_z = NULL,
S_js_z = NULL,
Q_res = NULL,
a0 = NULL,
a1 = NULL,
a2 = NULL,
b0 = NULL,
b1 = NULL,
b2 = NULL,
site_df = NULL,
return_long = TRUE,
label = NULL
)Arguments
- r_is_z
Matrix \(S \times I\) of standardized abiotic suitability for invaders. Row names are site IDs; column names are invader IDs.
- C_is_z
Matrix \(S \times I\) of standardized niche crowding for invaders.
- S_is_z
Matrix \(S \times I\) of standardized site saturation for invaders (site-only; same value down each site row).
- option
Character, one of
c("A","B","C","D","E"). See Details.- alpha_i
Optional named numeric vector (length \(I\)) of invader crowding sensitivities \(\alpha_i\). Required for A–C and E; ignored if
alpha_isis provided in D.- beta_i
Optional named numeric vector (length \(I\)) of saturation sensitivities \(\beta_i\). Used in A–D. For E, use
beta_signed_ifor a signed effect.- theta0
Numeric scalar global slope for \(r^{(z)}\) (Option B; default
1).- theta_i
Optional named numeric vector (length \(I\)) of trait-varying slopes for \(r^{(z)}\) (Option C).
- Gamma_is
Optional matrix \(S \times I\) of site-varying slopes for \(r^{(z)}\) (Option D). If NULL, falls back to
theta_iortheta0as available.- alpha_is
Optional matrix \(S \times I\) of site-varying penalties for crowding (Option D). If NULL, falls back to broadcasting
alpha_i.- beta_signed_i
Optional named numeric vector (length \(I\)) providing a signed \(\beta\) for Option E (facilitation allowed when \(\beta<0\)).
- calibrate_kappa
Logical; if
TRUE, compute \(\kappa\) from residents so that the mean resident \(\lambda\) is ~0 on the same scale (see below).- r_js_z, C_js_z, S_js_z
Optional resident standardized matrices (site \(\times\) resident), required only when
calibrate_kappa = TRUE.- Q_res
Optional data frame of resident trait-plane scores with columns
tr1,tr2and rownames = resident IDs (only needed for \(\kappa\) if you want to derive resident analogs \(\alpha_j\), \(\beta_j\) from trait slopes).- a0, a1, a2, b0, b1, b2
Optional numeric scalars: coefficients for resident analog slopes \(\text{slope}_C = a_0 + a_1\,tr1 + a_2\,tr2\) and \(\text{slope}_S = b_0 + b_1\,tr1 + b_2\,tr2\). Used only when
calibrate_kappa=TRUEandQ_resprovided.- site_df
Optional site table with columns
site,x,yused to enrich the tidy output whenreturn_long=TRUE.- return_long
Logical; if
TRUE, returns a tidy table with predictors and coefficients.- label
Optional character to tag the option in the tidy output; defaults to a descriptive name per option (e.g.,
"Option A (γ=1)").
Value
A list with:
lambda_is— matrix \(S \times I\) of invasion fitness,GI— the \(\gamma\) used (vector length \(I\) or matrix \(S \times I\)),AI— the \(\alpha\) used (vector length \(I\) or matrix \(S \times I\)),BI— the \(\beta\) used (vector length \(I\)),kappa— numeric calibration offset,option— option label,lambda_long— tidy tibble (ifreturn_long=TRUE).
Details
Compute invasion fitness (five options) with optional resident calibration
Options A: \(\lambda_{is} = 1\cdot r^{(z)}_{is} - \alpha_i C^{(z)}_{is} - \beta_i S^{(z)}_{is} + \kappa\) B: \(\lambda_{is} = \theta_0 r^{(z)}_{is} - \alpha_i C^{(z)}_{is} - \beta_i S^{(z)}_{is} + \kappa\) C: \(\lambda_{is} = \theta_i r^{(z)}_{is} - \alpha_i C^{(z)}_{is} - \beta_i S^{(z)}_{is} + \kappa\) D: \(\lambda_{is} = \Gamma_{is} r^{(z)}_{is} - \alpha_{is} C^{(z)}_{is} - \beta_i S^{(z)}_{is} + \kappa\) E: \(\lambda_{is} = \theta_0 r^{(z)}_{is} - \alpha_i C^{(z)}_{is} + \beta^{(\mathrm{signed})}_i S^{(z)}_{is} + \kappa\)
Resident calibration (\(\kappa\)). When calibrate_kappa=TRUE, the function
computes resident analog penalties \(\alpha_j,\beta_j\) from Q_res and slopes
{a0,a1,a2,b0,b1,b2}, builds resident matrices AJ, BJ, evaluates
\(\lambda^{(\mathrm{res})}_{js} = \theta_0 r^{(z)}_{js} - \alpha_j C^{(z)}_{js} - \beta_j S^{(z)}_{js}\),
then sets \(\kappa = -\mathrm{mean}(\lambda^{(\mathrm{res})}_{js})\) (na-rm),
keeping residents and invaders on the same scale.
Examples
# Minimal reproducible example (toy shapes only)
S = 5; I = 3
set.seed(1)
r_is_z = matrix(rnorm(S*I), S, I, dimnames=list(paste0("s",1:S), paste0("i",1:I)))
C_is_z = matrix(rnorm(S*I), S, I, dimnames=dimnames(r_is_z))
S_is_z = matrix(rep(scale(rnorm(S)), each=I), S, I, dimnames=dimnames(r_is_z)) # site-only broadcast
alpha_i = setNames(runif(ncol(r_is_z), 0.2, 1.0), colnames(r_is_z))
beta_i = setNames(runif(ncol(r_is_z), 0.1, 0.5), colnames(r_is_z))
# Option A (γ=1, κ=0)
outA = compute_invasion_fitness(r_is_z, C_is_z, S_is_z,
option="A", alpha_i=alpha_i, beta_i=beta_i,
theta0=1, return_long=FALSE)
# Option B (γ = θ0)
outB = compute_invasion_fitness(r_is_z, C_is_z, S_is_z,
option="B", alpha_i=alpha_i, beta_i=beta_i,
theta0=0.8, return_long=FALSE)
# Option C (γ_i = θ_i) — use I = ncol(r_is_z) to avoid length/name mismatch
I = ncol(r_is_z)
theta_i = setNames(runif(I, 0.5, 1.2), colnames(r_is_z))
outC = compute_invasion_fitness(r_is_z, C_is_z, S_is_z,
option="C", alpha_i=alpha_i, beta_i=beta_i,
theta_i=theta_i, return_long=FALSE)
# Option D (site-varying Γ_is and α_is)
Gamma_is = matrix(rep(theta_i, each=nrow(r_is_z)), nrow=nrow(r_is_z), dimnames=dimnames(r_is_z))
alpha_is = pmax(0, matrix(rep(alpha_i, each=nrow(r_is_z)), nrow=nrow(r_is_z),
dimnames=dimnames(r_is_z)) + matrix(rnorm(prod(dim(r_is_z)), 0, 0.1),
nrow=nrow(r_is_z)))
outD = compute_invasion_fitness(r_is_z, C_is_z, S_is_z,
option="D", alpha_is=alpha_is, beta_i=beta_i,
Gamma_is=Gamma_is, return_long=FALSE)
#> Error in compute_invasion_fitness(r_is_z, C_is_z, S_is_z, option = "D", alpha_is = alpha_is, beta_i = beta_i, Gamma_is = Gamma_is, return_long = FALSE): identical(dim(alpha_is), dim(r_is_z)) is not TRUE
# Option E (signed S effect)
beta_signed_i = setNames(rnorm(ncol(r_is_z), 0, 0.3), colnames(r_is_z))
outE = compute_invasion_fitness(r_is_z, C_is_z, S_is_z,
option="E", alpha_i=alpha_i, beta_signed_i=beta_signed_i,
theta0=1, return_long=FALSE)