Analysing real catch and effort data: a step-by-step guide

This guide shows how to prepare fishery-dependent catch and effort data for CPUE standardisation when fishers change what they target. It generalises the protocol developed for blackspot seabream (GFCM) to any multispecies fishery, from the raw logbook to the standardised index.

Step Question Functions
1. Format Which column is what? One row per operation? cpue_data(), subset()
2. Fleet Who fished when? Is reporting consistent? Which vessels are indicators? plot_fleet(), vessel_summary(), select_vessels(), plot_vessel_profile()
3. Species Which species carry the targeting signal? species_curve(), plot_species_curve(), select_species()
4. Nominal CPUE What do the raw data say? nominal_cpue(), plot_nominal(), plot_composition(), plot_cpue_map()
5. Subsetting (optional) Which operations fished the target’s habitat? stephens_maccall(), plot_stephens_maccall(), select_tactics() (after Step 6)
6. Targeting covariates How did fishing tactics change? add_targeting(), plot_oc(), plot_biplot(), tactic_table(), plot_targeting()
7. Models Base, Covariates, DPC, Cluster, spatial, vessel effects fit_cpue()
8. Diagnostics Which terms matter, and do the models fit? Is the error distribution right? cpue_diagnostics(), plot_index(), plot_step(), plot_influence(), plot_residuals(), ppc_cpue(), plot_effects(), plot_vessel_effects()
9. Index The index for the assessment cpue_index(), export_index()

Every step returns the same kind of object, and every step that removes operations writes a line into a processing log, so the final data set can be reported exactly.

Example data

To show what each step should find, the example uses a logbook generated by the bathymetric simulator (simulate_bathymetric()): four species live along a depth gradient and 30 vessels shift effort between them as prices change (years 1-10, 11-20, 21-30). In real data the truth is unknown; here it lets us check that the tools recover the changes in targeting.

We turn the simulation into a typical logbook extract: one row per trip and species, with catch in kg, hours fished, month, a coarse position, two rare bycatch species, and one species recorded under two names.

sim <- simulate_bathymetric(seed = 123)
set.seed(1)
sets <- as_set_data(sim$Data)
sets$hours <- round(runif(nrow(sets), 4, 12), 1)
sets$month <- sample(1:12, nrow(sets), replace = TRUE)
names_sp <- c(Sp1 = "Eopsetta jordani", Sp2 = "Microstomus pacificus",
              Sp3 = "Sebastes crameri", Sp4 = "Anoplopoma fimbria")
long <- do.call(rbind, lapply(names(names_sp), function(s) {
  data.frame(trip = sets$SetID, year = sets$year + 1999, vessel = sets$vessel,
             hours = sets$hours, month = sets$month, lon = sets$Xobs, lat = sets$Yobs,
             species = names_sp[[s]], kg = sets[[s]] * sets$hours)
}))
# rare bycatch and a synonym
rare <- data.frame(trip = sample(sets$SetID, 400), species = "Raja spp.", kg = rexp(400))
rare2 <- data.frame(trip = sample(sets$SetID, 80), species = "Squalus suckleyi", kg = rexp(80))
extra <- rbind(rare, rare2)
extra <- cbind(long[match(extra$trip, long$trip), c("year", "vessel", "hours", "month",
                                                    "lon", "lat")], extra)
long <- rbind(long, extra[, names(long)])
syn <- long$species == "Anoplopoma fimbria" & runif(nrow(long)) < 0.1
long$species[syn] <- "Sablefish"
logbook <- long[long$kg > 0, ]
head(logbook)
##   trip year vessel hours month  lon lat          species           kg
## 1    1 2000      6   6.1    10  8.5 3.5 Eopsetta jordani 386.36821205
## 3    3 2000      3   8.6    12 23.5 3.5 Eopsetta jordani   0.04827733
## 4    4 2000     10  11.3     1 43.5 3.5 Eopsetta jordani   4.19410019
## 6    6 2000     21  11.2    12  8.5 3.5 Eopsetta jordani 535.39500130
## 7    7 2000     14  11.6     4  8.5 3.5 Eopsetta jordani 345.30096240
## 8    8 2000     17   9.3     6 18.5 3.5 Eopsetta jordani  78.78594164

Step 1. Format the data

