The Finding
GAM_size_structure_Clean.R’s selectivity models build
dat_perch/dat_roach with one row per observed
catch event, plus one row per zero-catch net with
length_cm = NA. Because s(length_cm, ...)
needs a length value, mgcv::gam()’s default
na.action = na.omit silently drops every zero-catch net —
those models compared catch counts only among mesh/net-type combinations
where something was caught, never against true absence.
GAM_size_structure_ZeroFilled.R fixes this by expanding
every net × mesh × net-type combination onto the 8
Size_Class categories already used elsewhere in this
analysis, with catch_n as a real, explicit 0 where nothing
of that size was caught. Refitting the same models on this zero-filled
data reverses the headline conclusion:
tribble(
~Species, ~`Zone scope`, ~`p, catch-only (original)`, ~`p, zero-filled (this analysis)`,
"Perch", "Both zones", "1.8 × 10⁻¹³", "0.929",
"Roach", "Both zones", "< 2.2 × 10⁻¹⁶", "0.464",
"Perch", "Benthic only", "5.6 × 10⁻¹²", "0.718",
"Roach", "Benthic only", "< 2.2 × 10⁻¹⁶", "0.905"
) |>
knitr::kable(
caption = paste(
"Likelihood-ratio test, mesh×net-type selectivity smooth (Model 1) vs shared-smooth",
"baseline (Model 0). 'catch-only' p-values are from the original report",
"(Gillnet_Selectivity_BothZones_vs_Benthic.Rmd); every one of the four scopes flips",
"from highly significant to non-significant once zero-catch nets are counted."
)
)
Likelihood-ratio test, mesh×net-type selectivity smooth (Model
1) vs shared-smooth baseline (Model 0). ‘catch-only’ p-values are from
the original report (Gillnet_Selectivity_BothZones_vs_Benthic.Rmd);
every one of the four scopes flips from highly significant to
non-significant once zero-catch nets are counted.
| Perch |
Both zones |
1.8 × 10⁻¹³ |
0.929 |
| Roach |
Both zones |
< 2.2 × 10⁻¹⁶ |
0.464 |
| Perch |
Benthic only |
5.6 × 10⁻¹² |
0.718 |
| Roach |
Benthic only |
< 2.2 × 10⁻¹⁶ |
0.905 |
Caveat carried through this whole report: this could be a
resolution artefact, not (only) a real reversal. A follow-up
check refit all four zero-filled models with finer, fixed 5cm-wide bins
instead of the 8 Size_Class categories. Two of the four
moved back toward significance (Roach both-zones: p = 0.019; Perch
Benthic: p = 0.075) while the other two did not (Perch both zones: p =
0.518; Roach Benthic: p = 0.698) — still nowhere near the original’s p
< 10⁻¹¹ range for any of the four. The coarser the bins, the less
power the model has to detect a real shape difference, so the
exact non-significance reported here is somewhat
resolution-dependent — treat “no shape difference detected” as
the qualitative takeaway, not the precise p-values.
Perch
Model comparison and key coefficients
anova(m0_Perch, m1_Perch, test = "Chisq")
## Analysis of Deviance Table
##
## Model 1: catch_n ~ offset(log(area_m2)) + s(length_cm, by = mesh_mm, k = 8) +
## mesh_mm + net_type + zone + s(lake_year, bs = "re")
## Model 2: catch_n ~ offset(log(area_m2)) + s(length_cm, by = mesh_net,
## k = 8) + mesh_mm + net_type + zone + s(lake_year, bs = "re")
## Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1 32089 14896
## 2 32040 14861 48.215 34.646 0.929
bind_rows(
`Model 0 (shared smooth)` = extract_coefs(m0_Perch),
`Model 1 (interaction)` = extract_coefs(m1_Perch),
.id = "Model"
) |> knitr::kable(digits = 3, caption = "Perch, both zones")
Perch, both zones
| net_typeMOD…1 |
Model 0 (shared smooth) |
net_typeMOD |
-0.101 |
0.068 |
0.137 |
| zonePelagic…2 |
Model 0 (shared smooth) |
zonePelagic |
-2.984 |
0.095 |
0.000 |
| net_typeMOD…3 |
Model 1 (interaction) |
net_typeMOD |
-0.859 |
0.642 |
0.181 |
| zonePelagic…4 |
Model 1 (interaction) |
zonePelagic |
-2.977 |
0.095 |
0.000 |
anova(m0_Perch_Benthic, m1_Perch_Benthic, test = "Chisq")
## Analysis of Deviance Table
##
## Model 1: catch_n ~ offset(log(area_m2)) + s(length_cm, by = mesh_mm, k = 8) +
## mesh_mm + net_type + s(lake_year, bs = "re")
## Model 2: catch_n ~ offset(log(area_m2)) + s(length_cm, by = mesh_net,
## k = 8) + mesh_mm + net_type + s(lake_year, bs = "re")
## Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1 23210 12997
## 2 23162 12954 48.216 42.151 0.718
bind_rows(
`Model 0 (shared smooth)` = extract_coefs(m0_Perch_Benthic),
`Model 1 (interaction)` = extract_coefs(m1_Perch_Benthic),
.id = "Model"
) |> knitr::kable(digits = 3, caption = "Perch, Benthic zone only")
Perch, Benthic zone only
| net_typeMOD…1 |
Model 0 (shared smooth) |
net_typeMOD |
-0.191 |
0.070 |
0.007 |
| net_typeMOD…2 |
Model 1 (interaction) |
net_typeMOD |
-1.069 |
0.692 |
0.122 |
Selectivity Curves — Both Zones vs Benthic Only
Both zones
Perch_Selectivity_Plot

