diff --git a/R/prepare_wham_input.R b/R/prepare_wham_input.R index ec3b158b..335785c2 100644 --- a/R/prepare_wham_input.R +++ b/R/prepare_wham_input.R @@ -146,7 +146,7 @@ #' \item{\code{"dir-mult"}}{Dirichlet-multinomial. Effective sample size is estimated by the model (\href{https://www.sciencedirect.com/science/article/abs/pii/S0165783616301941}{Thorson et al. 2017}; \href{https://www.sciencedirect.com/science/article/abs/pii/S016578361830033X}{Thorson 2019}). 1 parameter.} #' \item{\code{"dirichlet"}}{See \href{https://www.sciencedirect.com/science/article/abs/pii/S0165783613003093}{Francis 2014} and \href{https://cdnsciencepub.com/doi/abs/10.1139/cjfas-2015-0532}{Albertsen et al. 2016}. 1 parameter.} #' \item{\code{"logistic-normal-01-infl"}}{Zero-or-one inflated logistic normal. Inspired by zero-one inflated beta in \href{https://www.sciencedirect.com/science/article/abs/pii/S0167947311003628}{Ospina and Ferrari (2012)}. 3 parameters.} -#' \item{\code{"logistic-normal-pool0"}}{Logistic normal, pooling zero observations with adjacent age classes. 1 parameter. See \href{https://doi.org/10.1093/icesjms/fsl024}{Schnute and Haigh (2007)} and \href{https://doi.org/10.1016/j.fishres.2013.12.015}{Francis (2014)}. +#' \item{\code{"logistic-normal-pool0"}}{Logistic normal, pooling zero observations with adjacent age classes. 1 parameter. See \href{https://doi.org/10.1093/icesjms/fsl024}{Schnute and Haigh (2007)} and \href{https://doi.org/10.1016/j.fishres.2013.12.015}{Francis (2014)}}. #' \item{\code{"logistic-normal-01-infl-2par"}}{Zero-one inflated logistic normal where p0 is a function of binomial sample size. 2 parameters.} #' \item{\code{"logistic-normal-miss0"}}{Logistic normal, treating zero observations as missing. 1 parameter.} #' } diff --git a/docs/articles/ex1_basics.html b/docs/articles/ex1_basics.html index 11efea9d..f18b2dec 100644 --- a/docs/articles/ex1_basics.html +++ b/docs/articles/ex1_basics.html @@ -143,7 +143,7 @@