cpue_data() takes the logbook in long format (one row per operation and species, as above) or wide format (one row per operation, one column per species) and returns one row per operation. Tell it which column plays which role.

x <- cpue_data(logbook, year = "year", species = "species", catch = "kg",
               effort = "hours", id = "trip", vessel = "vessel",
               lon = "lon", lat = "lat", covariates = "month",
               synonyms = c("Sablefish" = "Anoplopoma fimbria"))
x
## <cpue_data> 12799 operations, 6 species, years 2000 - 2029 
##   vessels: 30 
##   effort: hours 
##   position: lon / lat 
##   covariates: month 
##   main species: Microstomus pacificus, Anoplopoma fimbria, Eopsetta jordani, Sebastes crameri, Raja spp. ... 
## Processing log:
##                 step operations                     note
##  input (long format)      12799 44049 records, 6 species

Guidelines

  • Define the operation carefully: the unit at which effort and catch composition are recorded (set, haul, fishing day or trip). Catch composition reflects targeting best at the finest unit available; trips that span several fishing grounds or gears mix tactics.
  • Choose an effort measure that scales catch (hours fished, hooks, days at sea). Without effort, the catch per operation is used.
  • Merge synonyms and drop non-informative categories (bait, discards, “unidentified”) before anything else; they change the species set.
  • Use subset() for any further rule (e.g. single-day trips, a gear, a period). Each call is recorded in the log.
x <- subset(x, month %in% 1:12, note = "all months (example)")

Step 2. Explore the fleet

Standardisation corrects for the non-random allocation of effort. First look at how operations are spread over years and vessels.

fl <- plot_fleet(x, by = "month")
fl$records

fl$vessels

fl$vessel_years

Guidelines

  • Strong fleet turnover (new vessels replacing old ones) confounds vessel efficiency with year; random vessel effects help, but only if vessels overlap in time.
  • An indicator fleet of vessels that fished consistently can make reporting more homogeneous. select_vessels(x, min_years, min_records) keeps vessels with at least min_records operations in at least min_years years. Compare indices with and without the selection.
  • Rules on the target species keep vessels that fish its habitat regularly: target, min_years_target (years with catches of the target), min_share_target (share of the vessel’s operations catching it) and min_catch_target. vessel_summary() lists these quantities for every vessel and plot_vessel_profile() shows each vessel’s catch split by species or species group, which separates specialists from mixed vessels. Rules on the target select vessels by their catches of it: prefer rules on years active and on the share of operations, and always compare with the index of all vessels.
x_core <- select_vessels(x, min_years = 10, min_records = 5)
x_core$log
##                  step operations
## 1 input (long format)      12799
## 2 select core vessels      12799
##                                                           note
## 1                                     44049 records, 6 species
## 2 30 of 30 vessels (>= 10 years with >= 5 records) (0 removed)
vs <- vessel_summary(x, target = "Anoplopoma fimbria")
head(vs)
##   vessel records years years_qualified first last records_target share_target
## 1     10     470    30              30  2000 2029            373    0.7936170
## 2     23     466    30              30  2000 2029            374    0.8025751
## 3     28     456    30              30  2000 2029            416    0.9122807
## 4     11     451    30              30  2000 2029            413    0.9157428
## 5     14     448    30              30  2000 2029            376    0.8392857
## 6      1     443    30              30  2000 2029            350    0.7900677
##   years_target catch_target
## 1           30     18899.91
## 2           30     20474.02
## 3           30     30760.53
## 4           30     31132.41
## 5           30     22601.00
## 6           30     18512.00
x_target <- select_vessels(x, min_years = 10, min_records = 5,
                           target = "Anoplopoma fimbria", min_share_target = 0.3)
table(attr(x_target, "vessels")$selected)
## 
## TRUE 
##   30
plot_vessel_profile(x)

Step 3. Choose the species set

The catch composition carries the targeting signal, but rare species add noise and many zero proportions. The cumulative species curve ranks species by how often they are recorded; the species needed to reach a cumulative share (95% by default) form the species set.

