|
1 | | -#' Calculate keystoneness for a Northeast U.S. Rpath model |
| 1 | +#' Calculate keystoneness indices |
2 | 2 | #' |
3 | | -#' Calculates the keystoneness index (KSi) for a given ecosystem model |
4 | | -#' following Libralato et al. 2006: |
5 | | -#' KSi = log[epsilon_i * (1 - p_i)], |
6 | | -#' where epsilon_i is the total impact of group i (from the MTI matrix excluding self-effects) |
7 | | -#' and p_i is the proportion of total system biomass. |
| 3 | +#' Computes Keystone index #1, #2, #3 and Relative Total Impact (raw and normalized) |
| 4 | +#' for a Northeast U.S. Rpath model, excluding detritus and fleet groups. |
8 | 5 | #' |
9 | 6 | #' @param epu Character. Ecosystem production unit: "GB", "GOM", or "MAB". |
10 | 7 | #' @return A data.frame with ecological groups, biomass, proportion biomass, |
11 | | -#' total impact, and keystoneness index. |
| 8 | +#' raw and normalized Relative Total Impact, and keystone indices. |
12 | 9 | #' @examples |
13 | | -#' keystoneness("GB") |
| 10 | +#' keystoneness_all("GB") |
14 | 11 | #' @export |
15 | | -keystoneness <- function(epu = c("GB", "GOM", "MAB")) { |
| 12 | +keystoneness_all <- function(epu = c("GB", "GOM", "MAB")) { |
16 | 13 |
|
17 | 14 | epu <- match.arg(epu) |
18 | 15 |
|
19 | 16 | # --- STEP 1: load model and balanced parameters --- |
20 | | - data(list = paste0(epu)) # loads GB, GOM, or MAB model into environment |
| 17 | + data(list = epu) |
21 | 18 | model <- get(epu) |
22 | 19 |
|
23 | | - # load balanced parameters |
24 | 20 | params_name <- paste0(epu, "_balanced_params") |
25 | 21 | data(list = params_name) |
26 | 22 | params <- get(params_name) |
27 | 23 |
|
28 | | - # --- STEP 2: Mixed trophic impact matrix --- |
29 | | - mti_mat <- Rpath::MTI(Rpath = model, Rpath.params = params) |
| 24 | + # --- STEP 2: compute MTI matrix using local MTI function --- |
| 25 | + mti_mat <- MTI(Rpath = model, Rpath.params = params) |
30 | 26 |
|
31 | | - # --- STEP 3: assign group names (ecological groups only) --- |
| 27 | + # --- STEP 3: filter for living ecological groups only --- |
| 28 | + eco_rows <- which(params$model$Type < 2) # living groups only |
| 29 | + mti_mat <- mti_mat[eco_rows, eco_rows, drop = FALSE] |
| 30 | + |
| 31 | + biomass <- model$Biomass[eco_rows] |
| 32 | + prop_biomass <- biomass / sum(biomass, na.rm = TRUE) |
| 33 | + |
| 34 | + # Group names |
| 35 | + group_names <- model$Group[eco_rows] |
32 | 36 | if (!is.null(rownames(model$DC))) { |
33 | | - group_names <- rownames(model$DC) |
34 | | - } else if (!is.null(model$Group)) { |
35 | | - group_names <- model$Group |
36 | | - } else { |
37 | | - group_names <- paste0("Group", seq_len(nrow(mti_mat))) |
| 37 | + group_names <- rownames(model$DC)[eco_rows] |
38 | 38 | } |
39 | 39 |
|
40 | | - # exclude fishing gear groups |
41 | | - n_eco <- nrow(mti_mat) - model$NUM_GEARS |
42 | | - mti_mat <- mti_mat[1:n_eco, 1:n_eco] |
43 | | - group_names <- group_names[1:n_eco] |
| 40 | + # --- STEP 4: Relative Total Impact (RTI) --- |
| 41 | + total_effect <- rowSums(abs(mti_mat), na.rm = TRUE) |
| 42 | + self_effect <- diag(abs(mti_mat)) |
| 43 | + rti_raw <- total_effect - self_effect |
| 44 | + rti_norm <- rti_raw / max(rti_raw, na.rm = TRUE) |
44 | 45 |
|
45 | | - # --- STEP 4: compute proportional biomass --- |
46 | | - biomass <- model$Biomass[1:n_eco] |
47 | | - prop_biomass <- biomass / sum(biomass) |
| 46 | + # --- STEP 5: Keystone index #1 (Libralato 2006) --- |
| 47 | + KS1 <- log(rti_raw * (1 - prop_biomass)) |
48 | 48 |
|
49 | | - # --- STEP 5: compute total impacts excluding self-effects --- |
50 | | - total_effect <- apply(abs(mti_mat), 1, sum) |
51 | | - self_effect <- diag(abs(mti_mat)) |
52 | | - epsilon <- total_effect - self_effect |
| 49 | + # --- STEP 6: Keystone index #2 (Valls 2015) --- |
| 50 | + predator_impacts <- rowSums(abs(mti_mat * (mti_mat < 0)), na.rm = TRUE) |
| 51 | + prey_impacts <- rowSums(abs(mti_mat * (mti_mat > 0)), na.rm = TRUE) |
| 52 | + KS2 <- (predator_impacts + prey_impacts) / biomass |
53 | 53 |
|
54 | | - # --- STEP 6: keystoneness (Libralato et al. 2006) --- |
55 | | - KS_index <- log(epsilon * (1 - prop_biomass)) |
| 54 | + # --- STEP 7: Keystone index #3 (Valls 2015) --- |
| 55 | + KS3 <- predator_impacts / biomass |
56 | 56 |
|
57 | | - # --- STEP 7: tidy output --- |
| 57 | + # --- STEP 8: tidy output --- |
58 | 58 | results <- data.frame( |
59 | 59 | group = group_names, |
60 | 60 | biomass = biomass, |
61 | 61 | prop_biomass = prop_biomass, |
62 | | - impact = epsilon, |
63 | | - keystoneness = KS_index, |
| 62 | + RTI_raw = rti_raw, |
| 63 | + RTI_normalized = rti_norm, |
| 64 | + `Keystone index #1` = KS1, |
| 65 | + `Keystone index #2` = KS2, |
| 66 | + `Keystone index #3` = KS3, |
64 | 67 | stringsAsFactors = FALSE |
65 | 68 | ) |
66 | 69 |
|
67 | | - # Attach EPU label as an attribute |
| 70 | + # Attach EPU label as attribute |
68 | 71 | attr(results, "epu") <- switch(epu, |
69 | 72 | GB = "Georges Bank", |
70 | 73 | GOM = "Gulf of Maine", |
|
0 commit comments