Benthic zone
Perch_Benthic_Selectivity_Plot

Roach
Model comparison and key coefficients
anova(m0_roach, m1_roach, test = "Chisq")
## Analysis of Deviance Table
##
## Model 1: catch_n ~ offset(log(area_m2)) + s(length_cm, by = mesh_mm, k = 8) +
## mesh_mm + net_type + zone + s(lake_year, bs = "re")
## Model 2: catch_n ~ offset(log(area_m2)) + s(length_cm, by = mesh_net,
## k = 8) + mesh_mm + net_type + zone + s(lake_year, bs = "re")
## Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1 32093 10494
## 2 32051 10452 42.554 42.731 0.4636
bind_rows(
`Model 0 (shared smooth)` = extract_coefs(m0_roach),
`Model 1 (interaction)` = extract_coefs(m1_roach),
.id = "Model"
) |> knitr::kable(digits = 3, caption = "Roach, both zones")
Roach, both zones
| net_typeMOD…1 |
Model 0 (shared smooth) |
net_typeMOD |
-0.109 |
0.074 |
0.141 |
| zonePelagic…2 |
Model 0 (shared smooth) |
zonePelagic |
-1.215 |
0.080 |
0.000 |
| net_typeMOD…3 |
Model 1 (interaction) |
net_typeMOD |
-0.674 |
1.332 |
0.613 |
| zonePelagic…4 |
Model 1 (interaction) |
zonePelagic |
-1.223 |
0.080 |
0.000 |
anova(m0_roach_Benthic, m1_roach_Benthic, test = "Chisq")
## Analysis of Deviance Table
##
## Model 1: catch_n ~ offset(log(area_m2)) + s(length_cm, by = mesh_mm, k = 8) +
## mesh_mm + net_type + s(lake_year, bs = "re")
## Model 2: catch_n ~ offset(log(area_m2)) + s(length_cm, by = mesh_net,
## k = 8) + mesh_mm + net_type + s(lake_year, bs = "re")
## Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1 23218 7509.7
## 2 23178 7480.9 39.921 28.762 0.9053
bind_rows(
`Model 0 (shared smooth)` = extract_coefs(m0_roach_Benthic),
`Model 1 (interaction)` = extract_coefs(m1_roach_Benthic),
.id = "Model"
) |> knitr::kable(digits = 3, caption = "Roach, Benthic zone only")
Roach, Benthic zone only
| net_typeMOD…1 |
Model 0 (shared smooth) |
net_typeMOD |
-0.091 |
0.083 |
0.276 |
| net_typeMOD…2 |
Model 1 (interaction) |
net_typeMOD |
1.188 |
1.796 |
0.508 |
Selectivity Curves — Both Zones vs Benthic Only
Both zones
Roach_Selectivity_Plot

Benthic zone
Roach_Benthic_Selectivity_Plot