species_curve(x)
##                 species                 label rank value       share cumulative
## 1 Microstomus.pacificus Microstomus pacificus    1 10954 0.248677609  0.2486776
## 2      Sebastes.crameri      Sebastes crameri    2 10905 0.247565211  0.4962428
## 3    Anoplopoma.fimbria    Anoplopoma fimbria    3 10861 0.246566324  0.7428091
## 4      Eopsetta.jordani      Eopsetta jordani    4 10849 0.246293900  0.9891030
## 5             Raja.spp.             Raja spp.    5   400 0.009080796  0.9981838
## 6      Squalus.suckleyi      Squalus suckleyi    6    80 0.001816159  1.0000000
plot_species_curve(x, threshold = 0.95)

x <- select_species(x, threshold = 0.95)
x$species_labels
##   Microstomus.pacificus        Sebastes.crameri      Anoplopoma.fimbria 
## "Microstomus pacificus"      "Sebastes crameri"    "Anoplopoma fimbria" 
##        Eopsetta.jordani 
##      "Eopsetta jordani"

Guidelines

  • Use occurrence (default) as the main criterion and check by = "weight": a species caught rarely but in large amounts can be a target of a distinct tactic.
  • Always keep the species of interest (keep = "..."), even if rare.
  • Species that are characteristic of other tactics are valuable even when not abundant; they are what lets the PCA separate tactics.
  • pool_other = TRUE keeps the dropped species as one Other column. Try it if many operations would be lost.
  • Operations that caught none of the selected species are removed (their composition is undefined). The log reports how many.

Step 4. Nominal CPUE and catch composition

nom <- plot_nominal(x)
nom$index

nom$positive

nom$distribution

Changes in the catch composition over time are the first sign of changes in targeting (or of diverging trends in abundance).

plot_composition(x)

plot_cpue_map(x, res = 5, by_period = 10)

In this simulation prices change in 2010 and 2020 while the true biomass trends change smoothly, so shifts in composition at those years reflect targeting.

Guidelines

  • Look at the proportion of positive operations and the distribution of positive CPUE; they guide the choice between a Tweedie and a delta model.
  • Abrupt changes in composition that coincide with regulations, markets or gear changes point to targeting, not abundance.

Step 5. Habitat-based subsetting (optional)

Stephens and MacCall (2004) keep only operations likely to have fished the habitat of the target species, predicted from the presence of the other species with a binomial GLM. It is useful when many operations could not have caught the species at all.

Here we use the least frequently recorded of the selected species as the target.

target <- tail(species_curve(x)$label, 1)
target
## [1] "Eopsetta jordani"
sm <- stephens_maccall(x, target = target)
sm
## <stephens_maccall> target: Eopsetta jordani 
##   critical probability: 0.83
##   operations kept: 10905 of 12798 (85%)
##   target present in 85% of kept and 83% of dropped operations
pl <- plot_stephens_maccall(sm)
pl$threshold

pl$coefficients

pl$kept

x_sm <- subset(x, sm$selected, note = paste("Stephens & MacCall,", target))

Guidelines

  • Subsetting discards data and the subset is defined by the catch composition, so it can change over time with targeting. Check pl$kept: a trend in the share of operations kept means the subset itself follows the targeting.
  • It removes operations that could not catch the species, but it does not correct for different catch rates within the habitat; combine it with the targeting covariates of Step 6 when targeting varies within the subset.
  • The method needs a target that is absent from a fair share of operations.

Step 6. Targeting covariates from the catch composition

add_targeting() converts the catch of each operation into proportions, applies a fourth-root transformation, runs a PCA, chooses the number of non-trivial PCs with the Optimal Coordinates test, and clusters the operations into fishing tactics (n_pc + 1 clusters, Winker et al. 2014). It adds the PC scores (PC1, PC2, …) and the tactic (FT) to the data.

x <- add_targeting(x)
x$targeting$pca
## <cpue_pca> 12798 operations, 4 species, transform: fourth_root 
##  PC eigenvalue share cumulative
##   1      2.011 0.503      0.503
##   2      1.074 0.269      0.771
##   3      0.575 0.144      0.915
##   4      0.339 0.085      1.000
## Optimal Coordinates: 2 non-trivial PC(s); 3 clusters by the npc + 1 rule

How many PCs?

plot_oc(x)

A PC is retained if its eigenvalue is at least 1 (Kaiser-Guttman) and at least the value predicted by the line through the following eigenvalues (Optimal Coordinates). Model selection criteria such as AIC are not suitable here: the composition is not independent of the response, so they select too many PCs.

