--- title: "Incomplete-Trip Interviews" output: rmarkdown::html_vignette: highlight: null vignette: > %\VignetteIndexEntry{Incomplete-Trip Interviews} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) library(tidycreel) ``` ## The task An interview with an angler who is still fishing records the catch and hours *so far*: an incomplete trip. This page covers how tidycreel estimates a catch rate from incomplete trips, how to check those rates against complete trips, and what the package will not do with them. ## What the sources say - **Two estimators, one for each kind of trip.** For complete trips the catch rate is the ratio of means, total catch over total effort. For incomplete trips it is the mean of the individual catch rates, leaving out very short trips (say, under half an hour), whose rates are dominated by chance (Pollock et al. 1994, section 15.3.3.5). - **Why the mean of ratios for incomplete trips.** A roving clerk meets a party in proportion to how long it fishes. Under that length-biased selection, and with a catch rate that does not change over the trip (a stationary fishing process), the mean of ratios has approximately the right expectation once trips under 30 minutes are dropped; it also had the smaller mean squared error in their simulations (Hoenig et al. 1997). - **The risk.** If the catch rate changes during a trip, rates from trips caught part-way through misstate it: length-of-stay bias. Pollock et al. (1994, p. 230) report evidence ranging "from negligible to substantial" and advise checking roving rates against complete-trip data from the same fishery. `vignette("estimator-choice")` explains how the package picks between the two estimators. ## What tidycreel does by default The interview type decides: | Design | Default rate | |---|---| | Access point (`interview_type = "access"`, the default) | ratio of means on complete trips | | Roving (`interview_type = "roving"`) | mean of ratios on all trips, trips under `truncate_at` (0.5 h) removed | Naming `use_trips` or `estimator` turns the default off. The `method` field records which estimator ran: ```{r roving-default} roving_design <- creel_design(example_calendar, date = date, strata = day_type) |> add_counts(prep_counts_daily_effort(example_counts, date = date, strata = day_type, daily_effort = effort_hours )) |> add_interviews( example_interviews, catch = catch_total, effort = hours_fished, n_anglers = n_anglers, harvest = catch_kept, trip_status = trip_status, trip_duration = trip_duration, interview_type = "roving" ) estimate_catch_rate(roving_design)$method estimate_catch_rate(roving_design, use_trips = "complete")$method ``` On a roving design the unspecified default uses every interview, finished or not. If you need complete trips only, name `use_trips = "complete"`. The first call warns that 22 interviews is a small sample for a rate; the example dataset is small. ## Estimating from incomplete trips on an access design The rest of the page uses a simulated access-point survey with 50 complete and 120 incomplete trips. The catch rate is the same, about 2.4 fish per hour, for both, so the two kinds of trip should agree. ```{r sim-helper} simulate_survey <- function(seed, n_complete, n_incomplete, rate_complete, rate_incomplete, hours_complete, hours_incomplete) { set.seed(seed) calendar <- data.frame( date = seq.Date(as.Date("2024-06-01"), as.Date("2024-06-14"), by = "day"), day_type = rep(c("weekday", "weekend"), length.out = 14) ) # Angler-hours for each sampled day daily <- data.frame( date = calendar$date, day_type = calendar$day_type, effort_hours = round(runif(14, min = 50, max = 150)) ) trips <- function(n, status, hours, rate) { x <- data.frame( date = sample(calendar$date, n, replace = TRUE), hours_fished = runif(n, hours[1], hours[2]), trip_status = status ) x$trip_duration <- x$hours_fished # hours so far, for an incomplete trip x$catch_total <- rpois(n, lambda = x$hours_fished * rate) x } interviews <- rbind( trips(n_complete, "complete", hours_complete, rate_complete), trips(n_incomplete, "incomplete", hours_incomplete, rate_incomplete) ) creel_design(calendar, date = date, strata = day_type) |> add_counts(prep_counts_daily_effort(daily, date = date, strata = day_type, daily_effort = effort_hours )) |> add_interviews(interviews, catch = catch_total, effort = hours_fished, n_anglers = 1, trip_status = trip_status, trip_duration = trip_duration ) } design <- simulate_survey(42, n_complete = 50, n_incomplete = 120, rate_complete = 2.4, rate_incomplete = 2.35, hours_complete = c(2, 8), hours_incomplete = c(0.1, 6) ) ``` Each simulated interview is one angler, so `n_anglers = 1`. On an access design the incomplete-trip rate has to be asked for by name, with both the trip set and the estimator: ```{r incomplete-rate} estimate_catch_rate(design, use_trips = "complete") estimate_catch_rate(design, use_trips = "incomplete", estimator = "mor") ``` Asking for incomplete trips with the ratio of means is refused: the length bias of incomplete trips makes that estimator wrong. ### Short trips `truncate_at` is the shortest trip, in hours, the mean of ratios keeps. The default, half an hour, follows Hoenig et al. (1997). `NULL` keeps every trip, and the package says the variance is then not trustworthy: without truncation the estimator's variance is infinite. ```{r truncation} estimate_catch_rate(design, use_trips = "incomplete", estimator = "mor", truncate_at = 1 )$estimates estimate_catch_rate(design, use_trips = "incomplete", estimator = "mor", truncate_at = NULL )$estimates ``` At the default cutoff 5 of the 120 incomplete trips are dropped. Raising it to one hour drops 24, a fifth of them, and the package warns: when that many trips are short, the cutoff is removing a real part of the fishery rather than noise, and it is worth checking how trip lengths were recorded. With no cutoff all 120 are kept. ## Checking incomplete trips against complete ones Two tools compare the rates from the two kinds of trip. Both are the package's own; the sources advise the comparison but do not prescribe a test. ### Side by side `use_trips = "diagnostic"` estimates both and prints the difference: ```{r diagnostic} estimate_catch_rate(design, use_trips = "diagnostic") ``` Its "similar" or "different" verdict uses a 10% difference as the line. That is a rule of thumb, not a test. ### An equivalence test `validate_incomplete_trips()` asks whether the two rates are *equivalent*: closer than a margin, rather than merely not shown to differ. It uses two one-sided tests (TOST; Schuirmann 1987), each at the 5% level. The margin is ±20% of the complete-trip rate by default; set it with, for example, `options(tidycreel.equivalence_threshold = 0.15)` for ±15%. The margin is a package default, not a published standard: choose it for the decision the rate will support. ```{r validate-pass} validate_incomplete_trips(design, catch = catch_total, effort = hours_fished) ``` The same check on a fishery where anglers interviewed early in their trip catch fewer fish per hour (complete trips at 3.0 fish per hour, incomplete at 2.0): ```{r validate-fail} design_biased <- simulate_survey(123, n_complete = 45, n_incomplete = 110, rate_complete = 3.0, rate_incomplete = 2.0, hours_complete = c(3, 8), hours_incomplete = c(1, 5) ) validate_incomplete_trips(design_biased, catch = catch_total, effort = hours_fished) ``` When the check fails, estimate from complete trips and name them, `use_trips = "complete"`, rather than relying on a default. A failed check means the rate changes during trips, which is the stationarity assumption the mean of ratios rests on. `by =` runs the test within each group as well, and passes only if every group and the overall comparison pass. The package also warns when fewer than 10% of interviews are complete trips (option `tidycreel.min_complete_pct`). That threshold is likewise a package default, not a published rule. ## Mixing the two kinds of trip There is no `use_trips = "both"` on an access design. A ratio of means over complete and incomplete trips together divides whole-trip catch plus catch so far by whole-trip hours plus hours so far, which is neither of the estimators above. The roving default is different: it is the mean of ratios, the estimator the roving selection calls for, applied to every interview. ## Summary | Goal | Call | |---|---| | Rate from complete trips | `estimate_catch_rate(design, use_trips = "complete")` | | Rate from incomplete trips | `estimate_catch_rate(design, use_trips = "incomplete", estimator = "mor")` | | Change the short-trip cutoff | `truncate_at = ` (default 0.5) | | Compare the two | `estimate_catch_rate(design, use_trips = "diagnostic")` | | Test that they agree | `validate_incomplete_trips(design, catch = , effort = )` | ## References - Hoenig, J. M., Jones, C. M., Pollock, K. H., Robson, D. S., and Wade, D. L. (1997). Calculation of catch rate and total catch in roving surveys of anglers. *Biometrics*, 53, 306–317. - Pollock, K. H., Jones, C. M., and Brown, T. L. (1994). *Angler Survey Methods and Their Applications in Fisheries Management*. American Fisheries Society Special Publication 25. Bethesda, Maryland. - Schuirmann, D. J. (1987). A comparison of the two one-sided tests procedure and the power approach for assessing the equivalence of average bioavailability. *Journal of Pharmacokinetics and Biopharmaceutics*, 15, 657–680.