fishR-Core-Team / FSA

FSA (Fisheries Stock Assessment) package provides R functions to conduct typical introductory fisheries analyses.
https://fishr-core-team.github.io/FSA/
GNU General Public License v2.0
65 stars 20 forks source link

`addZeroCatch` unexpected behavior #61

Closed cmichaud92 closed 4 years ago

cmichaud92 commented 4 years ago

I have a dataframe which includes two vars: SpeciesCode (2 letter abbr. convenient for subsetting) and Common Name (used for visualizations). addZeroCatch works fine when only SpeciesCode OR CommonName are present in the dataframe (cpue below), however, when both are present the function returns additional rows unexpectedly (cpue1)

I am probably missing something fundamental here. I appreciate your thoughts

library(tibble)
library(dplyr)
library(FSA)

fish <- tribble(
    ~SampleNumber, ~SpeciesCode, ~CommonName, ~TotalLength, ~ElSeconds,
    "a1", "SM", "smallmouth bass", 100, 1000,
    "a1", "LG", "largemouth bass", 480, 1000,
    "a1", "SM", "smallmouth bass", 256, 1000,
    "a1", "BC", "black crappie", 176, 1000,
    "a1", "SM", "smallmouth bass", 378, 1000,
    "a1", "BB", "black bulhead", 250, 1000,
    "a1", "SM", "smallmouth bass", 145, 1000,
    "a2", "SM", "smallmouth bass", 100, 2000,
    "a2", "LG", "largemouth bass", 480, 2000,
    "a2", "SM", "smallmouth bass", 256, 2000,
    "a2", "BC", "black crappie", 176, 2000,
    "a2", "SM", "smallmouth bass", 378, 2000,
    "a2", "BB", "black bulhead", 250, 2000,
    "a2", "SM", "smallmouth bass", 145, 2000,
    "a3", "SM", "smallmouth bass", 145, 200,
    "a3", "WE", "walleye", 1145, 200
)

cpue <- fish %>% 
    group_by(SampleNumber, SpeciesCode, ElSeconds) %>% 
    summarise(FishCount = n(),
              .groups = "drop") %>% 
    addZeroCatch(eventvar = "SampleNumber", specvar = "SpeciesCode", zerovar = "FishCount")

cpue1 <- fish %>% 
    group_by(SampleNumber, SpeciesCode, CommonName, ElSeconds) %>% 
    summarise(FishCount = n(),
              .groups = "drop") %>% 
    addZeroCatch(eventvar = "SampleNumber", specvar = "SpeciesCode", zerovar = "FishCount")
droglenc commented 4 years ago

Christopher,

This is definitely an issue with addZeroCatch(). I have been considering dropping this function from FSA because it is a hacky fix to an important problem. I think the fix to this problem is better corrected using complete() from tidyr. For example, below does, I think, what you want ...

cpue2 <- fish %>% 
  group_by(SampleNumber, SpeciesCode, CommonName, ElSeconds) %>% 
  summarise(FishCount = n(),
            .groups = "drop") %>% 
  complete(nesting(SampleNumber,ElSeconds),
           nesting(SpeciesCode,CommonName),
           fill=list(FishCount=0))
cpue2

The first argument basically acts like eventvar= from addZeroCatch(),but you can use nesting() to bring other variables along as well (e.g., ElSeconds here). The second argument is basically specvar= but again can use nesting() to bring other variables along (which is what solves the issue you raised). The fill= argument is basically zerovar= but you must be specific about adding the zero because complete() defaults to adding an NA.

I posted on this briefly a couple of years ago. It may help some. I think complete() takes a bit to figure out but ultimately I think it provides a more general, less hacky, betters supported method to better perform what addZeroCatch() was intended for.

Sorry for the troubles, Thank you for your note and your well formed issue report and MRE!!

cmichaud92 commented 4 years ago

Derek, I appreciate the quick response and the work around! complete() works like a charm.

I have been using R to fetch data from a SQL server instance and have been looking for a tool to "add zero catch" to large datasets (several hundred thousand fish across tens of thousands of samples). I'm hoping this function might provide this functionality. Ideally, I'd like to push this operation into the database its self, being a tidyverse function there is potential. I'll let you know how it turns out.

Thanks

droglenc commented 4 years ago

Christopher, Good. Thanks.