What do the PCs and clusters represent?

plot_biplot(x)

tactic_table(x)
##   FT operations share              dominant Microstomus pacificus
## 1  1       6009 0.470    Anoplopoma fimbria                  32.2
## 2  2       4071 0.318 Microstomus pacificus                  73.5
## 3  3       2718 0.212      Eopsetta jordani                   6.9
##   Sebastes crameri Anoplopoma fimbria Eopsetta jordani
## 1              0.1               67.1              0.5
## 2              3.4               11.8             11.3
## 3              8.5                1.3             83.4
pt <- plot_targeting(x, by = "month", res = 5)
pt$loadings

pt$composition

pt$time

pt$pcs_time

pt$map_tactic

In this simulation, the shares of tactics should change at the price changes of 2010 and 2020: this is the targeting that the nominal CPUE cannot separate from abundance.

Guidelines

  • Name the tactics after their dominant species (tactic_table()) and check that they make sense to people who know the fishery.
  • Continuous or discrete? PCs (DPC) represent gradual changes and mixtures of tactics; clusters assume distinct tactics. Gear-defined tactics favour clusters; continuous habitat gradients favour PCs.
  • Diverging abundance trends. When the relative abundance of species changes strongly, the catch composition also carries an abundance signal. PCs can then absorb part of the true trend of the species whose relative abundance changes most, and more PCs absorb more. Coarser clusters are less affected. Compare indices with 1, 2 and n_pc PCs and with clusters, and be cautious when they differ.
  • Robustness. Compare clustering methods (method = "kmeans", "hclust"), the input (on = "pcs"), and the species set from Step 3.
  • Run add_targeting() after the last subsetting step; PCs and clusters depend on the operations included.

Removing irrelevant tactics (optional)

When the fleet uses tactics that cannot catch the species of interest (e.g. pelagic trolling for a demersal species), these trips add zeros that carry no information on its abundance, and the PCA spends its first axes on the contrast with them. select_tactics() removes clusters, by number or by species content, and recomputes the PCA and clusters on the remaining operations:

tactic_table(x)                       # identify the irrelevant cluster(s)
x2 <- select_tactics(x, drop = 3)     # by number, or by species content:
x2 <- select_tactics(x, species = c("Sp A", "Sp B"), min_share = 0.5)
tactic_table(x2)
  • Select on a group of species, not on the target alone: the clusters come from the catch composition, so selecting clusters rich in the target would select operations by their catch of the target.
  • Removed clusters should be clearly different, not borderline; check the share removed by year and compare the index with and without the selection.

Step 7. Fit the standardisation models

fit_cpue() fits a set of GAMs (mgcv) to the CPUE of one species and derives an annual index from each. Every model contains the year effect and differs in how it accounts for targeting:

Model Terms besides year
Base none
Covariates terms you give (e.g. month, port, gear)
DPC terms + smooths of the first n_pc PC scores
Cluster terms + fishing tactic (FT) as a factor
...+S adds a smoother of the reported positions

vessel = TRUE adds a random vessel intercept to every model. The default family is Tweedie, whose power parameter is estimated together with the model (also with random vessel effects); delta-lognormal and delta-gamma models are alternatives.

Here we standardise the deep-water species, whose price rises over the three decades so that it is targeted more and more.

fit <- fit_cpue(x, species = "Anoplopoma fimbria",
                models = c("Base", "Base+S", "Cluster+S", "DPC", "DPC+S"),
                vessel = TRUE, spatial_k = 30, engine = "bam")
fit
## <cpue_fit> Anoplopoma fimbria - tweedie with random vessel effects 
##   operations: 12798 ; years: 2000 - 2029 
##   index averaged over: FT (and positions in spatial models) 
## Models:
##   Base         y ~ fyear + s(vessel_re, bs = "re")
##   Base+S       y ~ fyear + s(pos_x, pos_y, k = 30) + s(vessel_re, bs = "re")
##   Cluster+S    y ~ fyear + s(pos_x, pos_y, k = 30) + FT + s(vessel_re, bs = "re")
##   DPC          y ~ fyear + s(PC1, k = 4) + s(PC2, k = 4) + s(vessel_re, bs = "re")
##   DPC+S        y ~ fyear + s(pos_x, pos_y, k = 30) + s(PC1, k = 4) + s(PC2, k = 4) + s(vessel_re, bs = "re")