Ex 1: The basics

  • Fit models and check for convergence

  • -
  • Compare models by AIC and Mohn’s rho (retrospective analysis)

  • +
  • Compare models by AIC and Mohn's rho (retrospective analysis)

  • Review plots of input data, diagnostics, and results.

  • @@ -151,37 +151,37 @@

    1. Load data

    We assume you have already read the Introduction and installed wham and its dependencies. If not, you should be able to just run devtools::install_github("timjmiller/wham", dependencies=TRUE).

    Open R and load the wham package:

    -
    +
     

    For a clean, runnable .R script, look at ex1_basics.R in the example_scripts folder of the wham package install:

    -
    +
     wham.dir <- find.package("wham")
     file.path(wham.dir, "example_scripts")
    -#> [1] "/tmp/RtmpxsYcd5/temp_libpath4c62c90d065/wham/example_scripts"
    +#> [1] "/tmp/RtmpS2yNsx/temp_libpath5e76603d0384/wham/example_scripts"

    You can run this entire example script with (2.0 min runtime):

    -
    +
     write.dir <- "choose/where/to/save/output" # otherwise will be saved in working directory
     source(file.path(wham.dir, "example_scripts", "ex1_basics.R"))
    -

    Let’s create a directory for this analysis:

    -
    +

    Let's create a directory for this analysis:

    +
     # choose a location to save output
     write.dir <- "/path/to/save/output" # modify
     dir.create(write.dir)
     setwd(write.dir)

    WHAM was built by modifying the ADMB-based ASAP model code (Legault and Restrepo 1999), and is designed to take an ASAP3 .dat file as input. We generally assume in wham that you have an existing ASAP3 .dat file. If you are not familiar with ASAP3 input files, see the ASAP documentation. For this vignette, an example ASAP3 input file is provided.

    Copy ex1_SNEMAYT.dat to our analysis directory:

    -
    +
     wham.dir <- find.package("wham")
     file.copy(from=file.path(wham.dir,"extdata","ex1_SNEMAYT.dat"), to=write.dir, overwrite=FALSE)

    Confirm you are in the working directory and it has the ex1_SNEMAYT.dat file:

    -
    +
     list.files()
     #>  [1] "CPI.csv"                "ex1_SNEMAYT.dat"        "ex1_test_results.rds"  
     #>  [4] "ex2_SNEMAYT.dat"        "ex2_test_results.rds"   "ex4_test_results.rds"  
     #>  [7] "ex5_summerflounder.dat" "ex5_test_results.rds"   "ex6_test_results.rds"  
     #> [10] "ex7_SNEMAYT.dat"        "GSI.csv"

    Read the ASAP3 .dat file into R:

    -
    +
     asap3 <- read_asap3_dat("ex1_SNEMAYT.dat")
    @@ -193,7 +193,7 @@

  • recruitment deviations: independent random effects (NAA_re = list(sigma="rec", cor="iid"))
  • selectivity: age-specific (fix sel=1 for age 5 in fishery, age 4 in index1, and age 2 in index2)
  • -
    +
     input1 <- prepare_wham_input(asap3, recruit_model=2, model_name="Ex 1: SNEMA Yellowtail Flounder",
                                   selectivity=list(model=rep("age-specific",3), 
                                       re=rep("none",3), 
    @@ -212,11 +212,11 @@ 

    3. Fit model and check for convergence

    -
    +
     m1 <- fit_wham(input1, do.osa = F) # turn off OSA residuals to save time in ex

    By default, fit_wham() uses 3 extra Newton steps to reduce the absolute value of the gradient (n.newton = 3) and estimates standard errors for derived parameters (do.sdrep = TRUE). fit_wham() also does a retrospective analysis with 7 peels by default (do.retro = TRUE, n.peels = 7). For more details, see fit_wham().

    -

    We need to check that m1 converged (m1$opt$convergence should be 0, and the maximum absolute value of the gradient vector should be < 1e-06). Convergence issues may indicate that a model is misspecified or overparameterized. To help diagnose these problems, fit_wham() includes a do.check option to run Jim Thorson’s useful function TMBhelper::Check_Identifiable(). do.check = FALSE by default. To turn on, set do.check = TRUE. See fit_wham().

    -
    +

    We need to check that m1 converged (m1$opt$convergence should be 0, and the maximum absolute value of the gradient vector should be < 1e-06). Convergence issues may indicate that a model is misspecified or overparameterized. To help diagnose these problems, fit_wham() includes a do.check option to run Jim Thorson's useful function TMBhelper::Check_Identifiable(). do.check = FALSE by default. To turn on, set do.check = TRUE. See fit_wham().

    +
    #> stats:nlminb thinks the model has converged: mod$opt$convergence == 0
     #> Maximum gradient component: 1.20e-07 
    @@ -227,7 +227,7 @@ 

    Fit models m2-m4

    The second model, m2, is like the first, but changes all the age composition likelihoods from multinomial to logistic normal (treating 0 observations as missing):

    -
    +
     input2 <- prepare_wham_input(asap3, recruit_model=2, model_name="Ex 1: SNEMA Yellowtail Flounder",
                                         selectivity=list(model=rep("age-specific",3), 
                                             re=rep("none",3), 
    @@ -237,14 +237,14 @@ 

    age_comp = "logistic-normal-miss0") m2 <- fit_wham(input2, do.osa = F) # turn off OSA residuals to save time in ex

    Check that m2 converged:

    -
    +
     
    #> stats:nlminb thinks the model has converged: mod$opt$convergence == 0
     #> Maximum gradient component: 4.96e-12 
     #> Max gradient parameter: logit_selpars 
     #> TMB:sdreport() was performed successfully for this model

    The third, m3, is a full state-space model where numbers at all ages are random effects (NAA_re$sigma = "rec+1"):

    -
    +
     input3 <- prepare_wham_input(asap3, recruit_model=2, model_name="Ex 1: SNEMA Yellowtail Flounder",
                                   selectivity=list(model=rep("age-specific",3), 
                                       re=rep("none",3), 
    @@ -253,14 +253,14 @@ 

    NAA_re = list(sigma="rec+1", cor="iid")) m3 <- fit_wham(input3, do.osa = F) # turn off OSA residuals to save time in ex

    Check that m3 converged:

    -
    +
     
    #> stats:nlminb thinks the model has converged: mod$opt$convergence == 0
     #> Maximum gradient component: 2.67e-06 
     #> Max gradient parameter: log_F1 
     #> TMB:sdreport() was performed successfully for this model

    The last, m4, is like m3, but again changes all the age composition likelihoods to logistic normal:

    -
    +
     input4 <- prepare_wham_input(asap3, recruit_model=2, model_name="Ex 1: SNEMA Yellowtail Flounder",
                                         selectivity=list(model=rep("age-specific",3), 
                                             re=rep("none",3), 
    @@ -270,40 +270,40 @@ 

    age_comp = "logistic-normal-miss0") m4 <- fit_wham(input4, do.osa = F) # turn off OSA residuals to save time in ex

    Check that m4 converged:

    -
    +
     
    #> stats:nlminb thinks the model has converged: mod$opt$convergence == 0
     #> Maximum gradient component: 2.32e-07 
     #> Max gradient parameter: log_F1 
     #> TMB:sdreport() was performed successfully for this model

    Store all models together in one (named) list:

    -
    +
     mods <- list(m1=m1, m2=m2, m3=m3, m4=m4)

    Since the retrospective analyses take a few minutes to run, you may want to save the output for later use:

    -
    +
     save("mods", file="ex1_models.RData")

    4. Compare models

    -

    We can compare models using AIC and Mohn’s rho:

    -
    +

    We can compare models using AIC and Mohn's rho:

    +
     res <- compare_wham_models(mods, fname="model_comparison", sort=TRUE)
    #>      dAIC     AIC  rho_R rho_SSB rho_Fbar
     #> m4    0.0 -1475.5 0.2918  0.0240  -0.0247
     #> m2  302.8 -1172.7 3.1666 -0.0708   0.1510
     #> m3 5575.9  4100.4 0.1124  0.0056  -0.0056
     #> m1 6322.0  4846.5 0.8207  0.1905  -0.1748
    -
    +
     res$best
    #> [1] "m4"

    By default, compare_wham_models() sorts the model comparison table with lowest (best) AIC at the top, and saves it as model_comparison.csv. However, in this example the models with alternative likelihoods for the age composition observations are not comparable due to differences in how the observations are defined. Still, the models that treat the age composition observations in the same way can be compared to evaluate whether stochasticity in abundances at age provides better performance, i.e. m1 vs. m3 (both multinomial) and m2 vs. m4 (both logistic normal).

    Project the best model

    -

    Let’s do projections for the best model, m4, using the default settings (see project_wham()):

    -
    +

    Let's do projections for the best model, m4, using the default settings (see project_wham()):

    +
     m4_proj <- project_wham(model=m4)
    @@ -311,15 +311,15 @@

    5. Plot input data, diagnostics, and results

    There are 3 options for plotting WHAM output. The default (out.type='html') creates and opens an HTML file with plots organized into tabs (code modified from r4ss::SS_html()):

    -
    +
     plot_wham_output(mod=m4_proj, out.type='html')
    Example HTML file created by plot_wham_output(mod=m4, out.type='html').

    Example HTML file created by plot_wham_output(mod=m4, out.type='html').

    Setting out.type='pdf' saves the plots organized into 6 .pdf files corresponding to the tabs in the .html file (Diagnostics, Input Data, Results, Reference Points, Retrospective, and Misc). Setting out.type='png' saves the plots as .png files organized into 6 subdirectories.

    -
    +
     plot_wham_output(mod=m4_proj, out.type='png')
    -

    Many plots are generated—here we display some examples:

    +

    Many plots are generated---here we display some examples:

    Diagnostics

    @@ -347,7 +347,7 @@

    Retrospective

    -

    SSB with 7 peelsMohn’s rho (SSB) with 7 peels

    +

    SSB with 7 peelsMohn's rho (SSB) with 7 peels

    diff --git a/docs/articles/ex2_CPI_recruitment.html b/docs/articles/ex2_CPI_recruitment.html index db947c10..b1f0d33c 100644 --- a/docs/articles/ex2_CPI_recruitment.html +++ b/docs/articles/ex2_CPI_recruitment.html @@ -138,49 +138,49 @@

    Ex 2: Recruitment linked to an environmental covariate (Cold P
  • environmental covariate (Cold Pool Index, CPI) process models (random walk, AR1), and

  • how the CPI affects recruitment (controlling or limiting)

  • -

    As in example 1, we check that each model converges (check_convergence()), plot diagnostics, results, and reference points (plot_wham_output()), and compare models using AIC and Mohn’s rho (compare_wham_models()).

    +

    As in example 1, we check that each model converges (check_convergence()), plot diagnostics, results, and reference points (plot_wham_output()), and compare models using AIC and Mohn's rho (compare_wham_models()).

    1. Prepare wham

    Open R and load the wham package:

    -
    +
     

    For a clean, runnable .R script, look at ex2_CPI_recruitment.R in the example_scripts folder of the wham package install:

    -
    +
     wham.dir <- find.package("wham")
     file.path(wham.dir, "example_scripts")

    You can run this entire example script with:

    -
    +
     write.dir <- "choose/where/to/save/output" # otherwise will be saved in working directory
     source(file.path(wham.dir, "example_scripts", "ex2_CPI_recruitment.R"))
    -

    Let’s create a directory for this analysis:

    -
    +

    Let's create a directory for this analysis:

    +
     # choose a location to save output, otherwise will be saved in working directory
     write.dir <- "choose/where/to/save/output"
     dir.create(write.dir)
     setwd(write.dir)

    WHAM was built by modifying the ADMB-based ASAP model code (Legault and Restrepo 1999), and is designed to take an ASAP3 .dat file as input. We generally assume in wham that you have an existing ASAP3 .dat file. If you are not familiar with ASAP3 input files, see the ASAP documentation. For this vignette, an example ASAP3 input file is provided, ex2_SNEMAYT.dat. We will also need a data file with an environmental covariate, the Cold Pool Index, CPI.csv.

    Copy ex2_SNEMAYT.dat and CPI.csv to our analysis directory:

    -
    +
     wham.dir <- find.package("wham")
     file.copy(from=file.path(wham.dir,"extdata","ex2_SNEMAYT.dat"), to=write.dir, overwrite=FALSE)
     file.copy(from=file.path(wham.dir,"extdata","CPI.csv"), to=write.dir, overwrite=FALSE)

    Confirm you are in the correct directory and it has the required data files:

    -
    +
     list.files()
     #>  [1] "CPI.csv"                "ex1_SNEMAYT.dat"        "ex1_test_results.rds"  
     #>  [4] "ex2_SNEMAYT.dat"        "ex2_test_results.rds"   "ex4_test_results.rds"  
     #>  [7] "ex5_summerflounder.dat" "ex5_test_results.rds"   "ex6_test_results.rds"  
     #> [10] "ex7_SNEMAYT.dat"        "GSI.csv"

    Read the ASAP3 .dat file into R and convert to input list for wham:

    -
    +
     asap3 <- read_asap3_dat("ex2_SNEMAYT.dat")

    Load the environmental covariate (Cold Pool Index, CPI) data into R:

    -
    +
     env.dat <- read.csv("CPI.csv", header=T)
    -

    We generally abbreviate ‘environmental covariate’ as ecov in the code. In this example, the ecov data file has columns for observations (CPI), standard error (CPI_sigma), and year (Year). Observations and year are always required. Standard error can be treated as fixed/data with yearly values (as here) or one overall value shared among years. It can also be estimated as a parameter(s), likewise either as yearly values or one overall value.

    -
    +

    We generally abbreviate 'environmental covariate' as ecov in the code. In this example, the ecov data file has columns for observations (CPI), standard error (CPI_sigma), and year (Year). Observations and year are always required. Standard error can be treated as fixed/data with yearly values (as here) or one overall value shared among years. It can also be estimated as a parameter(s), likewise either as yearly values or one overall value.

    +
     head(env.dat)
     #>   Year     CPI CPI_sigma
     #> 1 1973  0.5988    0.2838
    @@ -194,7 +194,7 @@ 

    2. Specify models

    Now we specify how the 7 models treat recruitment, the CPI process, and how the CPI affects recruitment:

    -
    +
     df.mods <- data.frame(Recruitment = c(2,2,3,3,3,3,4),
                           ecov_process = c(rep("rw",4),rep("ar1",3)),
                           ecov_how = c(0,1,0,2,2,1,1), stringsAsFactors=FALSE)
    @@ -202,7 +202,7 @@ 

    df.mods$Model <- paste0("m",1:n.mods) df.mods <- dplyr::select(df.mods, Model, tidyselect::everything()) # moves Model to first col

    Look at the model table

    -
    +
     df.mods
     #>   Model Recruitment ecov_process ecov_how
     #> 1    m1           2           rw        0
    @@ -220,7 +220,7 @@ 

  • Ricker.
  • The environmental covariate options are fed to prepare_wham_input() as a list, ecov:

    -
    +
       m=1 # example for first model
       ecov <- list(
         label = "CPI",
    @@ -234,23 +234,23 @@ 

    how = df.mods$ecov_how[m]) # 0 = no effect, 1 = controlling, 2 = limiting

    There are currently 2 options for the ecov process model (ecov$process_model): 1) random walk ('rw'), and 2) autoregressive ('ar1'). We must next specify where the ecov affects the population; here it is via recruitment (ecov$where = "recruit") as opposed to another process like catchability, mortality, maturity, etc. The options for how the ecov affects recruitment (ecov$how) follow Iles and Beverton (1998) and Xu et al. (2018):

      -
    1. “controlling” (dens-indep mortality),
    2. -
    3. “limiting” (carrying capacity, e.g. ecov determines amount of suitable habitat),
    4. -
    5. “lethal” (threshold, i.e. R –> 0 at some ecov value),
      +
    6. "controlling" (dens-indep mortality),
    7. +
    8. "limiting" (carrying capacity, e.g. ecov determines amount of suitable habitat),
    9. +
    10. "lethal" (threshold, i.e. R --> 0 at some ecov value),
    11. -
    12. “masking” (metabolic/growth, ecov decreases dR/dS), and
    13. -
    14. “directive” (e.g. behavioral).
    15. +
    16. "masking" (metabolic/growth, ecov decreases dR/dS), and
    17. +
    18. "directive" (e.g. behavioral).
    -

    Finally, we specify the lag at which CPI affects recruitment (ecov$lag = 1, i.e. CPI in year t affects recruitment in year t + 1).

    +

    Finally, we specify the lag at which CPI affects recruitment (ecov$lag = 1, i.e. CPI in year t affects recruitment in year t + 1).

    You can set ecov = NULL to fit the model without environmental covariate data, but note that here we fit the ecov data even for models without an ecov effect on recruitment (m1 and m3) so that we can compare them via AIC (need to have the same data in the likelihood). We accomplish this by setting ecov$how = 0.

    Options are described in the prepare_wham_input() help page. Not all ecov$how options are implemented for every recruitment model.

    -
    +
     ?prepare_wham_input

    3. Run the models

    -
    +
     for(m in 1:n.mods){
       # set up environmental covariate data and model options
       ecov <- list(
    @@ -293,11 +293,11 @@ 

    4. Check for convergence

    Collect all models into a list.

    -
    +
     mod.list <- paste0(df.mods$Model,".rds")
     mods <- lapply(mod.list, readRDS)

    There is no indication that any of the models failed to converge. In addition, SE estimates are calculable for all models (invertible Hessian, TMB::sdreport() succeeds).

    -
    +
     vign2_conv <- lapply(mods, function(x) capture.output(check_convergence(x)))
     for(m in 1:n.mods) cat(paste0("Model ",m,":"), vign2_conv[[m]], "", sep='\n')
    #> Model 1:
    @@ -345,12 +345,12 @@ 

    5. Compare models

    -

    Calculate AIC and Mohn’s rho using compare_wham_models().

    -
    +

    Calculate AIC and Mohn's rho using compare_wham_models().

    +
     df.aic <- compare_wham_models(mods, sort=FALSE)$tab # can't sort yet bc going to make labels prettier
     df.mods <- cbind(df.mods, df.aic)

    Print and save the results table. m6 has the lowest AIC (Bev-Holt recruitment, CPI modeled as AR1, controlling effect of CPI on recruitment).

    -
    +
     # make results table prettier
     rownames(df.mods) <- NULL
     df.mods$Recruitment <- dplyr::recode(df.mods$Recruitment, `2`='Random', `3`='Bev-Holt', `4`='Ricker')
    @@ -381,7 +381,7 @@ 

    6. Results

    There are 3 options for plotting WHAM output. The default (out.type='html') creates and opens an HTML file with plots organized into tabs (code modified from r4ss::SS_html()):

    -
    +
     # save output plots in subfolder for each model
     for(m in 1:n.mods) plot_wham_output(mod=mods[[m]], dir.main=file.path(getwd(), df.mods$Model[m]), out.type='html')
    diff --git a/docs/articles/ex3_projections.html b/docs/articles/ex3_projections.html index fe95e4a2..3e2f03e5 100644 --- a/docs/articles/ex3_projections.html +++ b/docs/articles/ex3_projections.html @@ -137,7 +137,7 @@

    Ex 3: Projecting / forecasting random effects

  • logistic normal age compositions (input$data$age_comp_model_fleets = 5 and input$data$age_comp_model_indices = 5)

  • Beverton-Holt recruitment (recruit_model = 3)

  • Cold Pool Index (CPI) fit as an AR1 process (ecov$process_model = "ar1")

  • -
  • CPI has a “controlling” (density-independent mortality, Iles and Beverton (1998)) effect on recruitment (ecov$where = "recruit", ecov$how = 1)

  • +
  • CPI has a "controlling" (density-independent mortality, Iles and Beverton (1998)) effect on recruitment (ecov$where = "recruit", ecov$how = 1)

  • In example 3, we demonstrate how to project/forecast WHAM models using the project_wham() function options for handling

      @@ -148,39 +148,39 @@

      Ex 3: Projecting / forecasting random effects

      1. Load data

      Open R and load the wham package:

      -
      +
       

      For a clean, runnable .R script, look at ex3_projections.R in the example_scripts folder of the wham package install:

      -
      +
       wham.dir <- find.package("wham")
       file.path(wham.dir, "example_scripts")

      You can run this entire example script with:

      -
      +
       write.dir <- "choose/where/to/save/output" # otherwise will be saved in working directory
       source(file.path(wham.dir, "example_scripts", "ex3_projections.R"))
      -

      Let’s create a directory for this analysis:

      -
      +

      Let's create a directory for this analysis:

      +
       # choose a location to save output, otherwise will be saved in working directory
       write.dir <- "choose/where/to/save/output"
       dir.create(write.dir)
       setwd(write.dir)
      -

      We need the same data files as in example 2. Let’s copy ex2_SNEMAYT.dat and CPI.csv to our analysis directory:

      -
      +

      We need the same data files as in example 2. Let's copy ex2_SNEMAYT.dat and CPI.csv to our analysis directory:

      +
       wham.dir <- find.package("wham")
       file.copy(from=file.path(wham.dir,"extdata","ex2_SNEMAYT.dat"), to=write.dir, overwrite=FALSE)
       file.copy(from=file.path(wham.dir,"extdata","CPI.csv"), to=write.dir, overwrite=FALSE)

      Confirm you are in the correct directory and it has the required data files:

      -
      +
       list.files()
       #>  [1] "CPI.csv"                "ex1_SNEMAYT.dat"        "ex1_test_results.rds"  
       #>  [4] "ex2_SNEMAYT.dat"        "ex2_test_results.rds"   "ex4_test_results.rds"  
       #>  [7] "ex5_summerflounder.dat" "ex5_test_results.rds"   "ex6_test_results.rds"  
       #> [10] "ex7_SNEMAYT.dat"        "GSI.csv"

      Read the ASAP3 .dat file into R and convert to input list for wham:

      -
      +
       asap3 <- read_asap3_dat("ex2_SNEMAYT.dat")

      Load the environmental covariate (Cold Pool Index, CPI) data into R:

      -
      +
       env.dat <- read.csv("CPI.csv", header=T)
      @@ -192,9 +192,9 @@

    • logistic normal age compositions (input$data$age_comp_model_fleets = 5 and input$data$age_comp_model_indices = 5)

    • Beverton-Holt recruitment (recruit_model = 3)

    • Cold Pool Index (CPI) fit as an AR1 process (ecov$process_model = "ar1")

    • -
    • CPI has a “controlling” (density-independent mortality, Iles and Beverton (1998)) effect on recruitment (ecov$where = "recruit", ecov$how = 1)

    • +
    • CPI has a "controlling" (density-independent mortality, Iles and Beverton (1998)) effect on recruitment (ecov$where = "recruit", ecov$how = 1)

    -
    +
     env <- list(
       label = "CPI",
       mean = as.matrix(env.dat$CPI), # CPI observations
    @@ -224,18 +224,18 @@ 

    1. Fit model without projections and then add projections afterward
    -
    +
     # don't run
     mod <- fit_wham(input) # default do.proj=FALSE
     mod_proj <- project_wham(mod)
    1. Add projections with initial model fit (do.proj = TRUE)
    -
    +
     # don't run
     mod_proj <- fit_wham(input, do.proj = TRUE)

    The two code blocks above are equivalent; when do.proj = TRUE, fit_wham() fits the model without projections and then calls project_wham() to add them. In this example we choose option #1 because we are going to add several different projections to the same model, mod. We will save each projected model in a list, mod_proj.

    -
    +
     # run
     mod <- fit_wham(input)
     saveRDS(mod, file="m6.rds") # save unprojected model
    @@ -244,7 +244,7 @@

    4. Add projections to fit model

    Projection options are specifed using the proj.opts input to project_wham(). The default settings are to project 3 years (n.yrs = 3), use average maturity-, weight-, and natural mortality-at-age from last 5 model years to calculate reference points (avg.yrs), use fishing mortality in the last model year (use.last.F = TRUE), and continue the ecov process model (cont.ecov = TRUE). These options are also described in the project_wham() help page.

    -
    +
      # save projected models in a list
     mod_proj <- list()
     
    @@ -257,13 +257,13 @@ 

    # mod_proj[[1]] <- project_wham(mod)

    WHAM implements four options for handling the environmental covariate(s) in the projections. Exactly one of these must be specified in proj.opts if ecov is in the model:

      -
    • (Default) Continue the ecov process model (e.g. random walk, AR1). Set cont.ecov = TRUE. WHAM will estimate the ecov process in the projection years (i.e. continue the random walk / AR1 process).

    • +
    • (Default) Continue the ecov process model (e.g. random walk, AR1). Set cont.ecov = TRUE. WHAM will estimate the ecov process in the projection years (i.e. continue the random walk / AR1 process).

    • Use last year ecov. Set use.last.ecov = TRUE. WHAM will use ecov value from the terminal year of the population model for projections.

    • Use average ecov. Provide avg.yrs.ecov, a vector specifying which years to average over the environmental covariate(s) for projections.

    • Specify ecov. Provide proj.ecov, a matrix of user-specified environmental covariate(s) to use for projections. Dimensions must be the number of projection years (proj.opts$n.yrs) x the number of ecovs (ncols(ecov$mean)).

    Note that for all options, if the original model fit the ecov in years beyond the population model, WHAM will use these already-fit ecov values for the projections. If the ecov model extended at least proj.opts$n.yrs years beyond the population model, then none of the above need be specified.

    -
    +
     # 5 years, use average ecov from 1992-1996
     mod_proj[[2]] <- project_wham(mod, proj.opts=list(n.yrs=5, use.last.F=TRUE, use.avg.F=FALSE,
                   use.FXSPR=FALSE, proj.F=NULL, proj.catch=NULL, avg.yrs=NULL,
    @@ -305,7 +305,7 @@ 

  • Specify F. Provide proj.F, an F vector with length = proj.opts$n.yrs.

  • Specify catch. Provide proj.catch, a vector of aggregate catch with length = proj.opts$n.yrs. WHAM will calculate F across fleets to apply the specified catch.

  • -
    +
     # 5 years, specify catch
     mod_proj[[6]] <- project_wham(mod, proj.opts=list(n.yrs=5, use.last.F=FALSE, use.avg.F=FALSE,
                   use.FXSPR=FALSE, proj.F=NULL, proj.catch=c(10, 2000, 1000, 3000, 20), avg.yrs=NULL,
    @@ -341,29 +341,29 @@ 

    # equivalent # mod_proj[[10]] <- project_wham(mod, proj.opts=list(n.yrs=10, use.avg.F=TRUE, avg.yrs=1992:1996))

    Save projected models

    -
    +
     saveRDS(mod_proj, file="m6_proj.rds")

    5. Compare projections

    Projecting the model differently should not have changed the marginal negative log-likelihood! Confirm that the NLL is the same for all projected models (within 1e-06).

    -
    +
     mod$opt$obj # original model NLL
    #> [1] -829.6624
     #> attr(,"logarithm")
     #> [1] TRUE
    -
    +
     nll_proj <-  sapply(mod_proj, function(x) x$opt$obj) # projected models NLL
     round(nll_proj - mod$opt$obj, 6) # difference between original and projected models' NLL
    #>  [1] 0 0 0 0 0 0 0 0 0 0
    -

    Now let’s plot results from each of the projected models.

    -
    +

    Now let's plot results from each of the projected models.

    +
     for(m in 1:length(mod_proj)){
       plot_wham_output(mod_proj[[m]], dir.main=file.path(getwd(),paste0("proj_",m)), out.type='html')
     }

    To more easily compare the same plots for each projection, we can copy the plots into new folders organized by plot type instead of model.

    -
    +
     plots <- c("Ecov_1","F_byfleet","SSB_at_age","SSB_F_trend","SSB_Rec_time","Kobe_status")
     dirs <- file.path(getwd(),plots)
     lapply(as.list(dirs), FUN=dir.create)
    diff --git a/docs/articles/ex4_selectivity.html b/docs/articles/ex4_selectivity.html
    index eb3a7836..2c34d34c 100644
    --- a/docs/articles/ex4_selectivity.html
    +++ b/docs/articles/ex4_selectivity.html
    @@ -153,42 +153,42 @@ 

    Ex 4: Selectivity with time- and age-varying random effects 1. Load data

    Open R and load the wham package:

    -
    +
     

    For a clean, runnable .R script, look at ex4_selectivity.R in the example_scripts folder of the wham package install:

    -
    +
     wham.dir <- find.package("wham")
     file.path(wham.dir, "example_scripts")

    You can run this entire example script with:

    -
    +
     write.dir <- "choose/where/to/save/output" # otherwise will be saved in working directory
     source(file.path(wham.dir, "example_scripts", "ex4_selectivity.R"))
    -

    Let’s create a directory for this analysis:

    -
    +

    Let's create a directory for this analysis:

    +
     # choose a location to save output, otherwise will be saved in working directory
     write.dir <- "choose/where/to/save/output" # need to change
     dir.create(write.dir)
     setwd(write.dir)
    -

    We need the same data files as in example 1. Let’s copy ex1_SNEMAYT.dat to our analysis directory:

    -
    +

    We need the same data files as in example 1. Let's copy ex1_SNEMAYT.dat to our analysis directory:

    +
     wham.dir <- find.package("wham")
     file.copy(from=file.path(wham.dir,"extdata","ex1_SNEMAYT.dat"), to=write.dir, overwrite=FALSE)

    Confirm you are in the correct directory and it has the required data files:

    -
    +
     list.files()
     #>  [1] "CPI.csv"                "ex1_SNEMAYT.dat"        "ex1_test_results.rds"  
     #>  [4] "ex2_SNEMAYT.dat"        "ex2_test_results.rds"   "ex4_test_results.rds"  
     #>  [7] "ex5_summerflounder.dat" "ex5_test_results.rds"   "ex6_test_results.rds"  
     #> [10] "ex7_SNEMAYT.dat"        "GSI.csv"

    Read the ASAP3 .dat file into R and convert to input list for wham:

    -
    +
     asap3 <- read_asap3_dat("ex1_SNEMAYT.dat")

    2. Specify selectivity model options

    We are going to run 9 models that differ only in the selectivity options:

    -
    +
     # m1-m5 logistic, m6-m9 age-specific
     sel_model <- c(rep("logistic",5), rep("age-specific",4))
     
    @@ -226,7 +226,7 @@ 

    3. Setup and run models

    The ASAP data file specifies selectivity options (model, initial parameter values, which parameters to fix/estimate). WHAM uses these by default in order to facilitate running ASAP models. To see the currently specified selectivity options in asap3:

    -
    +
     asap3$dat$sel_block_assign # 1 fleet, all years assigned to block 1
     #> [[1]]
     #>  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
    @@ -288,7 +288,7 @@ 

    Model selectivity$model -No. Parameters +No. Parameters @@ -318,9 +318,9 @@

    Mean selectivity parameters can be initialized at different values from the ASAP file with selectivity$initial_pars. Parameters can be fixed at their initial values by specifying selectivity$fix_pars. Finally, we specify any time-varying (random effects) on selectivity parameters (selectivity$re):

    ---+++ @@ -362,7 +362,7 @@

    selectivity$re

    Now we can run the above models in a loop:

    -
    +
     for(m in 1:n.mods){
         if(sel_model[m] == "logistic"){ # logistic selectivity
             # overwrite initial parameter values in ASAP data file (ex1_SNEMAYT.dat)
    @@ -396,11 +396,11 @@ 

    4. Model convergence and comparison

    Collect all models into a list:

    -
    +
     mod.list <- file.path(write.dir,paste0("m",1:n.mods,".rds"))
     mods <- lapply(mod.list, readRDS)

    Check which models converged. Note that 3 of the 9 models did NOT converge:

    -
    +
     vign4_conv <- lapply(mods, function(x) capture.output(check_convergence(x)))
     for(m in 1:n.mods) cat(paste0("Model ",m,":"), vign4_conv[[m]], "", sep='\n')
    #> Model 1:
    @@ -457,7 +457,7 @@ 

    #> Max gradient parameter: logit_q #> TMB:sdreport() was performed for this model, but it appears hessian was not invertible

    Plot output for models that converged (in a subfolder for each model):

    -
    +
     # Is Hessian positive definite?
     ok_sdrep = sapply(mods, function(x) if(x$na_sdrep==FALSE & !is.na(x$na_sdrep)) 1 else 0)
     pdHess <- as.logical(ok_sdrep)
    @@ -468,7 +468,7 @@ 

    plot_wham_output(mod=mods[[m]], out.type='html', dir.main=file.path(write.dir,paste0("m",m))) }

    Compare the models using AIC:

    -
    +
     df.aic <- as.data.frame(compare_wham_models(mods, sort=FALSE, calc.rho=FALSE)$tab)
     df.aic[!pdHess,] = NA
     minAIC <- min(df.aic$AIC, na.rm=T)
    @@ -502,7 +502,7 @@ 

    #> 8 -1477.5 #> 9 NA

    Prepare to plot selectivity-at-age for block 1 (fleet).

    -
    +
     library(tidyverse)
     library(viridis)
     
    @@ -530,7 +530,7 @@ 

    df$sel_cor <- factor(df$sel_cor, levels=c("None","IID","AR1","AR1_y","2D AR1")) df$conv = factor(df$conv)

    Now plot selectivity-at-age for block 1 (fleet) in all models, with unconverged models pale and converged models solid.

    -
    +
     print(ggplot(df, aes(x=Year, y=Age)) +
         geom_tile(aes(fill=Selectivity, alpha=conv)) +
         scale_alpha_discrete(range=c(0.4,1), guide=FALSE) +
    @@ -541,16 +541,18 @@ 

    theme_bw() + scale_x_continuous(expand=c(0,0)) + scale_y_continuous(expand=c(0,0)))

    -

    +
    + +

    A note on convergence

    When fitting age-specific selectivity, oftentimes some of the (mean, \(\mu^{s}_a\)) selectivity parameters need to be fixed for the model to converge. The specifications used here follow this procedure:

    1. Fit the model without fixing any selectivity parameters.
    2. -
    3. If the model fails to converge or the hessian is not invertible (i.e. not positive definite), look for mean selectivity parameters that are very close to 0 or 1 (> 5 or < -5 on the logit scale) and/or have NaN estimates of their standard error:
    4. +
    5. If the model fails to converge or the hessian is not invertible (i.e. not positive definite), look for mean selectivity parameters that are very close to 0 or 1 (> 5 or < -5 on the logit scale) and/or have NaN estimates of their standard error:
    -
    +
     mod$rep$logit_selpars # mean sel pars
     mod$rep$sel_repars # if time-varying selectivity turned on
     mod$rep$selAA # selectivity-at-age by block
    @@ -558,7 +560,7 @@ 

    1. Re-run the model fixing the worst selectivity-at-age parameter for each block at 0 or 1 as appropriate. In the above age-specific models, we first initialized and fixed ages 4, 4, and 2 for blocks 1-3, respectively. The logit scale selectivity for age 5 and ages 3-4 for blocks 1 and 3 remained around 20, indicating that they too should be fixed at 1. Sometimes just initializing the worst parameter is enough, without fixing it.
    -
    +
             # fix selectivity at 1 for ages 4-5 / 4 / 2-4 in blocks 1-3
             input <- prepare_wham_input(asap3, model_name=paste(paste0("Model ",m), sel_model[m], paste(sel_re[[m]], collapse="-"), sep=": "), recruit_model=2,
                         selectivity=list(model=rep("age-specific",3), re=sel_re[[m]], 
    @@ -568,7 +570,7 @@ 

    1. The goal is to find a set of selectivity parameter initial/fixed values that allow all nested models to converge. Fixing parameters should not affect the NLL much, and any model that is a superset of another should not have a greater NLL (indicates not converged to global minimum). The following commands may be helpful:
    -
    +
     mod.list <- file.path(getwd(),paste0("m",1:n.mods,".rds"))
     mods <- lapply(mod.list, readRDS)
     sapply(mods, function(x) check_convergence(x))
    diff --git a/docs/articles/ex5_GSI_M.html b/docs/articles/ex5_GSI_M.html
    index 12579fe5..3d22b2ad 100644
    --- a/docs/articles/ex5_GSI_M.html
    +++ b/docs/articles/ex5_GSI_M.html
    @@ -156,7 +156,7 @@ 

    Ex 5: Time-varying natural mortality linked to the Gulf Stream
  • 2D AR1 deviations by age and year (random effects), \(M_{y,a} = M_a + \delta_{y,a} \quad\mathrm{and}\quad \delta_{y,a} \sim \mathcal{N}(0,\Sigma)\)
  • -

    We also demonstrate alternate specifications for the link between \(M\) and an environmental covariate, the Gulf Stream Index (GSI), as in O’Leary et al. (2019):

    +

    We also demonstrate alternate specifications for the link between \(M\) and an environmental covariate, the Gulf Stream Index (GSI), as in O'Leary et al. (2019):

    • none
    • linear (in log-space), \(M_{y,a} = e^{\mathrm{log}\mu_M + \beta_1 E_y}\) @@ -169,37 +169,37 @@

      Ex 5: Time-varying natural mortality linked to the Gulf Stream

      1. Load data

      Open R and load the wham package:

      -
      +
       

      For a clean, runnable .R script, look at ex5_M_GSI.R in the example_scripts folder of the wham package install:

      -
      +
       wham.dir <- find.package("wham")
       file.path(wham.dir, "example_scripts")

      You can run this entire example script with:

      -
      +
       write.dir <- "choose/where/to/save/output" # otherwise will be saved in working directory
       source(file.path(wham.dir, "example_scripts", "ex5_M_GSI.R"))
      -

      Let’s create a directory for this analysis:

      -
      +

      Let's create a directory for this analysis:

      +
       # choose a location to save output, otherwise will be saved in working directory
       write.dir <- "choose/where/to/save/output"
       dir.create(write.dir)
       setwd(write.dir)
      -

      We need the same ASAP data file as in example 2, and the environmental covariate (GSI). Let’s copy ex2_SNEMAYT.dat and GSI.csv to our analysis directory:

      -
      +

      We need the same ASAP data file as in example 2, and the environmental covariate (GSI). Let's copy ex2_SNEMAYT.dat and GSI.csv to our analysis directory:

      +
       wham.dir <- find.package("wham")
       file.copy(from=file.path(wham.dir,"extdata","ex2_SNEMAYT.dat"), to=write.dir, overwrite=FALSE)
       file.copy(from=file.path(wham.dir,"extdata","GSI.csv"), to=write.dir, overwrite=FALSE)

      Confirm you are in the correct directory and it has the required data files:

      -
      +
       

      Read the ASAP3 .dat file into R and convert to input list for wham:

      -
      +
       asap3 <- read_asap3_dat("ex2_SNEMAYT.dat")

      Load the environmental covariate (Gulf Stream Index, GSI) data into R:

      -
      +
       env.dat <- read.csv("GSI.csv", header=T)
       head(env.dat)
       #>   year        GSI
      @@ -215,7 +215,7 @@ 

      2. Specify models

      Now we specify several models with different options for natural mortality:

      -
      +
       df.mods <- data.frame(M_model = c(rep("---",3),"age-specific","weight-at-age",rep("constant",6),"age-specific","age-specific",rep("constant",3),"---"),
                             M_re = c(rep("none",6),"ar1_y","2dar1","none","none","2dar1","none","2dar1",rep("ar1_a",3),"2dar1"),
                             Ecov_process = rep("ar1",17),
      @@ -224,7 +224,7 @@ 

      df.mods$Model <- paste0("m",1:n.mods) df.mods <- df.mods %>% select(Model, everything()) # moves Model to first col

      Look at the model table:

      -
      +
       df.mods
       #>    Model       M_model  M_re Ecov_process Ecov_link
       #> 1     m1           ---  none          ar1         0
      @@ -250,20 +250,13 @@ 

      3. Natural mortality options

      Next we specify the options for modeling natural mortality by including an optional list argument, M, to the prepare_wham_input() function (see the prepare_wham_input() help page). M specifies estimation options and can overwrite M-at-age values specified in the ASAP data file. By default (i.e. M is NULL or not included), the M-at-age matrix from the ASAP data file is used (M fixed, not estimated). M is a list with the following entries:

        -
      • -

        $model: Natural mortality model options.

        -
          +
        • $model: Natural mortality model options.

        • "constant": estimate a single \(M\), shared across all ages and years.
        • "age-specific": estimate \(M_a\) independent for each age, shared across years.
        • -
        • -"weight-at-age": estimate \(M\) as a function of weight-at-age, \(M_{y,a} = \mu_M * W_{y,a}^b\), as in Lorenzen (1996) and Miller & Hyun (2018).
        • -
        -
      • -
      • -

        $re: Time- and age-varying random effects on \(M\).

        -
          +
        • "weight-at-age": estimate \(M\) as a function of weight-at-age, \(M_{y,a} = \mu_M * W_{y,a}^b\), as in Lorenzen (1996) and Miller & Hyun (2018).

        • +
        • $re: Time- and age-varying random effects on \(M\).

        • "none": \(M\) constant in time and across ages (default).
        • @@ -272,25 +265,22 @@

          "ar1_a": \(M\) correlated by age (AR1), constant in time.

        • "ar1_y": \(M\) correlated by year (AR1), constant by age.
        • -
        • -"2dar1": \(M\) correlated by year and age (2D AR1), as in Cadigan (2016).
        • -
        -
      • +
      • "2dar1": \(M\) correlated by year and age (2D AR1), as in Cadigan (2016).

      • $initial_means: Initial/mean M-at-age vector, with length = number of ages (if $model = "age-specific") or 1 (if $model = "weight-at-age" or "constant"). If NULL, initial mean M-at-age values are taken from the first row of the MAA matrix in the ASAP data file.

      • $est_ages: Vector of ages to estimate age-specific \(M_a\) (others will be fixed at initial values). E.g. in a model with 6 ages, $est_ages = 5:6 will estimate \(M_a\) for the 5th and 6th ages, and fix \(M\) for ages 1-4. If NULL, \(M\) at all ages is fixed at M$initial_means (if not NULL) or row 1 of the MAA matrix from the ASAP file (if M$initial_means = NULL).

      • $logb_prior: (Only for weight-at-age model) TRUE or FALSE (default), should a \(\mathcal{N}(0.305, 0.08)\) prior be used on log_b? Based on Fig. 1 and Table 1 (marine fish) in Lorenzen (1996).

      For example, to fit model m1, fix \(M_a\) at values in ASAP file:

      -
      +
       M <- NULL # or simply leave out of call to prepare_wham_input

      To fit model m6, estimate one \(M\), constant by year and age:

      -
      +
       M <- list(model="constant", est_ages=1)

      And to fit model m8, estimate mean \(M\) with 2D AR1 deviations by year and age:

      -
      +
       M <- list(model="constant", est_ages=1, re="2dar1")

      To fit model m17, use the \(M_a\) values specified in the ASAP file, but with 2D AR1 deviations as in Cadigan (2016):

      -
      +
       M <- list(re="2dar1")
      @@ -310,7 +300,7 @@

      $link_model: specifies the model linking GSI to \(M\). Can be NA (no effect, default), "linear", or "poly-x" (where x is the degree of a polynomial). In this example we demonstrate models with no GSI-M effect, a linear GSI-M effect, and a quadratic GSI-M effect ("poly-2"). WHAM includes a function to calculate orthogonal polynomials in TMB, akin to the poly() function in R.

    For example, the ecov list for model m3 with a quadratic GSI-M effect:

    -
    +
       # example for model m3
       ecov <- list(
         label = "GSI",
    @@ -329,7 +319,7 @@ 

    5. Run all models

    All models use the same options for recruitment (random-about-mean, no stock-recruit function) and selectivity (logistic, with parameters fixed for indices 4 and 5).

    -
    +
     env.dat <- read.csv("GSI.csv", header=T)
     for(m in 1:n.mods){
       ecov <- list(
    @@ -385,11 +375,11 @@ 

    6. Compare models

    Collect all models into a list.

    -
    +
     mod.list <- paste0(df.mods$Model,".rds")
     mods <- lapply(mod.list, readRDS)

    Get model convergence and stats.

    -
    +
     opt_conv = 1-sapply(mods, function(x) x$opt$convergence)
     ok_sdrep = sapply(mods, function(x) if(x$na_sdrep==FALSE & !is.na(x$na_sdrep)) 1 else 0)
     df.mods$conv <- as.logical(opt_conv)
    @@ -397,7 +387,7 @@ 

    df.mods$runtime <- sapply(mods, function(x) x$runtime) df.mods$NLL <- sapply(mods, function(x) round(x$opt$objective,3))

    We have to deal with any NLL being NaN.

    -
    +
     theNA <- which(is.na(df.mods$NLL))
     mods2 <- mods
     mods2[theNA] <- NULL
    @@ -417,13 +407,13 @@ 

    df.aic$dAIC <- round(df.aic$AIC - minAIC,1) df.mods <- cbind(df.mods, df.aic)

    Make results table prettier.

    -
    +
     df.mods$Ecov_link <- c("---","linear","poly-2")[df.mods$Ecov_link+1]
     df.mods$M_re[df.mods$M_re=="none"] = "---"
     colnames(df.mods)[2] = "M_est"
     rownames(df.mods) <- NULL

    Look at results table.

    -
    +
     df.mods
    @@ -487,16 +477,16 @@

    m1 -— +--- -— +--- ar1 -— +--- TRUE @@ -534,10 +524,10 @@

    m2 -— +--- -— +--- ar1 @@ -581,10 +571,10 @@

    m3 -— +--- -— +--- ar1 @@ -631,13 +621,13 @@

    age-specific -— +--- ar1 -— +--- TRUE @@ -678,13 +668,13 @@

    weight-at-age -— +--- ar1 -— +--- TRUE @@ -725,13 +715,13 @@

    constant -— +--- ar1 -— +--- TRUE @@ -778,7 +768,7 @@

    ar1 -— +--- TRUE @@ -825,7 +815,7 @@

    ar1 -— +--- TRUE @@ -866,7 +856,7 @@

    constant -— +--- ar1 @@ -913,7 +903,7 @@

    constant -— +--- ar1 @@ -1007,7 +997,7 @@

    age-specific -— +--- ar1 @@ -1107,7 +1097,7 @@

    ar1 -— +--- TRUE @@ -1239,7 +1229,7 @@

    m17 -— +--- 2dar1 @@ -1248,7 +1238,7 @@

    ar1 -— +--- TRUE @@ -1298,29 +1288,29 @@

    Retrospective patterns

    Compared to m1, the retrospective pattern for m8 was slightly worse for recruitment (m8 0.32, m1 0.23) but improved for SSB (m8 0.01, m1 0.07) and F (m8 -0.05, m1 -0.11). In general, models with GSI effects or 2D AR1 deviations on \(M\) had reduced retrospective patterns compared to the status quo (m1) and models with 1D AR1 random effects on \(M\). Compare the retrospective patterns of numbers-at-age, SSB, and F for models m1 (left, fixed \(M_a\)) and m8 (right, estimated \(M\) + 2D AR1 deviations).

    -

    Mohn’s rho for numbers-at-age, m1.Mohn’s rho for numbers-at-age, m8.

    -

    Mohn’s rho for SSB, m1.Mohn’s rho for SSB, m8.

    -

    Mohn’s rho for F, m1.Mohn’s rho for F, m8.

    +

    Mohn's rho for numbers-at-age, m1.Mohn's rho for numbers-at-age, m8.

    +

    Mohn's rho for SSB, m1.Mohn's rho for SSB, m8.

    +

    Mohn's rho for F, m1.Mohn's rho for F, m8.

    Model m17 had \(\Delta AIC = 1.5\) and the lowest retrospective pattern for all numbers-at-age and F. Model m17 left \(M_a\) fixed at the values from the ASAP data file (as in m1) and estimated 2D AR1 deviations around these mean \(M_a\). This is how \(M\) was modeled in Cadigan (2016).

    -

    Mohn’s rho for SSB, m17.Mohn’s rho for F, m17.

    +

    Mohn's rho for SSB, m17.Mohn's rho for F, m17.

    -Mohn’s rho for recruitment, m17.

    Mohn’s rho for recruitment, m17.

    +Mohn's rho for recruitment, m17.

    Mohn's rho for recruitment, m17.

    Stock status

    -

    Compared to m1 (left), m8 (center) estimated higher M, lower and more uncertain F, and higher SSB – a much rosier picture of the stock status through time. Model m17 (right) is intermediate between m1 and m8.

    +

    Compared to m1 (left), m8 (center) estimated higher M, lower and more uncertain F, and higher SSB -- a much rosier picture of the stock status through time. Model m17 (right) is intermediate between m1 and m8.

    Relative stock status, m1.Relative stock status, m8.Relative stock status, m17.

    Compared to m1 (left), m8 (center) estimated higher and more variable reference points, \(F_{\%SPR}\) (top), and lower and more variable yield-per-recruit (bottom). Model m17 (right) estimated more of a trend in yield-per-recruit and \(F_{\%SPR}\), with a notable shift around 1990.

    Reference point variability, m1.Reference point variability, m8.Reference point variability, m17.

    -

    In the final year (2011), m8 and m17 both estimated much lower probabilities of the stock being overfished than m1 (16% and 21% vs. 98%).

    +

    In the final year (2011), m8 and m17 both estimated much lower probabilities of the stock being overfished than m1 (16% and 21% vs. 98%).

    Kobe status plot, m1.Kobe status plot, m8.Kobe status plot, m17.

    Yet more M options

    -

    If you want to estimate M-at-age shared/mirrored among some but not all ages, you’ll need to modify input$map$M_a after calling prepare_wham_input().

    +

    If you want to estimate M-at-age shared/mirrored among some but not all ages, you'll need to modify input$map$M_a after calling prepare_wham_input().

    diff --git a/docs/articles/ex6_NAA.html b/docs/articles/ex6_NAA.html index 0fdffa87..22b0d320 100644 --- a/docs/articles/ex6_NAA.html +++ b/docs/articles/ex6_NAA.html @@ -144,7 +144,7 @@

    Ex 6: Numbers-at-age / survival deviations as random effects
  • Beverton-Holt recruitment (recruit_model = 3)
  • Environmental covariate (ecov) modeled as an AR1 process (ecov$process_model = 'ar1')
  • -
  • Compare with and w/o ecov having a “limiting” (carrying capacity) effect on recruitment (ecov$how = 2)
  • +
  • Compare with and w/o ecov having a "limiting" (carrying capacity) effect on recruitment (ecov$how = 2)
  • As in example 4:

      @@ -155,7 +155,7 @@

      Ex 6: Numbers-at-age / survival deviations as random effectsEnvironmental covariate: Gulf Stream Index (GSI)
    • 2D AR1 deviations by age and year (random effects)
    -

    Example 6 highlights WHAM’s options for treating the yearly transitions in numbers-at-age (i.e. survival):

    +

    Example 6 highlights WHAM's options for treating the yearly transitions in numbers-at-age (i.e. survival):

    1. Deterministic (as in statistical catch-at-age models, recruitment in each year estimated as independent fixed effect parameters)
    2. Recruitment deviations (from Bev-Holt expectation) are random effects @@ -164,7 +164,7 @@

      Ex 6: Numbers-at-age / survival deviations as random effectsAR1 deviations by year (autocorrelated)

    3. -
    4. “Full state-space model” (survival of all ages are random effects) +
    5. "Full state-space model" (survival of all ages are random effects)
      • independent
      • AR1 deviations by age
      • @@ -177,37 +177,37 @@

        Ex 6: Numbers-at-age / survival deviations as random effects 1. Load data

        Open R and load the wham package:

        -
        +
         # devtools::install_github("timjmiller/wham", dependencies=TRUE)
         library(tidyverse)
         library(wham)

        For a clean, runnable .R script, look at ex6_NAA.R in the example_scripts folder of the wham package install:

        -
        +
         wham.dir <- find.package("wham")
         file.path(wham.dir, "example_scripts")

        You can run this entire example script with (total run time about 12 minutes):

        -
        +
         write.dir <- "choose/where/to/save/output" # otherwise will be saved in working directory
         source(file.path(wham.dir, "example_scripts", "ex6_NAA.R"))
        -

        Let’s create a directory for this analysis:

        -
        +

        Let's create a directory for this analysis:

        +
         # choose a location to save output, otherwise will be saved in working directory
         write.dir <- "choose/where/to/save/output"
         dir.create(write.dir)
         setwd(write.dir)
        -

        We need the same ASAP data file as in example 1, and the environmental covariate (Gulf Stream Index, GSI). Let’s copy ex1_SNEMAYT.dat and GSI.csv to our analysis directory:

        -
        +

        We need the same ASAP data file as in example 1, and the environmental covariate (Gulf Stream Index, GSI). Let's copy ex1_SNEMAYT.dat and GSI.csv to our analysis directory:

        +
         wham.dir <- find.package("wham")
         file.copy(from=file.path(wham.dir,"extdata","ex1_SNEMAYT.dat"), to=write.dir, overwrite=FALSE)
         file.copy(from=file.path(wham.dir,"extdata","GSI.csv"), to=write.dir, overwrite=FALSE)

        Confirm you are in the correct directory and it has the required data files:

        -
        +
         

        Read the ASAP3 .dat file into R and convert to input list for wham:

        -
        +
         asap3 <- read_asap3_dat("ex1_SNEMAYT.dat")

        Load the environmental covariate (Gulf Stream Index, GSI) data into R:

        -
        +
         env.dat <- read.csv("GSI.csv", header=T)
         head(env.dat)
         #>   year        GSI
        @@ -222,8 +222,8 @@ 

        2. Specify models

        -

        Now we specify several models with different options for the numbers-at-age (NAA) transitions, i.e. survival:

        -
        +

        Now we specify several models with different options for the numbers-at-age (NAA) transitions, i.e. survival:

        +
         df.mods <- data.frame(NAA_cor = c('---','iid','ar1_y','iid','ar1_a','ar1_y','2dar1','iid','ar1_y','iid','ar1_a','ar1_y','2dar1'),
                               NAA_sigma = c('---',rep("rec",2),rep("rec+1",4),rep("rec",2),rep("rec+1",4)),
                               GSI_how = c(rep(0,7),rep(2,6)), stringsAsFactors=FALSE)
        @@ -231,7 +231,7 @@ 

        df.mods$Model <- paste0("m",1:n.mods) df.mods <- df.mods %>% select(Model, everything()) # moves Model to first col

        Look at the model table:

        -
        +
         df.mods
         #>    Model NAA_cor NAA_sigma GSI_how
         #> 1     m1     ---       ---       0
        @@ -251,21 +251,17 @@ 

        3. Numbers-at-age options

        -

        To specify the options for modeling NAA transitions, include an optional list argument, NAA_re, to the prepare_wham_input function (see the prepare_wham_input help page). ASAP3 does not estimate random effects, and therefore these options are not specified in the ASAP data file. By default (NAA_re is NULL or not included), WHAM fits a traditional statistical catch-at-age model (NAA = predicted NAA for all ages, i.e. survival is deterministic). To fit a state-space model, we must specify NAA_re.

        +

        To specify the options for modeling NAA transitions, include an optional list argument, NAA_re, to the prepare_wham_input function (see the prepare_wham_input help page). ASAP3 does not estimate random effects, and therefore these options are not specified in the ASAP data file. By default (NAA_re is NULL or not included), WHAM fits a traditional statistical catch-at-age model (NAA = predicted NAA for all ages, i.e. survival is deterministic). To fit a state-space model, we must specify NAA_re.

        NAA_re is a list with the following entries:

        • -$sigma: Which ages allow deviations from pred_NAA? Common options are specified with strings. -
            +$sigma: Which ages allow deviations from pred_NAA? Common options are specified with strings.
          • "rec": Recruitment deviations are random effects, survival of all other ages is deterministic
          • -"rec+1": Survival of all ages is stochastic (“full state space model”), with 2 estimated \(\sigma_a\), one for recruitment and one shared among other ages
          • -
          -
        • +"rec+1": Survival of all ages is stochastic ("full state space model"), with 2 estimated \(\sigma_a\), one for recruitment and one shared among other ages
        • -$cor: Correlation structure for the NAA deviations. Options are: -
            +$cor: Correlation structure for the NAA deviations. Options are:
          • "iid": NAA deviations vary by year and age, but uncorrelated.
          • @@ -275,17 +271,15 @@

          • "2dar1": NAA deviations correlated by year and age (2D AR1, as for \(M\) in example 5).
          -
        • -

        Alternatively, you can specify a more complex NAA_re$sigma by entering a vector with length equal to the number of ages, where each entry points to the \(\sigma_a\) to use for that age. For example, NAA_re$sigma = c(1,2,2,3,3,3) will estimate three \(\sigma_a\), with recruitment (age-1) deviations having their own \(\sigma_R\), ages 2-3 sharing \(\sigma_2\), and ages 4-6 sharing \(\sigma_3\).

        For example, to fit model m1 (SCAA):

        -
        +
         NAA_re <- NULL # or simply leave out of call to prepare_wham_input

        To fit model m3, recruitment deviations are correlated random effects:

        -
        +
         NAA_re <- list(sigma="rec", cor="ar1_y")

        And to fit model m7, numbers at all ages are random effects correlated by year AND age:

        -
        +
         NAA_re <- list(sigma="rec+1", cor="2dar1")
        @@ -296,12 +290,12 @@

      • ecov$logsigma = "est_1" estimates the GSI observation error (\(\sigma_{GSI}\), one overall value for all years). The other option is "est_re" to allow the GSI observation error to have yearly fluctuations (random effects). The Cold Pool Index in example 2 had yearly observation errors given, so this was not necessary.
      • -ecov$how = 0 estimates the GSI time-series model (AR1) for models without a GSI-Recruitment effect, in order to compare AIC with models that do include the effect. Setting ecov$how = 2 specifies that the GSI affects the Beverton-Holt \(\beta\) parameter (“limiting” / carrying capacity effect).
      • +ecov$how = 0 estimates the GSI time-series model (AR1) for models without a GSI-Recruitment effect, in order to compare AIC with models that do include the effect. Setting ecov$how = 2 specifies that the GSI affects the Beverton-Holt \(\beta\) parameter ("limiting" / carrying capacity effect).
      • ecov$link_model = "linear" specifies a linear model linking GSI to \(\beta\).

      For example, the ecov list for models m8-m13 with the linear GSI-\(\beta\) effect:

      -
      +
         # example for model m3
         ecov <- list(
           label = "GSI",
      @@ -320,7 +314,7 @@ 

      5. Run all models

      All models use the same options for expected recruitment (Beverton-Holt stock-recruit function) and selectivity (age-specific, with one or two ages fixed at 1).

      -
      +
       for(m in 1:n.mods){
         NAA_list <- list(cor=df.mods[m,"NAA_cor"], sigma=df.mods[m,"NAA_sigma"])
         if(NAA_list$sigma == '---') NAA_list = NULL
      @@ -362,11 +356,11 @@ 

      6. Compare models

      Collect all models into a list.

      -
      +
       mod.list <- paste0(df.mods$Model,".rds")
       mods <- lapply(mod.list, readRDS)

      Get model convergence and stats.

      -
      +
       opt_conv = 1-sapply(mods, function(x) x$opt$convergence)
       ok_sdrep = sapply(mods, function(x) if(x$na_sdrep==FALSE & !is.na(x$na_sdrep)) 1 else 0)
       df.mods$conv <- as.logical(opt_conv)
      @@ -380,13 +374,13 @@ 

      df.mods <- cbind(df.mods, df.aic) rownames(df.mods) <- NULL

      Look at results table.

      -
      +
       df.mods

      Save results table.

      -
      +
       write.csv(df.mods, file="ex6_table.csv",quote=F, row.names=F)

      Plot output for models that converged.

      -
      +
       conv_mods <- which(df.mods$pdHess)
       mods[[1]]$env$data$recruit_model = 2 # m1 didn't actually fit a Bev-Holt
       for(m in conv_mods){
      @@ -397,7 +391,7 @@ 

      7. Results

      Two models had very similar AIC and were overwhelmingly supported relative to the other models (bold in table below): m11 (all NAA are random effects with correlation by age, GSI-Recruitment effect) and m13 (all NAA are random effects with correlation by age and year, GSI-Recruitment effect).

      -

      The SCAA and state-space models with independent NAA deviations had the lowest runtime. Estimating NAA deviations only for age-1, i.e. recruitment as random effects, broke the Hessian sparseness, making models m2, m3, m8, and m9 the slowest. Adding correlation structure to the NAA deviations increased runtime roughly by a factor of 2 (comparing models m4 with m5-m7 and m10 with m11-m13).

      +

      The SCAA and state-space models with independent NAA deviations had the lowest runtime. Estimating NAA deviations only for age-1, i.e. recruitment as random effects, broke the Hessian sparseness, making models m2, m3, m8, and m9 the slowest. Adding correlation structure to the NAA deviations increased runtime roughly by a factor of 2 (comparing models m4 with m5-m7 and m10 with m11-m13).

      All models converged and successfully inverted the Hessian to produce SE estimates for (fixed effect) parameters. WHAM stores this information in mod$na_sdrep (should be FALSE), mod$sdrep$pdHess (should be TRUE), and mod$opt$convergence (should be 0). See stats::nlminb() and TMB::sdreport() for details.

      We leave the AIC for model m1 blank because comparing models in which parameters (here, recruitment deviations) are estimated as fixed effects versus random effects is messy and marginal AIC is not appropriate. Still, we include m1 to show 1) that WHAM can fit this NAA option, and 2) the poor retrospective pattern in the status quo assessment. Note that m2 is identical to m1 except that recruitment deviations are random effects instead of fixed effects. The retrospective patterns are very similar, but m2 takes 7x longer to run.

      @@ -448,13 +442,13 @@

      m1

      -— +--- -— +--- -— +--- TRUE @@ -469,10 +463,10 @@

      -714.045

      -— +--- -— +--- 5.680 @@ -495,7 +489,7 @@

      rec

      -— +--- TRUE @@ -536,7 +530,7 @@

      rec

      -— +--- TRUE @@ -577,7 +571,7 @@

      rec+1

      -— +--- TRUE @@ -618,7 +612,7 @@

      rec+1

      -— +--- TRUE @@ -659,7 +653,7 @@

      rec+1

      -— +--- TRUE @@ -700,7 +694,7 @@

      rec+1

      -— +--- TRUE @@ -987,13 +981,15 @@

    6. Models with a GSI-Recruitment link also had less extreme recruitment deviations, because the GSI effect on expected recruitment accounted for some of this variability.
    7. Estimated survival deviations by age (y-axis) and year (x-axis) for all converged models:

      -

      +
      + +

      Retrospective patterns

      The base model, m1, had a severe retrospective pattern for recruitment (\(\rho_R\) = 5.68). The full state-space model effectively alleviated this, whether or not a GSI-Recruitment effect was included (\(\rho_R\) for m4-7 and m10-13 all below 0.32). Adding a GSI-Recruitment link to the state-space models further reduced \(\rho_R\), and also reduced \(\rho_{SSB}\) and \(\rho_{\overline{F}}\) (although \(|\rho_{SSB}|\) and \(|\rho_{\overline{F}}|\) were negligible for m4-7, < 0.05).

      -

      Comparing m11 and m13, the models with lowest AIC, m13 had slightly lower Mohn’s \(\rho_R\), \(\rho_{SSB}\), and \(\rho_{\overline{F}}\).

      +

      Comparing m11 and m13, the models with lowest AIC, m13 had slightly lower Mohn's \(\rho_R\), \(\rho_{SSB}\), and \(\rho_{\overline{F}}\).

      The plots below compare retrospective patterns from the base model (m1, left) to those from the full model (m13, right).

      Numbers-at-age, NAA
      diff --git a/docs/articles/ex7_debug.html b/docs/articles/ex7_debug.html index 8a92873b..8578b241 100644 --- a/docs/articles/ex7_debug.html +++ b/docs/articles/ex7_debug.html @@ -131,18 +131,18 @@

      Debugging WHAM models

      In this vignette we show how to use the do.fit = FALSE flag to debug a WHAM model.

      -
      +
       # devtools::install_github("timjmiller/wham", dependencies=TRUE)
       library(wham)

      Load the ASAP3 data file.

      -
      +
       asap3 <- read_asap3_dat("ex7_SNEMAYT.dat")

      Prepare the WHAM model (m3 from example 1).

      -
      +
       input <- prepare_wham_input(asap3, recruit_model=2, model_name="Ex 1: SNEMA Yellowtail Flounder",
                                     NAA_re = list(sigma="rec+1", cor="iid"))
      -

      Try to fit the model… uh oh.

      -
      +

      Try to fit the model... uh oh.

      +
       mod <- fit_wham(input, do.osa = F, do.retro = F)
       #> iter: 1  Error in iterate(par) : 
       #>   Newton dropout because inner gradient had non-finite components.
      @@ -152,14 +152,14 @@ 

      Debugging WHAM models

      #> Newton dropout because inner gradient had non-finite components. #> outer mgc: NaN #> Error in stats::nlminb(model$par, model$fn, model$gr, control = list(iter.max = 1000, : gradient function must return a numeric vector of length 61
      -

      What’s wrong? It looks like the likelihood function is returning NaN. It is often easier to diagnose problems like this using the unoptimized model, i.e. look at everything using the initial parameter values. WHAM includes a do.fit = F flag in fit_wham to return the unoptimized model object returned by TMB::MakeADFun. Let’s see how it works.

      -
      +

      What's wrong? It looks like the likelihood function is returning NaN. It is often easier to diagnose problems like this using the unoptimized model, i.e. look at everything using the initial parameter values. WHAM includes a do.fit = F flag in fit_wham to return the unoptimized model object returned by TMB::MakeADFun. Let's see how it works.

      +
       mod <- fit_wham(input, do.fit = F)

      This runs without an error. The optimization failed because the likelihood was NaN, and now we can see which of the likelihood components was responsible. To do so, we need to look at the REPORTed objects with "nll" in their name. We can use the $report() function from TMB.

      -
      +
       therep = mod$report()

      See all of the REPORTed objects.

      -
      +
       names(therep)
       #>  [1] "NAA"                "Ecov_beta"          "ZAA"               
       #>  [4] "pred_index_paa"     "nll_NAA"            "selAA"             
      @@ -179,16 +179,16 @@ 

      Debugging WHAM models

      #> [46] "log_Y_FXSPR" "SSB" "FAA_tot" #> [49] "nll_agg_catch" "nll" "nll_M"

      Now just get the objects with "nll" in their name, and sum over all individual values.

      -
      +
       sapply(grep("nll",names(therep),value=T), function(x) sum(therep[[x]]))
       #>         nll_NAA nll_index_acomp    nll_Ecov_obs nll_agg_indices        nll_Ecov 
       #>        346.2991       3921.8316          0.0000       1562.8441          0.0000 
       #>         nll_sel nll_catch_acomp   nll_agg_catch             nll           nll_M 
       #>          0.0000       2844.2380             NaN             NaN          0.0000

      The likelihood components that are equal to 0 are not used in the model (no random effects on M, Ecov, selectivity, etc.). nll is the total likelihood and is NaN. The one troublesome component is nll_agg_catch. This is the total (aggregate) catch from the fishery in each year. It could be an issue with the catch data or the model-predicted catch, since both are in the likelihood calculation.

      -

      Search the WHAM .cpp file for “nll_agg_catch”. We find that on line 888, this depends on agg_catch (the catch data) and pred_catch (model-predicted catch).

      +

      Search the WHAM .cpp file for "nll_agg_catch". We find that on line 888, this depends on agg_catch (the catch data) and pred_catch (model-predicted catch).

      The catch data looks ok.

      -
      +
       input$data$agg_catch
       #>             [,1]
       #>  [1,] 14549.0000
      @@ -237,7 +237,7 @@ 

      Debugging WHAM models

      #> [44,] 151.9999

      The predicted catch is calculated on lines 879-880. pred_catch depends on NAA (numbers-at-age), FAA (F at age), ZAA (Z at age), and waa (weight-at-age data).

      NAA looks ok.

      -
      +
       therep$NAA
       #>            [,1]     [,2]     [,3]     [,4]     [,5]     [,6]
       #>  [1,] 134809.00 11710.97 25945.08 17508.26 11476.00 13803.70
      @@ -285,7 +285,7 @@ 

      Debugging WHAM models

      #> [43,] 22026.47 22026.47 22026.47 22026.47 22026.47 22026.47 #> [44,] 22026.47 22026.47 22026.47 22026.47 22026.47 22026.47

      FAA looks ok - no issues with F or selectivity.

      -
      +
       therep$FAA[,1,] # middle dim is n.fleets = 1
       #>            [,1]       [,2]       [,3]       [,4]       [,5] [,6]
       #>  [1,] 0.0501933 0.07552447 0.09057153 0.09692876 0.09922137  0.1
      @@ -333,7 +333,7 @@ 

      Debugging WHAM models

      #> [43,] 0.0501933 0.07552447 0.09057153 0.09692876 0.09922137 0.1 #> [44,] 0.0501933 0.07552447 0.09057153 0.09692876 0.09922137 0.1

      ZAA looks ok - no issues with M either.

      -
      +
       therep$ZAA
       #>            [,1]      [,2]      [,3]      [,4]      [,5]     [,6]
       #>  [1,] 0.4551933 0.4115245 0.3865715 0.3719288 0.3552214 0.331099
      @@ -381,7 +381,7 @@ 

      Debugging WHAM models

      #> [43,] 0.4551933 0.4115245 0.3865715 0.3719288 0.3552214 0.331099 #> [44,] 0.4551933 0.4115245 0.3865715 0.3719288 0.3552214 0.331099

      Ah, here is the problem. The weight at age data has an entry of -99. This means that pred_catch is negative on line 880, and we take the log of a negative number on line 883.

      -
      +
       input$data$waa[1,,]
       #>          [,1]  [,2]  [,3]  [,4]  [,5]  [,6]
       #>  [1,]   0.210 0.296 0.348 0.374 0.382 0.428
      diff --git a/docs/index.html b/docs/index.html
      index ba1f5902..3d920938 100644
      --- a/docs/index.html
      +++ b/docs/index.html
      @@ -147,7 +147,7 @@
       

      Background

      -

      WHAM generalizes and extends R and TMB code from Miller et al. (2016), Miller and Hyun 2018, and Miller et al. 2018. WHAM has many similarities to ASAP (code, Legault and Restrepo 1998), including the input data file structure. Many of the plotting functions for input data, results, and diagnostics are modified from ASAP code written by Chris Legault and Liz Brooks (ASAPplots).

      +

      WHAM generalizes and extends R and TMB code from Miller et al. (2016), Miller and Hyun 2018, and Miller et al. 2018. WHAM has many similarities to ASAP (code, Legault and Restrepo 1998), including the input data file structure. Many of the plotting functions for input data, results, and diagnostics are modified from ASAP code written by Chris Legault and Liz Brooks (ASAPplots).

      Overview of WHAM presentation from Nov 2019 CAPAM workshop: https://www.youtube.com/watch?v=M1x4Nv4Ibio.

      WHAM is written in R and TMB, and would not be possible without these superb open-source tools. For more information, see:

      diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml index f7c851cd..25f3a4f6 100644 --- a/docs/pkgdown.yml +++ b/docs/pkgdown.yml @@ -1,4 +1,4 @@ -pandoc: 2.3.1 +pandoc: 1.19.2.4 pkgdown: 1.6.1 pkgdown_sha: ~ articles: @@ -9,7 +9,7 @@ articles: ex5_GSI_M: ex5_GSI_M.html ex6_NAA: ex6_NAA.html ex7_debug: ex7_debug.html -last_built: 2020-11-18T01:03Z +last_built: 2020-11-23T19:44Z urls: reference: https://timjmiller.github.io/wham//reference article: https://timjmiller.github.io/wham//articles diff --git a/docs/reference/prepare_wham_input.html b/docs/reference/prepare_wham_input.html index a03d321c..d1de235e 100644 --- a/docs/reference/prepare_wham_input.html +++ b/docs/reference/prepare_wham_input.html @@ -357,11 +357,11 @@

      Details

      age_comp specifies the age composition models for fleet(s) and indices. If NULL, the multinomial is used because this was the only option in ASAP. The age composition models available are:

      -
      "multinomial"

      Multinomial. This is the default because it was the only option in ASAP. 0 parameters. Generally inferior.

      +
      "multinomial"

      Multinomial. This is the default because it was the only option in ASAP. 0 parameters.

      "dir-mult"

      Dirichlet-multinomial. Effective sample size is estimated by the model (Thorson et al. 2017; Thorson 2019). 1 parameter.

      "dirichlet"

      See Francis 2014 and Albertsen et al. 2016. 1 parameter.

      "logistic-normal-01-infl"

      Zero-or-one inflated logistic normal. Inspired by zero-one inflated beta in Ospina and Ferrari (2012). 3 parameters.

      -
      "logistic-normal-pool0"

      Logistic normal, pooling zero observations with adjacent age classes. 1 parameter.

      +
      "logistic-normal-pool0"

      Logistic normal, pooling zero observations with adjacent age classes. 1 parameter. See Schnute and Haigh (2007) and Francis (2014)

      .
      "logistic-normal-01-infl-2par"

      Zero-one inflated logistic normal where p0 is a function of binomial sample size. 2 parameters.

      "logistic-normal-miss0"

      Logistic normal, treating zero observations as missing. 1 parameter.

      diff --git a/man/prepare_wham_input.Rd b/man/prepare_wham_input.Rd index db658506..2a6febce 100644 --- a/man/prepare_wham_input.Rd +++ b/man/prepare_wham_input.Rd @@ -187,11 +187,11 @@ To fit a state-space model, specify \code{NAA_re}, a list with the following ent If \code{NULL}, the multinomial is used because this was the only option in ASAP. The age composition models available are: \describe{ - \item{\code{"multinomial"}}{Multinomial. This is the default because it was the only option in ASAP. 0 parameters. Generally inferior.} + \item{\code{"multinomial"}}{Multinomial. This is the default because it was the only option in ASAP. 0 parameters.} \item{\code{"dir-mult"}}{Dirichlet-multinomial. Effective sample size is estimated by the model (\href{https://www.sciencedirect.com/science/article/abs/pii/S0165783616301941}{Thorson et al. 2017}; \href{https://www.sciencedirect.com/science/article/abs/pii/S016578361830033X}{Thorson 2019}). 1 parameter.} \item{\code{"dirichlet"}}{See \href{https://www.sciencedirect.com/science/article/abs/pii/S0165783613003093}{Francis 2014} and \href{https://cdnsciencepub.com/doi/abs/10.1139/cjfas-2015-0532}{Albertsen et al. 2016}. 1 parameter.} \item{\code{"logistic-normal-01-infl"}}{Zero-or-one inflated logistic normal. Inspired by zero-one inflated beta in \href{https://www.sciencedirect.com/science/article/abs/pii/S0167947311003628}{Ospina and Ferrari (2012)}. 3 parameters.} - \item{\code{"logistic-normal-pool0"}}{Logistic normal, pooling zero observations with adjacent age classes. 1 parameter.} + \item{\code{"logistic-normal-pool0"}}{Logistic normal, pooling zero observations with adjacent age classes. 1 parameter. See \href{https://doi.org/10.1093/icesjms/fsl024}{Schnute and Haigh (2007)} and \href{https://doi.org/10.1016/j.fishres.2013.12.015}{Francis (2014)}}. \item{\code{"logistic-normal-01-infl-2par"}}{Zero-one inflated logistic normal where p0 is a function of binomial sample size. 2 parameters.} \item{\code{"logistic-normal-miss0"}}{Logistic normal, treating zero observations as missing. 1 parameter.} }