The index of each year is the expected CPUE averaged over a reference set of covariate values: all observed positions, the fishing tactics (and months, if in the model), the median PC scores, and the average vessel.

Guidelines

  • Add terms in a meaningful order (e.g. Base, then space, then targeting) so that the step plot shows what each term does.
  • For a seasonal effect use a cyclic smoother: terms = 's(month, bs = "cc", k = 8)', knots = list(month = c(0.5, 12.5)).
  • Use engine = "bam" for large data sets (tens of thousands of operations or more).
  • With many zeros and no clear separation between “could not catch” and “did not catch”, Tweedie is a natural default; compare with a delta model (family = "delta_lognormal") when the proportion of positive catches changes strongly over time.

Step 8. Diagnostics

Model comparison

cpue_diagnostics(fit)
##       model component     n     AIC     BIC dev_explained  edf tweedie_p
## 1      Base      main 12798 72221.8 72660.4        0.0322 56.7     1.722
## 2    Base+S      main 12798 69827.7 70481.6        0.1679 85.5     1.697
## 3 Cluster+S      main 12798 60366.9 61026.4        0.5691 86.0     1.605
## 4       DPC      main 12798 49057.7 49551.6        0.8127 64.2     1.558
## 5     DPC+S      main 12798 49011.6 49650.3        0.8141 82.8     1.557
##   vessel_sd    dAIC
## 1     0.225 23210.2
## 2     0.223 20816.1
## 3     0.214 11355.4
## 4     0.189    46.1
## 5     0.190     0.0

AIC and BIC are only comparable between models with the same data and family, and they tend to favour many targeting terms because the catch composition is not independent of the response. Use them together with the following plots.

Indices and steps

Since the data are simulated, the true biomass trend is known and can be added to the plot.

truth <- data.frame(year = 1:30 + 1999,
                    true = sim$Biomass$True[sim$Biomass$Sp == "Sp4"])
plot_index(fit, true = truth)

plot_step(fit)

Influence

The influence of a term in a year is the ratio between the expected CPUE given that year’s covariate values and given the values of all years (Bentley et al. 2012). A term that changes the index has influence that changes over time.

plot_influence(fit, "DPC+S")

Residuals, effects and vessels

For Tweedie models the residuals are randomised quantile residuals, which should be standard normal if the model fits, despite the zeros.

res <- plot_residuals(fit, "DPC+S", by = "FT")
res$qq

res$fitted

res$year

Predictive check of the error distribution

Residuals check each observation against its own predicted distribution. A predictive check asks whether the fitted error distribution reproduces the data as a whole: the share of zeros, the upper tail and the shape of the positive catches. ppc_cpue() simulates replicate data sets from each fitted model: for every operation the expected CPUE is computed (with the coefficients drawn from their approximate posterior, so parameter uncertainty is included) and a new value is drawn from the fitted Tweedie (or delta) distribution. Each replicate is summarised like the observed data, and the spread across replicates gives a 95% envelope. This is an approximate posterior predictive check (Gelman et al. 1996); with param_uncertainty = FALSE it is a plug-in (parametric bootstrap) check.

pp <- ppc_cpue(fit, models = c("Base", "DPC+S"), n_sim = 50)
pp
## Predictive check: 50 replicates, with parameter uncertainty, tweedie 
## 
##  model  stat observed median  lower  upper tail_prob
##   Base zeros    0.151  0.149  0.142  0.155      0.20
##   Base  mean    6.520  6.500  6.330  6.750      0.40
##   Base   q90   19.900 19.600 19.000 20.400      0.28
##   Base   q99   37.300 44.300 42.100 46.300      1.00
##  DPC+S zeros    0.151  0.126  0.122  0.134      0.00
##  DPC+S  mean    6.520  6.580  6.470  6.710      0.88
##  DPC+S   q90   19.900 19.800 19.300 20.300      0.26
##  DPC+S   q99   37.300 35.600 34.400 36.700      0.00
pp$plots$distribution

pp$plots$zeros

pp$plots$tails

How to read it:

  • Zeros observed above the envelope: the model predicts too few zeros (e.g. a Poisson-type or lognormal-type error); below: too many.
  • Upper quantiles observed below the envelope: the model’s tail is too heavy (e.g. a negative binomial or a lognormal with large variance); above: too light.
  • Histogram of CPUE, zeros included (pp$plots$distribution): observed bars (the zero bar leftmost) against the predictive distribution (points with 95% ranges). Systematic departures point to the wrong distribution or power parameter. CPUE spans orders of magnitude, so the histogram is on a fourth-root scale by default (zero stays next to the small catches); scale = "log" shows the shape of the positive catches best, with the zeros as a separate bar, and scale = "raw" the untransformed values.
  • By year. Pooled over all operations, errors in opposite directions can cancel. The year effect fixes the mean CPUE of each year, not its zeros: a model without targeting covariates gives every operation in a year the same expected catch and gets the zeros wrong in years when the fleet fished elsewhere. A good targeting term brings the observed zeros inside the envelope. Other groupings: by = "FT", by = "month".
  • tail_prob is the share of replicates at least as large as the observed value; values near 0 or 1 flag misfit.
  • Information criteria cannot compare a Tweedie with a delta model; a predictive check can.
eff <- plot_effects(fit, "DPC+S")
eff$numeric

eff$space

plot_vessel_effects(fit, "DPC+S")

Guidelines

  • Check the influence of the targeting terms: a strong trend in influence means targeting changed and the term corrects for it.
  • Check that residuals show no trend by year and no pattern against the targeting covariates or tactics.
  • Check that the error distribution reproduces the zeros and the upper tail by year (ppc_cpue()).
  • Compare the DPC and Cluster indices. If they disagree, look at what the PCs capture over time (Step 6) and whether the species’ relative abundances may have diverged.

Step 9. The final index

cpue_index(fit, "DPC+S")
##    year   n  nominal    index  relative     se_log         cv     lower
## 1  2000 240 4.510639 7.829132 1.0210274 0.06019585 0.06025042 0.9073976
## 2  2001 341 5.015292 8.038209 1.0482940 0.05347061 0.05350886 0.9439913
## 3  2002 278 4.842745 8.355991 1.0897372 0.05735354 0.05740074 0.9738710
## 4  2003 266 4.580052 7.852519 1.0240774 0.05887658 0.05892764 0.9124646
## 5  2004 193 5.362843 7.952326 1.0370937 0.06353565 0.06359983 0.9156623
## 6  2005 285 4.500457 7.740408 1.0094566 0.05721895 0.05726581 0.9023643
## 7  2006 347 4.314219 8.153240 1.0632956 0.05509937 0.05514122 0.9544484
## 8  2007 413 5.213270 8.015370 1.0453155 0.05191488 0.05194988 0.9441838
## 9  2008 329 5.567656 7.829928 1.0211312 0.05324202 0.05327978 0.9199432
## 10 2009 391 4.924253 7.932474 1.0345047 0.05210057 0.05213595 0.9340789
## 11 2010 394 7.885983 8.301923 1.0826859 0.04876832 0.04879733 0.9839885
## 12 2011 315 7.431699 8.014271 1.0451721 0.05142740 0.05146142 0.9449568
## 13 2012 477 6.431612 7.463754 0.9733771 0.04744480 0.04747152 0.8869421
## 14 2013 439 7.263159 8.429152 1.0992784 0.04802593 0.04805363 1.0005233
## 15 2014 488 7.248029 8.058796 1.0509788 0.04682770 0.04685338 0.9588119
## 16 2015 453 6.384588 7.768571 1.0131294 0.04811571 0.04814357 0.9219513
## 17 2016 487 6.671560 7.582673 0.9888858 0.04716407 0.04719031 0.9015696
## 18 2017 559 6.992933 7.808668 1.0183586 0.04582210 0.04584617 0.9308853
## 19 2018 569 5.710792 7.039132 0.9180005 0.04671586 0.04674136 0.8376789
## 20 2019 593 6.531376 7.598737 0.9909807 0.04564496 0.04566875 0.9061736
## 21 2020 459 7.881028 7.550423 0.9846799 0.04715862 0.04718485 0.8977447
## 22 2021 344 7.925384 7.381901 0.9627022 0.04971617 0.04974690 0.8733186
## 23 2022 362 6.900679 7.612664 0.9927969 0.04984598 0.04987696 0.9003900
## 24 2023 460 8.181433 7.236991 0.9438040 0.04677814 0.04680374 0.8611195
## 25 2024 600 7.014238 7.188222 0.9374439 0.04535725 0.04538058 0.8577020
## 26 2025 742 7.015133 7.051518 0.9196158 0.04386800 0.04388912 0.8438499
## 27 2026 368 7.352740 7.145158 0.9318277 0.04951137 0.04954172 0.8456501
## 28 2027 522 7.668463 7.509477 0.9793400 0.04623283 0.04625755 0.8944979
## 29 2028 585 6.410652 6.968861 0.9088362 0.04584792 0.04587202 0.8307284
## 30 2029 499 7.036113 6.626388 0.8641729 0.04672034 0.04674585 0.7885541
##        upper
## 1  1.1488865
## 2  1.1641212
## 3  1.2193885
## 4  1.1493427
## 5  1.1746287
## 6  1.1292586
## 7  1.1845558
## 8  1.1572794
## 9  1.1334492
## 10 1.1457275
## 11 1.1912829
## 12 1.1560156
## 13 1.0682354
## 14 1.2077810
## 15 1.1520054
## 16 1.1133247
## 17 1.0846585
## 18 1.1140516
## 19 1.0060238
## 20 1.0837247
## 21 1.0800337
## 22 1.0612342
## 23 1.0946876
## 24 1.0344278
## 25 1.0245995
## 26 1.0021844
## 27 1.0267875
## 28 1.0722293
## 29 0.9942879
## 30 0.9470432
export_index(fit, "cpue_index_DPC.csv", model = "DPC+S")

index is in the units of the data (CPUE at the reference covariate values), relative is scaled to its mean, and se_log is the standard error of the log index, the usual input to stock assessment models.

Processing log

The log records every step, how many operations it removed, and the settings used.

x$log
##                                         step operations
## 1                        input (long format)      12799
## 2                             select species      12799
## 3 remove operations without selected species      12798
## 4                              add targeting      12798
##                                                           note
## 1                                     44049 records, 6 species
## 2                     4 of 6 species kept (occurrence >= 0.95)
## 3               zero catch of all selected species (1 removed)
## 4 2 PC(s) used (OC test: 2), 3 clusters (clara on composition)

Reporting checklist

Item Report
Operation and effort unit (set, trip, …), effort measure
Data selection all subsetting rules and the processing log
Species set threshold, criterion (occurrence or weight), species kept
Fleet indicator-fleet rules (activity and target species), number of vessels
Subsetting Stephens & MacCall target, critical value, share kept over time; tactics removed (select_tactics())
Targeting transformation, eigenvalues, OC result, number of PCs and clusters, clustering method, tactic composition
Models family, terms of each model, random effects, reference set of the index
Diagnostics model table, step and influence plots, residuals, predictive check (zeros and tails by year), vessel effects
Index table with nominal and standardised CPUE, log SE and CV
Sensitivity indices with alternative species sets, numbers of PCs, clusters, families

References

Bentley, N., Kendrick, T.H., Starr, P.J. and Breen, P.A. (2012) Influence plots and metrics: tools for better understanding fisheries catch-per-unit-effort standardizations. ICES Journal of Marine Science 69: 84-88.

Dunn, P.K. and Smyth, G.K. (1996) Randomized quantile residuals. Journal of Computational and Graphical Statistics 5: 236-244.

Gelman, A., Meng, X.-L. and Stern, H. (1996) Posterior predictive assessment of model fitness via realized discrepancies. Statistica Sinica 6: 733-807.

Hoyle, S.D., Langley, A.D. and Campbell, R.A. (2014) Recommended approaches for standardizing CPUE data from pelagic fisheries. WCPFC-SC10-2014/SA-IP-10.

Stephens, A. and MacCall, A. (2004) A multispecies approach to subsetting logbook data for purposes of estimating CPUE. Fisheries Research 70: 299-310.

Winker, H., Kerwath, S.E. and Attwood, C.G. (2013) Comparison of two approaches to standardize catch-per-unit-effort for targeting behaviour in a multispecies hand-line fishery. Fisheries Research 139: 118-131.

Winker, H., Kerwath, S.E. and Attwood, C.G. (2014) Proof of concept for a novel procedure to standardize multispecies catch and effort data. Fisheries Research 155: 149-159.