├── .here ├── Main.pdf ├── data ├── covariates.rdata ├── dat_spawners.rdata ├── oilsardine_qtr.rdata └── Create_respdat.R ├── figures ├── sst.mon2-1.png ├── cov-effects-1.png ├── fig-qtrly-catch-1.png └── kerala_study_area_with_inset.jpg ├── Tables.Rmd ├── .gitattributes ├── Appendices.Rmd ├── .gitignore ├── SupplementalInformation.Rmd ├── setup.Rmd ├── AppendixFiles ├── AppendixSpawner.Rmd ├── AppendixNonSpawner.Rmd ├── Appendix-Variables.Rmd └── Appendix-Functions.Rmd ├── README.md ├── Table 3.Rmd ├── Figures.Rmd ├── SupplementFiles └── Table App A spawner model.Rmd ├── Main.Rmd └── apa-edit.csl /.here: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Main.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RVerse-Tutorials/Journal_Article/master/Main.pdf -------------------------------------------------------------------------------- /data/covariates.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RVerse-Tutorials/Journal_Article/master/data/covariates.rdata -------------------------------------------------------------------------------- /data/dat_spawners.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RVerse-Tutorials/Journal_Article/master/data/dat_spawners.rdata -------------------------------------------------------------------------------- /figures/sst.mon2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RVerse-Tutorials/Journal_Article/master/figures/sst.mon2-1.png -------------------------------------------------------------------------------- /data/oilsardine_qtr.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RVerse-Tutorials/Journal_Article/master/data/oilsardine_qtr.rdata -------------------------------------------------------------------------------- /figures/cov-effects-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RVerse-Tutorials/Journal_Article/master/figures/cov-effects-1.png -------------------------------------------------------------------------------- /figures/fig-qtrly-catch-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RVerse-Tutorials/Journal_Article/master/figures/fig-qtrly-catch-1.png -------------------------------------------------------------------------------- /figures/kerala_study_area_with_inset.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RVerse-Tutorials/Journal_Article/master/figures/kerala_study_area_with_inset.jpg -------------------------------------------------------------------------------- /Tables.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Tables" 3 | output: 4 | pdf_document: default 5 | word_document: default 6 | html_document: default 7 | header-includes: \usepackage[labelformat=empty]{caption} 8 | --- 9 | 10 | ```{r child = 'setup.Rmd'} 11 | ``` 12 | 13 | 14 | ```{r child = 'Table 3.Rmd'} 15 | ``` 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /Appendices.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Appendices: Covariate tests' 3 | output: 4 | pdf_document: default 5 | html_document: default 6 | word_document: default 7 | header-includes: \usepackage[labelformat=empty]{caption} 8 | --- 9 | 10 | ```{r include=FALSE} 11 | here::set_here() 12 | ``` 13 | 14 | ```{r child = file.path('AppendixFiles','AppendixSpawner.Rmd')} 15 | ``` 16 | 17 | ```{r, results="asis", echo=FALSE} 18 | cat("\\clearpage") 19 | ``` 20 | 21 | ```{r child = file.path('AppendixFiles','AppendixNonSpawner.Rmd')} 22 | ``` 23 | 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | .Rproj.user 49 | *.Rproj 50 | .RData 51 | .Rhistory 52 | *.log 53 | -------------------------------------------------------------------------------- /SupplementalInformation.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Supplemental Information: Full model tests and diagnostics' 3 | output: 4 | pdf_document: default 5 | html_document: default 6 | word_document: default 7 | header-includes: \usepackage[labelformat=empty]{caption} 8 | --- 9 | 10 | `setup.Rmd` is always called at the start of my Rmds. It loads the data and sets up variables. 11 | 12 | ```{r child = 'setup.Rmd'} 13 | ``` 14 | 15 | ```{r echo=FALSE} 16 | # This is some code so I don't have the change things if I submit to a 17 | # different journal that uses 'appendices' instead of 'supplements' 18 | Supplement <- TRUE # Change if this will be labeled appendix 19 | 20 | # The .rmdenvir is where the figure and table counter is located. 21 | # This must be at the head of all Rmds 22 | if(!exists(".rmdenvir")) .rmdenvir = environment() 23 | ``` 24 | 25 | I've cut this down quite a bit. But it gives you an idea of how to set this up. 26 | 27 | # Tests for prior season catch as covariate 28 | 29 | ```{r child = file.path('SupplementFiles', 'Table App A spawner model.Rmd')} 30 | ``` 31 | 32 | ```{r, results="asis", echo=FALSE} 33 | cat("\\clearpage") 34 | ``` 35 | 36 | # Comparison of land and oceanic rainfall measurements 37 | 38 | ```{r echo=FALSE} 39 | #set the table pre 40 | if(Supplement){ 41 | pre <- "S" 42 | figset <- "figsupp:" 43 | }else{ 44 | pre <- "E" 45 | figset <- "figappE:" 46 | } 47 | ``` 48 | 49 | ```{r echo=FALSE} 50 | thecap=paste0("Monthly precipitation measured over land via land gauges versus the precipitation measured via remote sensing over the ocean.") 51 | fullcap.precip <- paste0("Figure ", ref(paste0(figset,"figprecip"), pre=pre), ". ", thecap) 52 | ``` 53 | 54 | ```{r rainfall.mon.comparison, echo=FALSE,fig.cap=fullcap.precip, fig.width=6,fig.height=6,message=FALSE,warning=FALSE} 55 | plot(covariates$Precip.Kerala, covariates$precip.gpcp.kerala, ylab="Monthly land precipitation (mm)", 56 | xlab="Monthly ocean precipitation (average mm/day)") 57 | ``` 58 | 59 | ```{r, results="asis", echo=FALSE} 60 | cat("\\clearpage") 61 | ``` 62 | 63 | 64 | -------------------------------------------------------------------------------- /setup.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Generic set-up for all Rmds" 3 | author: "EE Holmes" 4 | output: 5 | pdf_document: default 6 | html_document: default 7 | --- 8 | 9 | ```{r message=FALSE,warning=FALSE, echo=FALSE} 10 | # Load up the needed libraries and 11 | # set the global environment varible for figure numbering (.rmdenvir) 12 | # and whether this is being built to LaTeX or not 13 | knitr::opts_chunk$set(echo = FALSE) 14 | library(stringr) 15 | library(mgcv) 16 | library(knitr) 17 | library(here) 18 | library(forecast) 19 | # If this is being called from another Rmd (as a child), this counter will exist 20 | if(!exists(".rmdenvir")) .rmdenvir = environment() 21 | #detect if making latex 22 | knitOut=knitr::opts_knit$get("rmarkdown.pandoc.to") 23 | if(length(knitOut)==0) isLatex=FALSE else isLatex=(knitOut=="latex") 24 | ``` 25 | 26 | ```{r} 27 | # Check if Create_respdat.R was changed since dat_spawners.rdata was last created 28 | # re-source if so. Idea is to make sure data is up to date, but not re-run code excessively 29 | p1 <- file.path(here::here(),"data/dat_spawners.rdata") 30 | t1 <- file.info(p1)$ctime 31 | p2 <- file.path(here::here(),"data/Create_respdat.R") 32 | t2 <- file.info(p1)$ctime 33 | if(t1 < t2) source(file.path( here::here(), "data/Create_respdat.R")) 34 | ``` 35 | 36 | ```{r} 37 | # load up the catch data 38 | load(file.path(here::here(),"data/oilsardine_qtr.rdata")) 39 | # load the response and covariate data frame 40 | load(file.path(here::here(),"data/dat_spawners.rdata")) 41 | load(file.path(here::here(),"data/covariates.rdata")) 42 | ``` 43 | 44 | 45 | ```{r} 46 | # Note I actually keep these functions in a personal package that I load for my papers 47 | # But for this example repository I put them here 48 | # Since this setup.Rmd is called for all Rmds, I use the if statement to prevent the function 49 | # from being redefined over and over (not that anything bad would happen). 50 | if(!exists("ref")){ 51 | ref <- function(useName, pre = "", app = "") { 52 | if (!exists(".refctr")) .refctr <- c(`_` = 0) 53 | if (any(names(.refctr) == useName)) { 54 | return(.refctr[useName]) 55 | } 56 | type <- stringr::str_split(useName, ":")[[1]][1] 57 | reftypes <- unlist(lapply(stringr::str_split(names(.refctr), ":"), function(x) { 58 | x[1] 59 | })) 60 | nObj <- sum(reftypes == type) 61 | useNum <- paste(pre, nObj + 1, app, sep = "") 62 | newrefctr <- c(.refctr, useNum) 63 | names(newrefctr)[length(.refctr) + 1] <- useName 64 | assign(".refctr", newrefctr, envir = .rmdenvir) 65 | return(useNum) 66 | } 67 | } 68 | 69 | if(!exists("AICc")){ 70 | AICc <- function(object){ 71 | k <- attributes(logLik(object))$df 72 | aic <- AIC(object) 73 | n <- nrow(object$model) 74 | if(class(object)[1]=="marssMLE") n <- object$samp.size 75 | return(aic+(2*k^2+2*k)/(n-k-1)) 76 | } 77 | } 78 | ``` 79 | -------------------------------------------------------------------------------- /AppendixFiles/AppendixSpawner.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Appendices: Covariate tests' 3 | output: 4 | pdf_document: default 5 | html_document: default 6 | word_document: default 7 | header-includes: \usepackage[labelformat=empty]{caption} 8 | --- 9 | 10 | ```{r child = file.path(here::here(),'setup.Rmd')} 11 | ``` 12 | 13 | ```{r child = file.path(here::here(),'AppendixFiles','Appendix-Functions.Rmd')} 14 | ``` 15 | 16 | ```{r child = file.path(here::here(),'AppendixFiles','Appendix-Variables.Rmd')} 17 | ``` 18 | 19 | 20 | ```{r spawncovnames, echo=FALSE} 21 | vars <- getspawnercovs() 22 | datcommon <- dat.spawners[, 23 | c("Year", "spawners0", "spawners1", "spawners2", 24 | "nspawners1", "nspawners2", vars$allcovnames)] 25 | dat <- na.omit(datcommon) 26 | 27 | NE=mean(abs(dat$spawners0-dat$spawners1)) 28 | ``` 29 | 30 | ```{r spawnerapptabeqns, echo=FALSE} 31 | nullmod <- "$ln(S_t) = ln(S_{t-1}) + \\epsilon_t$" 32 | basemod <- "$ln(S_t) = \\alpha + s(ln(N_{t-1})) + \\epsilon_t$" 33 | resp <- "ln(S_t)" 34 | baseformula <- "spawners0 ~ s(nspawners1, sp=0.6)" 35 | nullformula <- "spawners0 ~ -1 + offset(spawners1)" 36 | ``` 37 | 38 | ```{r spawntable} 39 | seltable <- makeapptable(dat, nullmod, basemod, nullformula, baseformula, resp, vars$covnamelist, vars$covlags) 40 | ``` 41 | 42 | 43 | ```{r print-apptable1, echo=FALSE} 44 | seltable = seltable[,c("Model", "Residual.df", "Adj.R2", "RMSE", "AIC", "LOOCV", "LOOMd")] 45 | colnames(seltable) <- c("Model", "Resid. df", "Adj. R2", "RMSE", "AICc", "LOOCV", "LOOMdAE") 46 | if(isLatex) colnames(seltable)=c("Model", "\\shortstack{Resid.\\\\df}", "\\shortstack{Adj.\\\\$R^2$}", "RMSE", "AICc", "\\shortstack{LOOCV\\\\RMSE}", "\\shortstack{LOOCV\\\\MdAE}") 47 | 48 | thecap=paste("Covariate tests for the July-September catch ($S_t$). M is the base model with only prior season October-March catch ($N_{t-1}$) as the covariate. To the base model, the environmental covariates are added. ns-SST is nearshore (0-80km) and r-SST is regional (0-160km) SST. Similarly, ns-Chl is nearshore chlorophyll. The models are nested sets, e.g. 1, 2a, 3a and 1, 2b, 3b.") 49 | fullcap=paste("Table ", ref("apptab:spawnercovariate-models", pre="A"), ". ", thecap, sep="") 50 | kable(seltable, align=paste0("l", paste0(rep("c",dim(seltable)[2]-1),collapse="")), caption=fullcap, escape=FALSE) 51 | ``` 52 | 53 | Notes: LOOCV = Leave one out cross-validation. RMSE = root mean square error. MdAE = median absolute error. AICc = Akaike Information Criterion corrected for small sample size. $\dagger$ and $\dagger\dagger$ = AICc greater than 2 and greater than 5 below model M (base catch model). $\ddagger$, $\ddagger\ddagger$, and ${\ddagger}{\ddagger}{\ddagger}$ = LOOCV RMSE 5\%, 10\% and 20\% below model M, respectively. $t$ indicates current season (Jul-Jun) and $t-1$ is prior season. Thus a Jan-Mar covariate with $t-1$ would be in the same calendar year as the Jul-Sep catch, though in a prior fishing season. With the exception that for covariates that are calendar year (Jan-Dec) or multiyear, $t$ is the current calendar year. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | README 2 | ================ 3 | EE Holmes 4 | 5 | This shows a repository for writing a journal article. 6 | 7 | The Rmd files create the manuscript as PDF or Word. Note that the tables do not look very good in Word. Best to look at those in the pdf file. 8 | 9 | To run 10 | ------ 11 | 12 | Download all the Rmd files. The README file is not needed. 13 | 14 | If you do not have these packages installed, install the following from CRAN. 15 | 16 | - knitr 17 | - bibtex 18 | - forecast 19 | - gbRd 20 | - mgcv 21 | - stringr 22 | - rmarkdown 23 | - here 24 | 25 | Running the Rmds requires pandoc with pandoc-citeproc installed (citeproc is doing the citations). That should come by default but if you get a pandoc error, try installing from http://pandoc.org/installing.html. Now you can run the Rmd files for the paper. If the RStudio complains that it cannot make a pdf, then click the little arrow next to the 'knitr' button at top (in RStudio) and you will see 'Knit to Word'. Click that. 26 | 27 | Note, to make PDF files you will need a LaTeX installation. If you don't have one already (if you are not sure, then you don't), you can install [tinytex](https://yihui.name/tinytex/). Run these lines: 28 | 29 | ``` 30 | install.packages('tinytex') 31 | tinytex::install_tinytex() 32 | ``` 33 | 34 | Note that the first time you knit to a PDF, tinytex will have to install needed packages and this will take a long time (like up to 15-20 minutes). Just keep waiting as the little wheel spins on the R Markdown tab. 35 | 36 | Structure 37 | ------------ 38 | 39 | * Main.Rmd The main text with title page an abstract 40 | * Tables.Rmd Calls the Rmds for individual tables 41 | * Figures.Rmd Calls the Rmds for individual figures 42 | * Appendices.Rmd Calls the Rmds for individual appendices 43 | * SupplementalInformation.Rmd 44 | * References are in `Sardine.bib`. The formating file for the references is in `apa-edit.csl`. I editted that to look more like a typical fisheries journal format. 45 | * Images are in the `images` folder 46 | * Figures are saved to the `figures` folder 47 | * Date is in the `data` folder. In that folder, it the script that creates the data frame used in the analyses: `dat_spawners.rdata`. The script that produced the catch and covariate data is not shown here, but would be in this folder too for the real paper. 48 | 49 | 50 | To knit 51 | ------------- 52 | 53 | - Open Main.Rmd. To knit, click the 'knit' button in the top navbar in RStudio. This will use the Rmd files for the tables and insert in the main document. The citations bib file is in the `Sardine.bib`. I maintain my references in EndNote and export to bibtex format (its one of the EndNote export options). 54 | 55 | The main Rmd file, runs the Figures and Appendices, but you can make these separately too. 56 | 57 | - Open Figures.Rmd to knit the figures for the main paper. 58 | - Open Tables.Rmd to knit the tables for the main paper. 59 | - Open Appendices.Rmd to create the appendices. This will call the Rmd files for the appendix tables. 60 | 61 | -------------------------------------------------------------------------------- /AppendixFiles/AppendixNonSpawner.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Appendices: Non-spawner covariate tests' 3 | output: 4 | pdf_document: default 5 | html_document: default 6 | word_document: default 7 | header-includes: \usepackage[labelformat=empty]{caption} 8 | --- 9 | 10 | ```{r child = file.path(here::here(),'setup.Rmd')} 11 | ``` 12 | 13 | ```{r echo=FALSE} 14 | #set the table pre 15 | if(Supplement){ 16 | pre <- "S" 17 | tabset <- "tabsupp:" 18 | }else{ 19 | pre <- "A" 20 | tabset <- "tabapp:" 21 | } 22 | ``` 23 | 24 | ```{r child = file.path(here::here(),'AppendixFiles','Appendix-Functions.Rmd')} 25 | ``` 26 | 27 | ```{r child = file.path(here::here(),'AppendixFiles','Appendix-Variables.Rmd')} 28 | ``` 29 | 30 | ```{r nonspawncovnames, echo=FALSE} 31 | vars <- getnonspawnercovs() 32 | datcommon <- dat.spawners[, 33 | c("Year", "nspawners0", "spawners1", "spawners2", 34 | "nspawners1", "nspawners2", vars$allcovnames)] 35 | dat <- na.omit(datcommon) 36 | 37 | NE=mean(abs(dat$nspawners0-dat$nspawners1)) 38 | ``` 39 | 40 | ```{r nonspawnertablevals} 41 | nullmod <- "$ln(N_t) = ln(N_{t-1}) + \\epsilon_t$" 42 | basemod <- "$ln(N_t) = \\alpha + s(ln(N_{t-1})) + s(ln(S_{t-2})) + \\epsilon_t$" 43 | resp <- "ln(N_t)" 44 | baseformula <- "nspawners0 ~ s(nspawners1, sp=0.6) + s(spawners2, sp=0.6)" 45 | nullformula <- "nspawners0 ~ -1 + offset(nspawners1)" 46 | ``` 47 | 48 | ```{r nonspawnertable} 49 | seltable <- makeapptable(dat, nullmod, basemod, nullformula, baseformula, resp, vars$covnamelist, vars$covlags) 50 | ``` 51 | 52 | 53 | ```{r print-apptable2, echo=FALSE} 54 | seltable = seltable[,c("Model", "Residual.df", "Adj.R2", "RMSE", "AIC", "LOOCV", "LOOMd")] 55 | colnames(seltable) <- c("Model", "Resid. df", "Adj. R2", "RMSE", "AICc", "LOOCV", "LOOMdAE") 56 | if(isLatex) colnames(seltable)=c("Model", "\\shortstack{Resid.\\\\df}", "\\shortstack{Adj.\\\\$R^2$}", "RMSE", "AICc", "\\shortstack{LOOCV\\\\RMSE}", "\\shortstack{LOOCV\\\\MdAE}") 57 | 58 | thecap=paste("Covariate tests for the October-March catch ($N_t$). M is the base model with prior season October-March catch ($N_{t-1}$) and July-September catch two seasons prior ($S_{t-2}$) as the covariates. To the base model, the environmental covariates are added. ns-SST is nearshore (0-80km) and r-SST is regional (0-160km) SST. Similarly, ns-Chl is nearshore chlorophyll. The nested F-tests are given in Supporting Information. The models are nested sets, e.g. 1, 2a, 3a and 1, 2b, 3b.") 59 | fullcap=paste("Table ", ref(paste0(tabset,"nonspawnercovariate-models"), pre=pre), ". ", thecap, sep="") 60 | kable(seltable, align=paste0("l", paste0(rep("c",dim(seltable)[2]-1),collapse="")), caption=fullcap, escape=FALSE) 61 | ``` 62 | 63 | Notes: LOOCV = Leave one out cross-validation. RMSE = root mean square error. MdAE = median absolute error. AICc = Akaike Information Criterion corrected for small sample size. $\dagger$ and $\dagger\dagger$ = AICc greater than 2 and greater than 5 below model M (base catch model). $\ddagger$, $\ddagger\ddagger$, and ${\ddagger}{\ddagger}{\ddagger}$ = LOOCV RMSE 5\%, 10\% and 20\% below model M, respectively. $t$ indicates current season (Jul-Jun) and $t-1$ is prior season. Thus a Jan-Mar covariate with $t-1$ would be in the same calendar year as the Jul-Sep catch, though in a prior fishing season. With the exception that for covariates that are calendar year (Jan-Dec) or multiyear, $t$ is the current calendar year. -------------------------------------------------------------------------------- /AppendixFiles/Appendix-Variables.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Appendices: Common Functions' 3 | output: 4 | pdf_document: default 5 | html_document: default 6 | word_document: default 7 | --- 8 | 9 | ```{r echo=FALSE} 10 | getnonspawnercovs <- function(){ 11 | covnamelist = list( 12 | Precipitation=c("precip.gpcp.kerala.mon6to7.", "Precip.Kerala.mon6to7.", 13 | "precip.gpcp.kerala.mon4to5.", "Precip.Kerala.mon4to5."), 14 | `Sea surface temperature`= c("SST.2.10.mon3to5.", "SST.2.5.mon10to12."), 15 | Upwelling=c("SST.UPW.4.mon6to9.", "SST.2.5.mon6to9.", "Bakun.UPW.mon6to9."), 16 | `Ocean climate`=c("SST.2.10.3.yr.runsum.", 17 | "ONI.mon1to12.", "DMI.mon9to11.")) 18 | covlags = list( 19 | precip.gpcp.kerala.mon6to7. = c(0,1), 20 | Precip.Kerala.mon6to7. = c(0,1), 21 | precip.gpcp.kerala.mon4to5. = c(0,1), 22 | Precip.Kerala.mon4to5. = c(0,1), 23 | SST.2.10.mon3to5. = c(0,1), 24 | SST.2.5.mon10to12. = c(0,1), 25 | SST.UPW.4.mon6to9. = c(0,1), 26 | SST.2.5.mon6to9. = c(0,1), 27 | Bakun.UPW.mon6to9. = c(0,1), 28 | SSTICOAD.2.10.3.yr.runsum. = 0, 29 | SST.2.5.3.yr.runsum. = 0, SST.2.10.3.yr.runsum. = 0, 30 | SST.1.13.3.yr.runsum. = 0, SST.7.13.3.yr.runsum. = 0, 31 | DMI.3.yr.runsum. = c(0), 32 | ONI.mon1to12. = c(0), 33 | DMI.mon6to9. = c(0,1), 34 | DMI.mon9to11. = c(0,1), 35 | tide.level.interp.mon7to8. = c(0,1), 36 | anomalies.mon6to9. = c(0,1), 37 | tide.level.interp.mon8to8. = c(0,1)) 38 | allcovnames <- c() 39 | covnames <- unlist(covnamelist) 40 | for(i in covnames) allcovnames <- c(allcovnames, 41 | paste0(i, covlags[[i]])) 42 | return(list(allcovnames=allcovnames, covnamelist=covnamelist, covlags=covlags)) 43 | } 44 | ``` 45 | 46 | ```{r echo=FALSE} 47 | getnonspawnerchlcovs <- function(){ 48 | covnamelist = list( 49 | Chlorophyll=c("log.CHL.2.5.mon7to9.", 50 | "log.CHL.2.5.mon10to12.") 51 | ) 52 | covlags = list( 53 | DMI.mon9to11. = c(0,1), 54 | log.CHL.2.5.mon7to9. = c(0,1), 55 | log.CHL.2.5.mon10to12. = c(0,1), 56 | log.CHL.2.5.mon1to3. = c(0,1)) 57 | allcovnames <- c() 58 | covnames <- unlist(covnamelist) 59 | for(i in covnames) allcovnames <- c(allcovnames, 60 | paste0(i, covlags[[i]])) 61 | return(list(allcovnames=allcovnames, covnamelist=covnamelist, covlags=covlags)) 62 | } 63 | ``` 64 | 65 | ```{r echo=FALSE} 66 | getspawnercovs <- function(){ 67 | covnamelist = list( 68 | Precipitation=c("precip.gpcp.kerala.mon6to7.", "Precip.Kerala.mon6to7.", 69 | "precip.gpcp.kerala.mon4to5.", "Precip.Kerala.mon4to5."), 70 | `Sea surface temperature`= c("SST.2.10.mon3to5.", "SST.2.5.mon10to12."), 71 | Upwelling=c("SST.UPW.4.mon6to9.", "SST.2.5.mon6to9.", "Bakun.UPW.mon6to9."), 72 | `Ocean climate`=c("SST.2.10.3.yr.runsum.", 73 | "ONI.mon1to12.", "DMI.mon9to11.")) 74 | covlags = list( 75 | precip.gpcp.kerala.mon6to7. = 0, 76 | precip.gpcp.kerala.mon4to5. = 0, 77 | Precip.Kerala.mon6to7. = c(0), 78 | Precip.Kerala.mon4to5. = c(0), 79 | SST.2.10.mon3to5. = c(0,1), 80 | SST.2.5.mon10to12. = 1, 81 | SST.UPW.4.mon6to9. = c(0,1), 82 | SST.2.5.mon6to9. = c(0,1), 83 | Bakun.UPW.mon6to9. = c(0,1), 84 | SST.2.5.3.yr.runsum. = 0, 85 | SST.2.10.3.yr.runsum. = 0, 86 | SSTICOAD.2.10.3.yr.runsum. = 0, 87 | ONI.mon1to12. = c(1), 88 | DMI.mon9to11. = c(1), 89 | DMI.3.yr.runsum. = c(0)) 90 | allcovnames <- c() 91 | covnames <- unlist(covnamelist) 92 | for(i in covnames) allcovnames <- c(allcovnames, 93 | paste0(i, covlags[[i]])) 94 | return(list(allcovnames=allcovnames, covnamelist=covnamelist, covlags=covlags)) 95 | } 96 | ``` 97 | 98 | ```{r echo=FALSE} 99 | getspawnerchlcovs <- function(){ 100 | covnamelist = list( 101 | Chlorophyll=c("log.CHL.2.5.mon7to9.", 102 | "log.CHL.2.5.mon10to12.") 103 | ) 104 | covlags = list( 105 | log.CHL.2.5.mon7to9. = c(0,1), 106 | log.CHL.2.5.mon10to12. = 1, 107 | log.CHL.2.5.mon1to3. = 1) 108 | allcovnames <- c() 109 | covnames <- unlist(covnamelist) 110 | for(i in covnames) allcovnames <- c(allcovnames, 111 | paste0(i, covlags[[i]])) 112 | return(list(allcovnames=allcovnames, covnamelist=covnamelist, covlags=covlags)) 113 | } 114 | ``` 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /data/Create_respdat.R: -------------------------------------------------------------------------------- 1 | # This file creates respdata.rdata 2 | # which is used in all the analyses 3 | # setup.Rmd will detect if this file has change and will re-source it if needed. 4 | 5 | # load up the data 6 | load(file.path(here::here(), "data/oilsardine_qtr.rdata")) 7 | load(file.path(here::here(), "data/covariates.rdata")) 8 | 9 | # Create the response variables (respdat) 10 | # spawners is Jul-Sep catch (qtr 3) 11 | # nspawners is Oct-Mar catch (qtr 4 and 1) 12 | Qtr <- 3 # start of season 13 | reg <- "Kerala" 14 | respdat <- data.frame( 15 | spawners0 = oilsardine_qtr[[reg]][oilsardine_qtr$Qtr == 3] 16 | ) 17 | CatchWin <- stats::filter(oilsardine_qtr[[reg]], c(0, 1, 1, 0), sides = 1)[seq(6, dim(oilsardine_qtr)[1], 4)] 18 | respdat$nspawners0 <- c(CatchWin, NA) 19 | respdat <- log(respdat) 20 | years <- oilsardine_qtr$Year[oilsardine_qtr$Qtr == Qtr] 21 | 22 | 23 | # Create the covariate data 24 | 25 | # These are the covariates I am using 26 | # SST.4 is the SST in box 4 (lat/lon box) 27 | covnames <- c( 28 | paste0("log.CHL.", 1:13), 29 | paste0("SST.UPW.", 1:5), 30 | paste0("Wind.UPW.", 1:5), 31 | paste0("SST.", 1:13), 32 | paste0("SSTICOAD.", 1:13), 33 | "precip.gpcp.kerala", "Precip.Kerala", 34 | "ONI", "DMI", "Bakun.UPW" 35 | ) 36 | 37 | # There are the months I want to combine 38 | covmon <- list( 39 | 7:9, 1:3, 10:12, 9:10, 6:9, 40 | 1:12, 3:5, 4:6, 1:5, 4:5, 6:7, 41 | 9:11, 8, 9, 7:8 42 | ) 43 | 44 | # fix problem in covariates with SST in 1994. 45 | # replace with 5 year mean for that month 46 | covariates2 <- covariates 47 | tmpcov <- c( 48 | "SST.UPW.3", "SST.UPW.4", "SST.UPW.5", "SST.2", 49 | paste0("SST.", c(2:5, 7:13)), 50 | paste0("SSTICOAD.", c(2:5, 7:13)) 51 | ) 52 | for (itmpcov in tmpcov) { 53 | for (mon in 10:12) { 54 | filt1 <- with(covariates2, Year == 1994 & Month == mon) 55 | if (!is.na(covariates2[filt1, itmpcov])) next 56 | filt2 <- with(covariates2, Year %in% (1990:1996) & Month == mon) 57 | covariates2[filt1, itmpcov] <- mean(covariates[filt2, itmpcov], na.rm = TRUE) 58 | } 59 | } 60 | 61 | # Subset covariates to match the years in respdat 62 | covariates2 <- covariates2[covariates2$Year %in% years, ] 63 | 64 | # Now create the covariates averaged over specified month and lat/lon boxes 65 | 66 | for (i in 1:length(covnames)) { 67 | covname <- covnames[i] 68 | for (j in 1:length(covmon)) { 69 | mon <- covmon[[j]] 70 | varname <- paste(covname, ".mon", mon[1], "to", mon[length(mon)], ".0", sep = "") 71 | covdat <- tapply(covariates2[[covname]], covariates2$Year, function(x) { 72 | mean(x[mon], na.rm = TRUE) 73 | }) 74 | covdat[is.infinite(covdat)] <- NA 75 | if (stringr::str_detect(varname, "mon1to3") | stringr::str_detect(varname, "mon4to6")) { 76 | # Fishing season if July to June, so Jan-Jun should be prior fishing year 77 | respdat[[varname]] <- c(covdat[-1], NA) 78 | } else { 79 | respdat[[varname]] <- covdat 80 | } 81 | } 82 | } 83 | # go through the boxes and make spatial averages 84 | for (bx in list(c(2:5), c(2:5, 7:10), c(7:13), c(7, 10), c(11:13), c(1:13))) { 85 | for (j in c("mon1to3.0", "mon9to10.0", "mon6to9.0", "mon1to12.0", "mon3to5.0", "mon10to12.0", "mon7to9.0")) { 86 | for (jj in c("SST.", "log.CHL.", "SSTICOAD.")) { 87 | varname <- c(paste0(jj, bx, ".", j)) 88 | tmp <- apply(respdat[, varname], 1, mean, na.rm = TRUE) 89 | varname <- paste0(jj, bx[1], ".", bx[NROW(bx)], ".", j) 90 | respdat[[varname]] <- tmp 91 | } 92 | } 93 | } 94 | 95 | # add lags 96 | for (i in colnames(respdat)) { 97 | name <- paste(stringr::str_sub(i, 1, stringr::str_length(i) - 1), "1", sep = "") 98 | respdat[[name]] <- c(NA, respdat[[i]][1:(dim(respdat)[1] - 1)]) 99 | name <- paste(stringr::str_sub(i, 1, stringr::str_length(i) - 1), "2", sep = "") 100 | respdat[[name]] <- c(NA, NA, respdat[[i]][1:(dim(respdat)[1] - 2)]) 101 | } 102 | 103 | # make 2.5 year running means 104 | for (varn in c("SST.", "DMI", "Precip.Kerala", "SSTICOAD.")) { 105 | if (varn == "SST." | varn == "SSTICOAD.") ivals <- c("2.5", "2.10", "7.10", "7.13", "11.13", "1.13") 106 | if (varn == "DMI" | varn == "Precip.Kerala") ivals <- c("") 107 | for (i in ivals) { 108 | tmp <- (respdat[, paste0(varn, i, ".mon1to12.0")] * 12 - 109 | respdat[, paste0(varn, i, ".mon10to12.0")] * 3 - 110 | respdat[, paste0(varn, i, ".mon7to9.0")] * 3) + 111 | respdat[, paste0(varn, i, ".mon1to12.1")] * 12 + 112 | respdat[, paste0(varn, i, ".mon1to12.2")] * 12 113 | varname <- paste0(varn, i, ".3.yr.runsum.0") 114 | respdat[[varname]] <- tmp / (12 + 12 + 6) 115 | # create the lag 1 116 | for (ii in paste0(varn, i, ".3.yr.runsum.0")) { 117 | name <- paste(stringr::str_sub(ii, 1, stringr::str_length(ii) - 1), "1", sep = "") 118 | respdat[[name]] <- c(NA, respdat[[ii]][1:(dim(respdat)[1] - 1)]) 119 | name <- paste(stringr::str_sub(ii, 1, stringr::str_length(ii) - 1), "2", sep = "") 120 | respdat[[name]] <- c(NA, NA, respdat[[ii]][1:(dim(respdat)[1] - 2)]) 121 | } 122 | } 123 | } 124 | 125 | respdat$Year <- years 126 | 127 | 128 | # Name for data frame with response vars and covariates 129 | dat.spawners <- respdat 130 | 131 | # Fix the runsum names 132 | runsumnames <- colnames(dat.spawners)[stringr::str_detect(colnames(dat.spawners), "runsum")] 133 | runsumnames <- unique(sapply(runsumnames, function(x) { 134 | stringr::str_split(x, "runsum")[[1]][1] 135 | })) 136 | runsumnames <- paste0(runsumnames, "runsum.") 137 | 138 | # These are the covariates I want 139 | covnames <- c( 140 | "precip.gpcp.kerala.mon6to7.", "precip.gpcp.kerala.mon4to5.", 141 | "Precip.Kerala.mon6to7.", "Precip.Kerala.mon4to5.", 142 | "SST.4.mon6to9.", 143 | "SST.UPW.4.mon6to9.", "Bakun.UPW.mon6to9.", 144 | "SST.2.5.mon6to9.", "SST.2.5.mon9to10.", 145 | "SST.2.10.mon3to5.", "SST.2.5.mon10to12.", 146 | "ONI.mon1to12.", "DMI.mon9to11.", "DMI.mon6to9.", runsumnames 147 | ) 148 | 149 | dat.spawners <- dat.spawners[, 150 | c("Year", "nspawners0", "nspawners1", "nspawners2", 151 | "spawners0", "spawners1", "spawners2", 152 | paste(covnames, "0", sep=""), 153 | paste(covnames, "1", sep="")) 154 | ] 155 | 156 | # Do a check just in case there was a missing year in the data somewhere 157 | if (any(diff(dat.spawners$Year) != 1)) stop("Problem in setup.Rmd. The covariate data.frame cannot have any missing years.") 158 | 159 | # save to rdata 160 | save(dat.spawners, file = file.path(here::here(), "data/dat_spawners.rdata")) 161 | -------------------------------------------------------------------------------- /Table 3.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Table 3: Covariate tests' 3 | output: 4 | word_document: default 5 | html_document: default 6 | pdf_document: default 7 | header-includes: \usepackage[labelformat=empty]{caption} 8 | --- 9 | 10 | ```{r child = file.path(here::here(),'setup.Rmd')} 11 | ``` 12 | 13 | ```{r child = file.path(here::here(),'AppendixFiles','Appendix-Functions.Rmd')} 14 | ``` 15 | 16 | ```{r child = file.path(here::here(),'AppendixFiles','Appendix-Variables.Rmd')} 17 | ``` 18 | 19 | 20 | ```{r tab3-spawncovnames, echo=FALSE} 21 | # Make sure data used is consistent across appendices and here 22 | vars <- getspawnercovs() 23 | datcommon <- dat.spawners[, 24 | c("Year", "spawners0", "spawners1", "spawners2", 25 | "nspawners1", "nspawners2", vars$allcovnames)] 26 | datcommon <- na.omit(datcommon) 27 | covnamelist = list( 28 | `July-September catch`=c( 29 | "SST.2.5.mon6to9.", 30 | "Bakun.UPW.mon6to9.", 31 | "Precip.Kerala.mon6to7.", 32 | "SST.2.10.3.yr.runsum.") 33 | ) 34 | covlags = list( 35 | SST.2.5.mon6to9. = 0, 36 | Precip.Kerala.mon6to7. = 0, 37 | Bakun.UPW.mon6to9. = 0, 38 | DMI.3.yr.runsum. = 0, 39 | SST.2.10.3.yr.runsum. = 0) 40 | allcovnames <- c() 41 | covnames <- unlist(covnamelist) 42 | for(i in covnames) allcovnames <- c(allcovnames, 43 | paste0(i, covlags[[i]])) 44 | dat <- datcommon[, 45 | c("Year", "spawners0", "spawners1", "spawners2", 46 | "nspawners1", "nspawners2", allcovnames)] 47 | NE=mean(abs(dat$spawners0-dat$spawners1)) 48 | ``` 49 | 50 | ```{r tab3-spawnerapptabeqns, echo=FALSE} 51 | nullmod <- "$ln(S_t) = ln(S_{t-1}) + \\epsilon_t$" 52 | basemod <- "$ln(S_t) = \\alpha + s(ln(N_{t-1})) + \\epsilon_t$" 53 | resp <- "ln(S_t)" 54 | baseformula <- "spawners0 ~ s(nspawners1, sp=0.6)" 55 | nullformula <- "spawners0 ~ -1 + offset(spawners1)" 56 | ``` 57 | 58 | ```{r tab3-spawntable} 59 | headval <- paste0("**July-Sept catch ", min(dat$Year), "-", max(dat$Year), "**") 60 | seltable <- maketable3(dat, nullmod, basemod, nullformula, baseformula, resp, covnamelist, covlags, type="nonlinear", include.num=FALSE, include.group=FALSE, header=headval, compact=TRUE) 61 | ``` 62 | 63 | ```{r tab3-nonspawncovnames, echo=FALSE} 64 | # Make sure data used is consistent across appendices and here 65 | vars <- getnonspawnercovs() 66 | datcommon <- dat.spawners[, 67 | c("Year", "nspawners0", "spawners1", "spawners2", 68 | "nspawners1", "nspawners2", vars$allcovnames)] 69 | datcommon <- na.omit(datcommon) 70 | covnamelist = list( 71 | `October-March catch - simpler model`=c( 72 | "Precip.Kerala.mon6to7.", 73 | "SST.2.10.3.yr.runsum.", 74 | "DMI.mon9to11.") 75 | ) 76 | covlags = list( 77 | SST.2.5.mon6to9. = 0, 78 | Precip.Kerala.mon6to7. = 0, 79 | Bakun.UPW.mon6to9. = 0, 80 | DMI.mon9to11. = 1, 81 | SST.2.10.3.yr.runsum. = 0) 82 | allcovnames <- c() 83 | covnames <- unlist(covnamelist) 84 | for(i in covnames) allcovnames <- c(allcovnames, 85 | paste0(i, covlags[[i]])) 86 | dat <- datcommon[, 87 | c("Year", "nspawners0", "spawners1", "spawners2", 88 | "nspawners1", "nspawners2", allcovnames)] 89 | NE=mean(abs(dat$spawners0-dat$spawners1)) 90 | ``` 91 | 92 | ```{r tab3-nonspawnerapptabeqns, echo=FALSE} 93 | nullmod <- "$ln(N_t) = ln(N_{t-1}) + \\epsilon_t$" 94 | basemod <- "$ln(N_t) = \\alpha + s(ln(N_{t-1})) + \\epsilon_t$" 95 | resp <- "ln(N_t)" 96 | baseformula <- "nspawners0 ~ s(nspawners1, sp=0.6)" 97 | nullformula <- "nspawners0 ~ -1 + offset(nspawners1)" 98 | ``` 99 | 100 | ```{r tab3-nonspawntable} 101 | headval <- paste0("**October-March catch - simpler model ", min(dat$Year), "-", max(dat$Year), "**") 102 | nonspawnerwoS2table <- maketable3(dat, nullmod, basemod, nullformula, baseformula, resp, covnamelist, covlags, type="nonlinear", include.num=FALSE, include.group=FALSE, header=headval, compact=TRUE) 103 | seltable <- rbind(seltable, nonspawnerwoS2table) 104 | ``` 105 | 106 | ```{r tab3-nonspawncovnames2, echo=FALSE} 107 | covnamelist = list( 108 | `October-March catch - more complex model`=c( 109 | "Precip.Kerala.mon6to7.", 110 | "SST.2.10.3.yr.runsum.", 111 | "DMI.mon9to11.") 112 | ) 113 | covlags = list( 114 | DMI.mon9to11. = 1, 115 | Precip.Kerala.mon6to7. = 0, 116 | Bakun.UPW.mon6to9. = 0, 117 | SST.2.10.3.yr.runsum. = 0) 118 | allcovnames <- c() 119 | covnames <- unlist(covnamelist) 120 | for(i in covnames) allcovnames <- c(allcovnames, 121 | paste0(i, covlags[[i]])) 122 | dat <- datcommon[, 123 | c("Year", "nspawners0", "spawners2", 124 | "nspawners1", allcovnames)] 125 | NE=mean(abs(dat$spawners0-dat$spawners1)) 126 | ``` 127 | 128 | ```{r tab3-nonspawnerapptabeqns2, echo=FALSE} 129 | nullmod <- "$ln(N_t) = ln(N_{t-1}) + \\epsilon_t$" 130 | basemod <- "$ln(N_t) = \\alpha + s(ln(N_{t-1})) + s(ln(S_{t-2})) + \\epsilon_t$" 131 | resp <- "ln(N_t)" 132 | baseformula <- "nspawners0 ~ s(nspawners1, sp=0.6) + s(spawners2, sp=0.6)" 133 | nullformula <- "nspawners0 ~ -1 + offset(nspawners1)" 134 | ``` 135 | 136 | ```{r tab3-nonspawntable2} 137 | headval <- paste0("**October-March catch - more complex model ", min(dat$Year), "-", max(dat$Year), "**") 138 | nonspawnertable <- maketable3(dat, nullmod, basemod, nullformula, baseformula, resp, covnamelist, covlags, type="nonlinear", include.num=FALSE, include.group=FALSE, header="**October-March catch - more complex model**", compact=TRUE) 139 | seltable <- rbind(seltable, nonspawnertable) 140 | ``` 141 | 142 | ```{r print-table3, echo=FALSE} 143 | seltable = seltable[,c("Model", "Residual.df", "Adj.R2", "RMSE", "AIC", "LOOCV")] 144 | colnames(seltable) <- c("Model", "Resid. df", "Adj. R2", "RMSE", "AICc", "LOOCV") 145 | if(isLatex) colnames(seltable)=c("Model", "\\shortstack{Resid.\\\\df}", "\\shortstack{Adj.\\\\$R^2$}", "RMSE", "AICc", "\\shortstack{LOOCV\\\\RMSE}") 146 | 147 | thecap=paste("Top covariates for the monsoon (Jul-Sep) and post-monsoon (Oct-Mar) catch ($S_t$ and $N_t$) models. M is the base models with only prior catch as covariates. To the base models, the environmental covariates are added. ns-SST is nearshore (0-80km) and r-SST is regional (0-160km). The full set of nested covariate models and tests are given in the appendices.", sep="") 148 | fullcap=paste("Table ", ref("tab:covariate-models"), ". ", thecap, sep="") 149 | kable(seltable, align=paste0("l", paste0(rep("c",dim(seltable)[2]-1),collapse="")), caption=fullcap, escape=FALSE) 150 | ``` 151 | 152 | Notes: The nested F-tests are given in Supporting Information. LOOCV = Leave one out cross-validation. RMSE = root mean square error. AICc = Akaike Information Criterion corrected for small sample size. $\dagger$ and $\dagger\dagger$ = AICc greater than 2 and greater than 5 below model M (base catch model). $\ddagger$, $\ddagger\ddagger$, and ${\ddagger}{\ddagger}{\ddagger}$ = LOOCV RMSE 5\%, 10\% and 20\% below model M, respectively. $t$ indicates current season (Jul-Jun). For covariates that are multiyear, $t$ is the current calendar year. -------------------------------------------------------------------------------- /Figures.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | pdf_document: default 4 | html_document: 5 | keep_md: true 6 | word_document: default 7 | header-includes: \usepackage[labelformat=empty]{caption} 8 | --- 9 | 10 | ```{r child = 'setup.Rmd'} 11 | ``` 12 | 13 | ```{r echo=FALSE} 14 | # Note not all the figures are shown. I have cut some out to shorten the file 15 | ``` 16 | 17 | ```{r eval=FALSE} 18 | # set eval=FALSE to not evaluate, but for paper submission, I run this to save the dpi=300 19 | # requested by the journal 20 | library(knitr) 21 | opts_chunk$set(dev="postscript", 22 | dpi=300) 23 | ``` 24 | 25 | ```{r} 26 | # This will save the figures to the folder figures 27 | library(knitr) 28 | opts_chunk$set(fig.path='figures/', dev=c('png'), 29 | dpi=300) 30 | ``` 31 | 32 | ```{r, results="asis", echo=FALSE} 33 | cat("\\clearpage") 34 | ``` 35 | 36 | ```{r echo=FALSE} 37 | thecap <- paste("Figure", ref("fig:studyarea")) 38 | ``` 39 | 40 | ```{r fig-study-area, out.width = "350px", fig.align='center', echo=FALSE, fig.cap=thecap, message=FALSE, warning=FALSE} 41 | figfile = file.path(here::here(), "figures/kerala_study_area_with_inset.jpg") 42 | knitr::include_graphics(figfile) 43 | ``` 44 | 45 | ```{r, results="asis", echo=FALSE} 46 | cat("\\clearpage") 47 | ``` 48 | 49 | ```{r fig-qtrly-catch, echo=FALSE,fig.cap=paste("Figure", ref("fig:catch")), fig.width=8,fig.height=6,message=FALSE,warning=FALSE} 50 | par(mfrow = c(1, 1), mar = c(5, 5, 1, 5)) 51 | dat <- oilsardine_qtr 52 | plot(ts(dat$Kerala / 1000, start = 1956, frequency = 4), ylab = "Quarterly Kerala Catch (1000 kg)", xlab = "", bty = "L", ylim = c(0, 200)) 53 | oldpar <- par(fig = c(0.5, 1, 0.55, .97), new = TRUE) 54 | catchmeans <- tapply(dat$Kerala, dat$Qtr, mean, na.rm = TRUE) 55 | names(catchmeans) <- c("JFM", "AMJ", "JAS", "OND") 56 | barplot(catchmeans / 1000, 57 | ylab = "", col = "grey", cex.axis = .75, 58 | cex.names = .75, line = -1, yaxt = "n", border = NA 59 | ) 60 | axis(2) 61 | box(bty = "L") 62 | title("Mean Quarterly Catch", cex.main = .75) 63 | par(oldpar) 64 | ``` 65 | 66 | ```{r, results="asis", echo=FALSE} 67 | cat("\\clearpage") 68 | ``` 69 | 70 | ```{r sst.mon, eval=FALSE, echo=FALSE,fig.cap=paste("Figure", ref("fig:SSTts")), fig.width=8,fig.height=5,message=FALSE,warning=FALSE} 71 | ### FIGURE SST 72 | oldpar=par(mfrow=c(1,1), mar=c(2,4,2,0)) 73 | i=4 74 | covname=paste("SST.",i,sep="") 75 | dat=covariates[[covname]] 76 | datmon=covariates$Month 77 | datts=ts(dat,start=1956, frequency=12) 78 | plot(datts,ylab="Ave Monthly SST",xlab="",bty="n",ylim=c(24,31),xlim=c(2000,2005), yaxs="i", xaxs="i") 79 | ``` 80 | 81 | ```{r sst.mon2, echo=FALSE,fig.cap=paste("Figure", ref("fig:SSTts")), fig.width=8.5,fig.height=6,message=FALSE,warning=FALSE} 82 | par(mfrow=c(1,1), mar=c(2,4,1,4)) 83 | yrs=c(2010) 84 | nyr=3 85 | ymin=23; ymax=31 86 | desc.cex = .75 87 | for(start in yrs){ 88 | i=4 89 | covname=paste("SST.",i,sep="") 90 | dat=covariates[[covname]] 91 | datts1=window(ts(dat,start=1956, frequency=12),start=c(start,1), end=c(start+nyr,12)) 92 | dat1=as.vector(datts1) 93 | i=11 94 | covname=paste("SST.",i,sep="") 95 | dat=covariates[[covname]] 96 | datts2=window(ts(dat,start=1956, frequency=12),start=c(start,1), end=c(start+nyr,12)) 97 | dat2=as.vector(datts2) 98 | plot(dat1, ylim=c(ymin,ymax), xaxt="n",type="l",lwd=2,col="red",ylab="",xlab="") 99 | #axis(1,at=seq(1,12*(nyr+1),12),labels=start:(start+nyr)) 100 | axis(1,at=1:length(dat1),labels=rep(str_sub(month.name,1,1),nyr+1),cex.axis=.5,line=-.75,lwd=-1,lwd.ticks=-1) 101 | axis(1,at=1:length(dat1),labels=FALSE) 102 | abline(v=seq(1,12*(nyr+1),12)) 103 | axis(1,at=seq(7,12*(nyr+1),12),labels=start:(start+nyr),cex.axis=.75,lwd=-1,lwd.ticks=-1) 104 | lines(dat2, col="black", lwd=1) 105 | legend(length(dat2)-11.5,ymin+3,c("SST nearshore","SST offshore","Chl-a"), lwd=c(2,1,10),col=c("red","black","#228B22"),bty="n",cex=1,seg.len=1) 106 | 107 | lev=ymax; jit=.3 108 | cols=c("black","green","blue","red") 109 | j=1 110 | lines(c(j+1,j+2),c(lev,lev)-jit,lwd=8,lend=2,col=adjustcolor(cols[1], alpha.f=.2)) #juv peak 111 | lines(c(j+6.5,j+7.5),c(lev,lev)-jit,lwd=8,lend=2,col=cols[1]) #juv peak 2 112 | text(j+6,lev,"juveniles appear in catch",cex=desc.cex) 113 | 114 | j=13 115 | lines(c(j+7,j+9),c(lev,lev)-jit,lwd=8,col=cols[2],lend=2) #highest growth 116 | text(j+6,lev,"highest somatic growth",cex=desc.cex) 117 | 118 | j=25 119 | lines(c(j+5,j+10),c(lev,lev)-jit,lwd=8,col=adjustcolor("blue", alpha.f=.2),lend=2) #spawning 120 | lines(c(j+5,j+6),c(lev,lev)-jit,lwd=8,col="blue",lend=2) #spawning 121 | text(j+6,lev,"spawning",cex=desc.cex) 122 | 123 | j=37 124 | lines(c(j+2,j+4),c(lev,lev)-jit,lwd=8,col=cols[4],lend=2) #bad 125 | text(j+6,lev,"fish move offshore",cex=desc.cex) 126 | 127 | dat=covariates[["CHL.4"]] 128 | datts1=window(ts(dat,start=1956, frequency=12),start=c(start,1), end=c(start+nyr,12)) 129 | dat1=as.vector(datts1) 130 | TT=length(dat1) 131 | tdat1=1:length(dat1) 132 | tdat1=tdat1[!is.na(dat1)] 133 | dat1=na.omit(dat1) 134 | par(new=TRUE) 135 | plot(tdat1,dat1,type="n",axes=FALSE,ylab="",xlab="",ylim=c(0,40)) 136 | polygon( 137 | c(tdat1,TT,1,1), 138 | c(dat1,0,0,dat1[1]), 139 | col="#228B22", border=NA) 140 | axis(side=4) 141 | mtext(side = 4, line = 2.25, expression('Surface chlorophyll-a (Chl-a mg m'^"-3"*')')) 142 | mtext(side = 2, line = 2.25, expression('Average monthly SST ('*degree*'C)')) 143 | } 144 | ``` 145 | 146 | ```{r, results="asis", echo=FALSE} 147 | cat("\\clearpage") 148 | ``` 149 | 150 | 151 | 152 | ```{r cov-effects, echo=FALSE,fig.cap=paste("Figure", ref("fig:cov-effects")), fig.width=8,fig.height=9,message=FALSE,warning=FALSE} 153 | oldpar <- par(mfcol = c(3, 2), mar = c(5, 4, 2, 2)) 154 | ylims <- c(-3, 2) 155 | dat <- dat.spawners 156 | dat <- subset(dat, Year > 1982 & Year < 2016) 157 | covnames <- c("SST.2.5.3.yr.runsum.0", "SST.UPW.4.mon6to9.0", "Precip.Kerala.mon6to7.0") 158 | dat$cov0 <- dat[["SST.2.5.3.yr.runsum.0"]] 159 | dat$cov1 <- dat[["SST.UPW.4.mon6to9.0"]] 160 | dat$cov2 <- dat[["Precip.Kerala.mon6to7.0"]] 161 | m1 <- gam(spawners0 ~ s(nspawners1, sp = 0.6) + s(cov0, sp = 0.6), data = dat) 162 | m2 <- gam(spawners0 ~ s(nspawners1, sp = 0.6) + s(cov1, sp = 0.6), data = dat) 163 | m3 <- gam(spawners0 ~ s(nspawners1, sp = 0.6) + s(cov2, sp = 0.6), data = dat) 164 | xl <- expression("2.5-year average SST (" * degree * "C)") 165 | plot(m1, select = 2, xlab = xl, ylab = "Effect", ylim = ylims) 166 | # legend("topright","A", bty="n") 167 | legend("topleft", "Jul-Sep catch", bty = "n") 168 | abline(h = 0, col = "grey") 169 | plot(m2, select = 2, xlab = "Jun-Sep SST-derived upwelling index", ylab = "Effect", ylim = ylims) 170 | # legend("topright","B", bty="n") 171 | text(1.25, -3, "high upwelling", pos = 4) 172 | text(0, -3, "low upwelling", adj = 0) 173 | abline(h = 0, col = "grey") 174 | legend("topleft", "Jul-Sep catch", bty = "n") 175 | plot(m2, select = 2, xlab = "Jun-Jul land precipitation (mm/day)", ylab = "Effect", ylim = ylims) 176 | # legend("topright","B", bty="n") 177 | abline(h = 0, col = "grey") 178 | legend("topleft", "Jul-Sep catch", bty = "n") 179 | 180 | dat <- dat.spawners 181 | dat <- subset(dat, Year > 1982 & Year < 2016) 182 | covnames <- c("SST.2.5.3.yr.runsum.0", "SST.UPW.4.mon6to9.0", "Precip.Kerala.mon6to7.0", ylim = ylims) 183 | dat$cov0 <- dat[[covnames[1]]] 184 | dat$cov1 <- dat[[covnames[2]]] 185 | dat$cov2 <- dat[[covnames[3]]] 186 | m1 <- gam(nspawners0 ~ s(nspawners1, sp = 0.6) + s(spawners2, sp = 0.6) + s(cov0, sp = 0.6), data = dat) 187 | m2 <- gam(nspawners0 ~ s(nspawners1, sp = 0.6) + s(spawners2, sp = 0.6) + s(cov1, sp = 0.6), data = dat) 188 | m3 <- gam(nspawners0 ~ s(nspawners1, sp = 0.6) + s(spawners2, sp = 0.6) + s(cov2, sp = 0.6), data = dat) 189 | xl <- expression("2.5-year average SST (" * degree * "C)") 190 | plot(m1, select = 3, xlab = xl, ylab = "Effect", ylim = ylims) 191 | # legend("topright","C", bty="n") 192 | legend("topleft", "Oct-Mar catch", bty = "n") 193 | abline(h = 0, col = "grey") 194 | plot(m2, select = 3, xlab = "Jun-Sep SST-derived upwelling index", ylab = "Effect", ylim = ylims) 195 | # legend("topright","D", bty="n") 196 | legend("topleft", "Oct-Mar catch", bty = "n") 197 | abline(h = 0, col = "grey") 198 | # abline(v=0, col="blue") 199 | text(1.25, -3, "high upwelling", pos = 4) 200 | text(0, -3, "low upwelling", adj = 0) 201 | plot(m3, select = 3, xlab = "Jun-Jul land precipitation (mm/day)", ylab = "Effect", ylim = ylims) 202 | # legend("topright","D", bty="n") 203 | legend("topleft", "Oct-Mar catch", bty = "n") 204 | abline(h = 0, col = "grey") 205 | 206 | par(oldpar) 207 | ``` 208 | 209 | ```{r, results="asis", echo=FALSE} 210 | cat("\\clearpage") 211 | ``` 212 | -------------------------------------------------------------------------------- /AppendixFiles/Appendix-Functions.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Appendices: Common Functions' 3 | output: 4 | pdf_document: default 5 | html_document: default 6 | word_document: default 7 | --- 8 | 9 | ```{r echo=FALSE} 10 | # These are the table functions. 11 | # I want to use a standardized format for each appendix table 12 | # so I put the function here and call it. 13 | # I could also save this as a script and source it. 14 | ``` 15 | 16 | ```{r echo=FALSE} 17 | covfun <- function(mod, eqn, NE=NA, baseaic=-Inf, baseloo=-Inf, baseloomae=-Inf, baseloomd=-Inf, digits=3){ 18 | # a is anova(m1, m2, etc 19 | aa = summary(mod) 20 | modrmse <- SardineForecast:::loogam(mod)$RMSE 21 | ddag <- "" 22 | if(modrmse < 0.95*baseloo) ddag <- "$\\ddagger$" 23 | if(modrmse < 0.9*baseloo) ddag <- "$\\ddagger\\ddagger$" 24 | if(modrmse < 0.8*baseloo) ddag <- "${\\ddagger}{\\ddagger}{\\ddagger}$" 25 | #if(modrmse < 0.7*baseloo) ddag <- "${\\ddagger}{\\ddagger}{\\ddagger}{\\ddagger}$" 26 | 27 | modrmse <- SardineForecast:::loogam(mod)$MdAE 28 | ddag2 <- "" 29 | if(modrmse < 0.95*baseloomd) ddag2 <- "$\\ddagger$" 30 | if(modrmse < 0.9*baseloomd) ddag2 <- "$\\ddagger\\ddagger$" 31 | if(modrmse < 0.8*baseloomd) ddag2 <- "${\\ddagger}{\\ddagger}{\\ddagger}$" 32 | 33 | modaic <- SardineForecast::AICc(mod) 34 | dag <- "" 35 | if(modaic < baseaic-2) dag <- "$\\dagger$" 36 | if(modaic < baseaic-5) dag <- "$\\dagger\\dagger$" 37 | tmp1=data.frame( 38 | Model=eqn, 39 | Residual.df=round(mod$df.residual,digits=1), 40 | MASE=round(mean(abs(residuals(mod)))/NE,digits=digits), 41 | MAE=round(mean(abs(residuals(mod))),digits=digits), 42 | RMSE=round(sqrt(mean((residuals(mod))^2)),digits=digits), 43 | LOOCV=paste0(round(SardineForecast:::loogam(mod)$RMSE, digits=digits), ddag), 44 | Adj.R2=100*round(aa$r.sq, digits=3), 45 | AIC=paste0(round(SardineForecast::AICc(mod), digits=1),dag), 46 | LOOMd=paste0(round(SardineForecast:::loogam(mod)$MdAE, digits=digits), ddag2), 47 | LOOMAE=paste0(round(SardineForecast:::loogam(mod)$MAE, digits=digits), "")) 48 | return(tmp1) 49 | } 50 | 51 | modfun <- function(mod, eqn, NE=NA, digits=3){ 52 | aa = summary(mod) 53 | tmp1=data.frame( 54 | Model=eqn, 55 | Residual.df=round(mod$df.residual,digits=1), 56 | MASE=round(mean(abs(residuals(mod)))/NE,digits=digits), 57 | MAE=round(mean(abs(residuals(mod))),digits=digits), 58 | RMSE=round(sqrt(mean((residuals(mod))^2)),digits=digits), 59 | LOOCV=round(SardineForecast:::loogam(mod)$RMSE, digits=digits), 60 | Adj.R2=100*round(aa$r.sq, digits=3), 61 | AIC=round(AICc(mod), digits=1), 62 | LOOMd=round(SardineForecast:::loogam(mod)$MdAE, digits=digits), 63 | LOOMAE=round(SardineForecast:::loogam(mod)$MAE, digits=digits), 64 | stringsAsFactors=FALSE) 65 | return(tmp1) 66 | } 67 | 68 | ## Header 69 | getmodheader <- function(dat){ 70 | Yr1 <- min(dat$Year) 71 | Yr2 <- max(dat$Year) 72 | knitOut=knitr::opts_knit$get("rmarkdown.pandoc.to") 73 | if(length(knitOut)==0) isLatex=FALSE else isLatex=(knitOut=="latex") 74 | 75 | space <- " " 76 | if(isLatex) space <- "\\kern 1em" 77 | return(data.frame( 78 | Model=paste("catch only models ", Yr1,"-", Yr2, " data", sep=""), 79 | Residual.df=space, 80 | MASE=space, 81 | MAE=space, RMSE=space, 82 | LOOCV=space, 83 | Adj.R2=space, AIC=space, 84 | LOOMd=space, LOOMAE=space, 85 | stringsAsFactors=FALSE)) 86 | } 87 | 88 | getmodheadertext <- function(text){ 89 | #detect if making latex 90 | knitOut=knitr::opts_knit$get("rmarkdown.pandoc.to") 91 | if(length(knitOut)==0) isLatex=FALSE else isLatex=(knitOut=="latex") 92 | 93 | space <- " " 94 | if(isLatex) space <- "\\kern 1em" 95 | return(data.frame( 96 | Model=text, 97 | Residual.df=space, 98 | MASE=space, 99 | MAE=space, RMSE=space, 100 | LOOCV=space, 101 | Adj.R2=space, AIC=space, 102 | LOOMd=space, LOOMAE=space, 103 | stringsAsFactors=FALSE)) 104 | } 105 | 106 | # Space 107 | knitOut=knitr::opts_knit$get("rmarkdown.pandoc.to") 108 | if(length(knitOut)==0) isLatex=FALSE else isLatex=(knitOut=="latex") 109 | 110 | space <- " " 111 | if(isLatex) space <- "\\kern 1em" 112 | spacetmp = data.frame(Model=space, Residual.df=space, MASE=space, MAE=space, RMSE=space, LOOCV=space, Adj.R2=space, AIC=space, LOOMd=space, LOOMAE=space, stringsAsFactors=FALSE) 113 | 114 | # Get names 115 | getcovtit <- function(covname){ 116 | if(covname=="SST.4.mon10to12.") covtit = "$V_t$ = Oct-Dec SST (L1)" 117 | if(covname=="SST.2.5.mon6to9.") covtit = "$V_t$ = Jun-Sep ns-SST (L2)" 118 | if(covname=="SST.2.5.mon9to10.") covtit = "$V_t$ = Sep-Oct ns-SST (L1)" 119 | if(covname=="SST.2.10.mon3to5.") covtit = "$V_t$ = Mar-May r-SST (S5)" 120 | if(covname=="SST.4.mon7to9.") covtit = "$V_t$ = Jul-Sep SST" 121 | if(covname=="SST.4.mon6to9.") covtit = "$V_t$ = Jun-Sep SST" 122 | if(covname=="SST.4.mon7to12.") covtit = "$V_t$ = Jul-Dec SST" 123 | if(covname=="SST.4.mon1to3.") covtit = "$V_t$ = Jan-Mar SST" 124 | if(covname=="SST.4.mon1to12.") covtit = "$V_t$ = Jan-Dec SST" 125 | if(covname=="SST.4.mon9to10.") covtit = "$V_t$ = Sep-Oct SST" 126 | if(covname=="SST.4.mon1to12.") covtit = "$V_t$ = Jan-Dec SST" 127 | if(covname=="SST.2.10.mon7to12.") covtit = "$V_t$ = Jul-Dec r-SST" 128 | if(covname=="precip.gpcp.kerala.mon6to7.") covtit = "$V_t$ = Jun-Jul Precipitation - satellite (S1)" 129 | if(covname=="Precip.Kerala.mon4to5.") covtit = "$V_t$ = Apr-May Precipitation - land gauges (S2)" 130 | if(covname=="Precip.Kerala.mon6to7.") covtit = "$V_t$ = Jun-Jul Precipitation - land gauges (S1)" 131 | if(covname=="precip.gpcp.kerala.mon4to5.") covtit = "$V_t$ = Apr-May Precipitation - satellite (S2)" 132 | if(covname=="SST.2.5.mon10to12.") covtit = "$V_t$ = Oct-Dec ns-SST (L1)" 133 | if(covname=="Bakun.UPW.mon6to9.") covtit = "$V_t$ = Jun-Sep Bakun-UPW (L2)" 134 | if(covname=="Wind.UPW.4.mon6to9.") covtit = "$V_t$ = Jun-Sep Wind-UPW (L2)" 135 | if(covname=="SST.UPW.4.mon6to9.") covtit = "$V_t$ = Jun-Sep SST-derived UPW (L2)" 136 | if(covname=="SST.2.5.mon6to9.") covtit = "$V_t$ = Jun-Sep ns-SST (L2)" 137 | if(covname=="SST.2.10.3.yr.runsum.") covtit = "$V_t$ = 2.5-year average r-SST - AVHRR (A1)" 138 | if(covname=="SST.11.13.3.yr.runsum.") covtit = "$V_t$ = 2.5-year average fo-SST (A1)" 139 | if(covname=="SST.7.10.3.yr.runsum.") covtit = "$V_t$ = 2.5-year average o-SST (A1)" 140 | if(covname=="SST.7.13.3.yr.runsum.") covtit = "$V_t$ = 2.5-year ave o-SST (A1)" 141 | if(covname=="SST.2.5.3.yr.runsum.") covtit = "$V_t$ = 2.5-year avereage ns-SST (A1)" 142 | if(covname=="SST.1.13.3.yr.runsum.") covtit = "$V_t$ = 2.5-year average rr-SST (A1)" 143 | if(covname=="SSTICOAD.2.10.3.yr.runsum.") covtit = "$V_t$ = 2.5-year average r-SST (A1)" 144 | if(covname=="ONI.mon1to12.") covtit = "$V_t$ = ONI (A2)" 145 | if(covname=="DMI.mon9to11.") covtit = "$V_t$ = Sep-Nov DMI (A3)" 146 | if(covname=="DMI.mon6to9.") covtit = "$V_t$ = Jun-Sep DMI (A3)" 147 | if(covname=="DMI.3.yr.runsum.") covtit = "$V_t$ = DMI 2.5-year average (A3)" 148 | if(covname=="log.CHL.4.mon1to3.") covtit = "$V_t$ = Jan-Mar Chlorophyll" 149 | if(covname=="log.CHL.4.mon7to9.") covtit = "$V_t$ = Jul-Sep Chlorophyll (L3)" 150 | if(covname=="log.CHL.4.mon10to12.") covtit = "$V_t$ = Oct-Dec Chlorophyll (L3)" 151 | if(covname=="log.CHL.2.5.mon1to3.") covtit = "$V_t$ = Jan-Mar ns-CHL" 152 | if(covname=="log.CHL.2.5.mon7to9.") covtit = "$V_t$ = Jul-Sep ns-CHL (L3)" 153 | if(covname=="log.CHL.2.5.mon10to12.") covtit = "$V_t$ = Oct-Dec ns-CHL (L3)" 154 | if(covname=="tide.level.interp.mon6to9.") covtit = "$V_t$ = Jun-Sep tide level" 155 | if(covname=="tide.level.interp.mon1to12.") covtit = "$V_t$ = Jan-Dec tide level" 156 | if(covname=="tide.level.interp.mon9to11.") covtit = "$V_t$ = Sep-Nov tide level" 157 | if(covname=="tide.level.interp.mon8to8.") covtit = "$V_t$ = Aug tide level at Kochi (A3)" 158 | if(covname=="tide.level.interp.mon9to9.") covtit = "$V_t$ = Sep tide level at Kochi (A3)" 159 | if(covname=="tide.level.interp.mon7to8.") covtit = "$V_t$ = Jul-Aug tide level at Kochi (A3)" 160 | if(covname=="anomalies.mon6to9.") covtit = "$V_t$ = Jun-Sep tide level anomalies at Kochi (A3)" 161 | 162 | return(covtit) 163 | } 164 | ``` 165 | 166 | ```{r, echo=FALSE} 167 | makeapptable <- function(dat, nullmod, basemod, nullformula, baseformula, resp, covnamelist, covlags, m3form = "s(cov, sp=0.6)", type=c("linear", "nonlinear"), include.num=TRUE, header=NULL, include.group=TRUE, compact=FALSE){ 168 | 169 | if(missing(header)) seltable <- getmodheader(dat) 170 | if(!missing(header)) seltable <- getmodheadertext(header) 171 | 172 | # Null model 173 | m0 = lm(as.formula(nullformula), data=dat) 174 | mod <- "m0" 175 | Model=paste0("null model: ", nullmod) 176 | tmp1 <- modfun(get(mod), Model) 177 | tmp1$Adj.R2 <- "" 178 | modtable <- tmp1 179 | # Base model 180 | m1 = gam(as.formula(baseformula), data=dat) 181 | mod <- "m1" 182 | num <- ifelse(include.num, " 1.", "") 183 | Model <- paste0("base (M):", num, " ", basemod) 184 | tmp1 <- modfun(get(mod), Model) 185 | modtable=rbind(modtable,tmp1) 186 | baseaic <- SardineForecast::AICc(m1) 187 | lg <- SardineForecast::loogam(m1) 188 | baseloo <- lg$RMSE 189 | baseloomae <- lg$MAE 190 | baseloomd <- lg$MdAE 191 | 192 | seltable <- rbind(seltable, modtable) 193 | 194 | seltable=rbind(seltable, spacetmp) 195 | 196 | for(covgroup in names(covnamelist)){ 197 | #Group header 198 | tmp1 <- spacetmp; tmp1$Model <- paste0("**", covgroup, "**") 199 | if(include.group) seltable = rbind(seltable, tmp1, spacetmp) 200 | 201 | for(covname in covnamelist[[covgroup]]){ 202 | #var header 203 | covtit <- getcovtit(covname) 204 | tmp1 <- spacetmp; tmp1$Model <- covtit 205 | seltable = rbind(seltable, tmp1) 206 | 207 | for(i in 1:length(covlags[[covname]])){ 208 | lag <- covlags[[covname]][i] 209 | let <- letters[i] 210 | tlab <- ifelse(lag==0, "t", "t-1") 211 | dat$cov=dat[[paste(covname, lag, sep="")]] 212 | m1 = gam(as.formula(baseformula), data=dat) 213 | m2 = gam(as.formula(paste(baseformula, "+ cov")), data=dat) 214 | m3 = gam(as.formula(paste(baseformula, "+", m3form)), data=dat) 215 | 216 | if("linear" %in% type){ 217 | mod <- "m2" 218 | num <- ifelse(include.num, paste0("2",let,". "), " ") 219 | Model=paste0(num, "$", resp, "$ = M + $\\beta V_{", tlab,"}$") 220 | tmp1 <- covfun(get(mod), Model, baseaic=baseaic, baseloo=baseloo, baseloomae=baseloomae, baseloomd=baseloomd) 221 | seltable=rbind(seltable,tmp1) 222 | } 223 | 224 | if("nonlinear" %in% type){ 225 | num <- ifelse(include.num, paste0("3",let,". "), " ") 226 | mod <- "m3" 227 | covf <- ifelse(stringr::str_detect(m3form, "poly"),"p","s") 228 | Model <- paste0(num, "$", resp, "$ = M + $", covf, "(V_{", tlab, "})$") 229 | tmp1 <- covfun(get(mod), Model, baseaic=baseaic, baseloo=baseloo, baseloomae=baseloomae, baseloomd=baseloomd) 230 | seltable=rbind(seltable,tmp1) 231 | } 232 | } 233 | if(!compact) seltable <- rbind(seltable, spacetmp) 234 | } 235 | } 236 | seltable 237 | } 238 | ``` 239 | 240 | ```{r, echo=FALSE} 241 | maketable3 <- function(dat, nullmod, basemod, nullformula, baseformula, resp, covnamelist, covlags, m3form = "s(cov, sp=0.6)", type=c("linear", "nonlinear"), include.num=TRUE, header=NULL, include.group=TRUE, compact=FALSE){ 242 | 243 | seltable <- getmodheadertext(header) 244 | 245 | # Null model 246 | m0 = lm(as.formula(nullformula), data=dat) 247 | mod <- "m0" 248 | Model=paste0("null model: ", nullmod) 249 | tmp1 <- modfun(get(mod), Model, digits=2) 250 | tmp1$Adj.R2 <- "" 251 | modtable <- tmp1 252 | # Base model 253 | m1 = gam(as.formula(baseformula), data=dat) 254 | mod <- "m1" 255 | num <- ifelse(include.num, " 1.", "") 256 | Model <- paste0("base (M):", num, " ", basemod) 257 | tmp1 <- modfun(get(mod), Model, digits=2) 258 | modtable=rbind(modtable,tmp1) 259 | baseaic <- SardineForecast::AICc(m1) 260 | lg <- SardineForecast::loogam(m1) 261 | baseloo <- lg$RMSE 262 | baseloomae <- lg$MAE 263 | baseloomd <- lg$MdAE 264 | # covariate model 265 | if("linear" %in% type){ 266 | Model=paste0("linear covariate model: $", resp, "$ = M + $\\beta V_t$") 267 | tmp1 <- getmodheadertext(Model) 268 | modtable=rbind(modtable,tmp1) 269 | } 270 | if("nonlinear" %in% type){ 271 | covf <- ifelse(stringr::str_detect(m3form, "poly"),"p","s") 272 | Model <- paste0("nonlinear covariate model: $", resp, "$ = M + $", covf, "(V_t)$") 273 | tmp1 <- getmodheadertext(Model) 274 | modtable=rbind(modtable,tmp1) 275 | } 276 | 277 | 278 | seltable <- rbind(seltable, modtable) 279 | 280 | seltable=rbind(seltable, spacetmp) 281 | 282 | for(covgroup in names(covnamelist)){ 283 | 284 | for(covname in covnamelist[[covgroup]]){ 285 | #var header 286 | covtit <- getcovtit(covname) 287 | covtit <- stringr::str_remove(covtit, "$V_t$ = ") 288 | 289 | for(i in 1:length(covlags[[covname]])){ 290 | lag <- covlags[[covname]][i] 291 | let <- letters[i] 292 | tlab <- ifelse(lag==0, "t", "t-1") 293 | dat$cov=dat[[paste(covname, lag, sep="")]] 294 | m1 = gam(as.formula(baseformula), data=dat) 295 | m2 = gam(as.formula(paste(baseformula, "+ cov")), data=dat) 296 | m3 = gam(as.formula(paste(baseformula, "+", m3form)), data=dat) 297 | 298 | if("linear" %in% type){ 299 | mod <- "m2" 300 | Model <- covtit 301 | tmp1 <- covfun(get(mod), Model, baseaic=baseaic, baseloo=baseloo, baseloomae=baseloomae, baseloomd=baseloomd, digits=2) 302 | seltable=rbind(seltable,tmp1) 303 | } 304 | 305 | if("nonlinear" %in% type){ 306 | mod <- "m3" 307 | Model <- covtit 308 | tmp1 <- covfun(get(mod), Model, baseaic=baseaic, baseloo=baseloo, baseloomae=baseloomae, baseloomd=baseloomd, digits=2) 309 | seltable=rbind(seltable,tmp1) 310 | } 311 | } 312 | if(!compact) seltable <- rbind(seltable, spacetmp) 313 | } 314 | if(compact) seltable <- rbind(seltable, spacetmp) 315 | } 316 | seltable 317 | } 318 | ``` 319 | -------------------------------------------------------------------------------- /SupplementFiles/Table App A spawner model.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Table A2 a-c" 3 | output: 4 | pdf_document: default 5 | html_document: default 6 | word_document: default 7 | header-includes: \usepackage[labelformat=empty]{caption} 8 | --- 9 | 10 | ```{r child = file.path(here::here(),'setup.Rmd')} 11 | ``` 12 | 13 | ```{r echo=FALSE} 14 | #set the table pre 15 | if(Supplement){ 16 | pre <- "S" 17 | tabset <- "tabsupp:" 18 | }else{ 19 | pre <- "A" 20 | tabset <- "tabappA:" 21 | } 22 | ``` 23 | 24 | ```{r child = file.path(here::here(),'AppendixFiles','Appendix-Variables.Rmd')} 25 | ``` 26 | 27 | ```{r table-appA-set-spawner-years, echo=FALSE} 28 | #dat.spawners defined in setup-covariates.Rmd 29 | vars <- getspawnercovs() 30 | datcommon <- dat.spawners[, 31 | c("Year", "spawners0", "spawners1", "spawners2", 32 | "nspawners1", "nspawners2", vars$allcovnames)] 33 | dat <- na.omit(datcommon) 34 | Yr1 = min(dat$Year) 35 | Yr2 = max(dat$Year) 36 | 37 | #naive model error 38 | #def of MASE is MAE/naive error 39 | NE=mean(abs(dat$spawners0-dat$spawners1)) 40 | ``` 41 | 42 | ```{r seltableA1a, echo=FALSE} 43 | respdat = dat 44 | 45 | seltable = data.frame( 46 | Model=paste("Naive Model ", min(respdat$Year),"-", max(respdat$Year), " data", sep=""), 47 | Residual.df="", 48 | MASE="", 49 | Adj.R2="", 50 | F="", 51 | p.value="", 52 | AIC="", 53 | LOOCV="", 54 | stringsAsFactors=FALSE) 55 | 56 | #5 is most complex 57 | m5 = gam(spawners0 ~ spawners1+spawners2, data=respdat) 58 | m1 = lm(spawners0 ~ -1 + offset(spawners1), data=m5$model) 59 | 60 | #Naive model 61 | i=1; mod=paste("m",i,sep="") 62 | aa = summary(get(mod)) 63 | tmp1=data.frame( 64 | Model="$ln(S_t)$ = $ln(S_{t-1})$ + $\\epsilon_t$", 65 | Residual.df=round(aa[["df"]][2],digits=1), 66 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 67 | Adj.R2="", 68 | F="", p.value="", 69 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 70 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 71 | ) 72 | seltable=rbind(seltable,tmp1) 73 | 74 | ## Space 75 | tmp1 = data.frame( 76 | Model="\\kern 1em", 77 | Residual.df="\\kern 1em", 78 | MASE="\\kern 1em", 79 | Adj.R2="", 80 | F="\\kern 1em", 81 | p.value="\\kern 1em", 82 | AIC="", LOOCV="") 83 | tmp2 = data.frame( 84 | Model=paste("Time dependency test A ", min(respdat$Year),"-", max(respdat$Year), " data", sep=""), 85 | Residual.df="", 86 | MASE="", 87 | Adj.R2="", 88 | F="", 89 | p.value="", 90 | AIC="", 91 | LOOCV="" 92 | ) 93 | seltable=rbind(seltable,tmp1,tmp2) 94 | 95 | #5 is most complex 96 | m5 = gam(spawners0 ~ spawners1+spawners2, data=respdat) 97 | m0=m5 98 | m1 = gam(spawners0 ~ offset(spawners1), data=m0$model) 99 | m2 = gam(spawners0 ~ spawners1, data=m0$model) 100 | m3 = gam(spawners0 ~ spawners1 + spawners2, data=m0$model) 101 | a=anova(m1,m2,m3, test="F") 102 | 103 | #simple model 104 | i=1; mod=paste("m",i,sep="") 105 | aa = summary(get(mod)) 106 | tmp1=data.frame( 107 | Model="1. $ln(S_t)$ = $\\alpha$ + $ln(S_{t-1})$ + $\\epsilon_t$", 108 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 109 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 110 | Adj.R2=100*round(aa$r.sq, digits=3), 111 | F="", p.value="", 112 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 113 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 114 | ) 115 | seltable=rbind(seltable,tmp1) 116 | 117 | #linear ln N_t 118 | i=2; mod=paste("m",i,sep="") 119 | aa = summary(get(mod)) 120 | tmp1=data.frame( 121 | Model="2. $ln(S_t)$ = $\\alpha$ + $\\beta ln(S_{t-1})$ + $\\epsilon_t$", 122 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 123 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 124 | Adj.R2=100*round(aa$r.sq, digits=3), 125 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 126 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 127 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 128 | ) 129 | seltable=rbind(seltable,tmp1) 130 | 131 | #linear ln Catch1 + ln Catch2 132 | i=3; mod=paste("m",i,sep="") 133 | aa = summary(get(mod)) 134 | tmp1=data.frame( 135 | Model="3. $ln(S_t)$ = $\\alpha$ + $\\beta_1 ln(S_{t-1})$ + $\\beta_2 ln(S_{t-2})$ + $\\epsilon_t$", 136 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 137 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 138 | Adj.R2=100*round(aa$r.sq, digits=3), 139 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 140 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 141 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 142 | ) 143 | seltable=rbind(seltable,tmp1) 144 | 145 | ## Space 146 | tmp1 = data.frame( 147 | Model="\\kern 1em", 148 | Residual.df="\\kern 1em", 149 | MASE="\\kern 1em", 150 | Adj.R2="", 151 | F="\\kern 1em", 152 | p.value="\\kern 1em", 153 | AIC="", LOOCV="") 154 | tmp2 = data.frame( 155 | Model=paste("Time dependency test B ", min(respdat$Year),"-", max(respdat$Year), " data", sep=""), 156 | Residual.df="", 157 | MASE="", 158 | Adj.R2="", 159 | F="", 160 | p.value="", 161 | AIC="", LOOCV="") 162 | seltable=rbind(seltable,tmp1,tmp2) 163 | 164 | #5 is most complex 165 | m5 = gam(spawners0 ~ nspawners1+nspawners2, data=respdat) 166 | m0=m5 167 | m1 = gam(spawners0 ~ offset(nspawners1), data=m0$model) 168 | m2 = gam(spawners0 ~ nspawners1, data=m0$model) 169 | m3 = gam(spawners0 ~ nspawners1 + nspawners2, data=m0$model) 170 | a=anova(m1,m2,m3, test="F") 171 | 172 | #simple level model 173 | i=1; mod=paste("m",i,sep="") 174 | aa = summary(get(mod)) 175 | tmp1=data.frame( 176 | Model="1. $ln(S_t)$ = $\\alpha$ + $ln(N_{t-1})$ + $\\epsilon_t$", 177 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 178 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 179 | Adj.R2=100*round(aa$r.sq, digits=3), 180 | F="", p.value="", 181 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 182 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 183 | ) 184 | seltable=rbind(seltable,tmp1) 185 | 186 | #linear ln N_t 187 | i=2; mod=paste("m",i,sep="") 188 | aa = summary(get(mod)) 189 | tmp1=data.frame( 190 | Model="2. $ln(S_t)$ = $\\alpha$ + $\\beta ln(N_{t-1})$ + $\\epsilon_t$", 191 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 192 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 193 | Adj.R2=100*round(aa$r.sq, digits=3), 194 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 195 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 196 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 197 | ) 198 | seltable=rbind(seltable,tmp1) 199 | 200 | #linear ln Catch1 + ln Catch2 201 | i=3; mod=paste("m",i,sep="") 202 | aa = summary(get(mod)) 203 | tmp1=data.frame( 204 | Model="3. $ln(S_t)$ = $\\alpha$ + $\\beta_1 ln(N_{t-1})$ + $\\beta_2 ln(N_{t-2})$ + $\\epsilon_t$", 205 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 206 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 207 | Adj.R2=100*round(aa$r.sq, digits=3), 208 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 209 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 210 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 211 | ) 212 | seltable=rbind(seltable,tmp1) 213 | 214 | ## Space 215 | tmp1 = data.frame( 216 | Model="\\kern 1em", 217 | Residual.df="\\kern 1em", 218 | MASE="\\kern 1em", 219 | Adj.R2="", 220 | F="\\kern 1em", 221 | p.value="\\kern 1em", 222 | AIC="", LOOCV="") 223 | tmp2 = data.frame( 224 | Model=paste("Time dependency test C ", min(respdat$Year),"-", max(respdat$Year), " data", sep=""), 225 | Residual.df="", 226 | MASE="", 227 | Adj.R2="", 228 | F="", 229 | p.value="", 230 | AIC="", LOOCV="") 231 | seltable=rbind(seltable,tmp1,tmp2) 232 | 233 | #5 is most complex 234 | m5 = gam(spawners0 ~ nspawners1+spawners1, data=respdat) 235 | m0=m5 236 | m1 = gam(spawners0 ~ offset(nspawners1), data=m0$model) 237 | m2 = gam(spawners0 ~ nspawners1, data=m0$model) 238 | m3 = gam(spawners0 ~ nspawners1 + spawners1, data=m0$model) 239 | a=anova(m1,m2,m3, test="F") 240 | 241 | #simple model 242 | i=1; mod=paste("m",i,sep="") 243 | aa = summary(get(mod)) 244 | tmp1=data.frame( 245 | Model="1. $ln(S_t)$ = $\\alpha$ + $ln(N_{t-1})$ + $\\epsilon_t$", 246 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 247 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 248 | Adj.R2=100*round(aa$r.sq, digits=3), 249 | F="", p.value="", 250 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 251 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 252 | ) 253 | seltable=rbind(seltable,tmp1) 254 | 255 | #linear ln N_t 256 | i=2; mod=paste("m",i,sep="") 257 | aa = summary(get(mod)) 258 | tmp1=data.frame( 259 | Model="2. $ln(S_t)$ = $\\alpha$ + $\\beta ln(N_{t-1})$ + $\\epsilon_t$", 260 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 261 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 262 | Adj.R2=100*round(aa$r.sq, digits=3), 263 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 264 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 265 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 266 | ) 267 | seltable=rbind(seltable,tmp1) 268 | 269 | #linear ln N1 + ln S1 270 | i=3; mod=paste("m",i,sep="") 271 | aa = summary(get(mod)) 272 | tmp1=data.frame( 273 | Model="3a. $ln(S_t)$ = $\\alpha$ + $\\beta_1 ln(N_{t-1})$ + $\\beta_2 ln(S_{t-1})$ + $\\epsilon_t$", 274 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 275 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 276 | Adj.R2=100*round(aa$r.sq, digits=3), 277 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 278 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 279 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 280 | ) 281 | seltable=rbind(seltable,tmp1) 282 | 283 | #5 is most complex 284 | m5 = gam(spawners0 ~ nspawners1+spawners2, data=respdat) 285 | m0=m5 286 | m1 = gam(spawners0 ~ 1, data=m0$model) 287 | m2 = gam(spawners0 ~ nspawners1, data=m0$model) 288 | m3 = gam(spawners0 ~ nspawners1 + spawners2, data=m0$model) 289 | a=anova(m1,m2,m3, test="F") 290 | 291 | #linear ln N1 + ln S2 292 | i=3; mod=paste("m",i,sep="") 293 | aa = summary(get(mod)) 294 | tmp1=data.frame( 295 | Model="3b. $ln(S_t)$ = $\\alpha$ + $\\beta_1 ln(N_{t-1})$ + $\\beta_2 ln(S_{t-2})$ + $\\epsilon_t$", 296 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 297 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 298 | Adj.R2=100*round(aa$r.sq, digits=3), 299 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 300 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 301 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 302 | ) 303 | seltable=rbind(seltable,tmp1) 304 | ``` 305 | 306 | ```{r print-tableA1a, echo=FALSE} 307 | colnames(seltable)=c("Model", "Residual df", "MASE", "Adj.R2", "F", "p value", "AICc", "LOOCV") 308 | if(isLatex) colnames(seltable)=c("Model", "\\shortstack{Residual\\\\df}", "MASE", "\\shortstack{Adj.\\\\$R^2$}", "F", "\\shortstack{p\\\\value}", "AICc", "\\shortstack{LOOCV\\\\RMSE}") 309 | 310 | thecap=paste("Model selection tests of time-dependency the log catch during spawning months using F-tests of nested linear models. $S_t$ is the catch during the spawning period (Jul-Sep). $N_t$ is the catch during the non-spawning period (Oct-Jun). $S_{t-1}$ and $N_{t-1}$ are the catch during the prior season during and after the spawning period respectively. $S_{t-2}$ and $N_{t-2}$ are the same for two seasons prior. Test A uses catch during the spawning period as the explanatory variable. Test B uses catch during the non-spawning period as the explanatory variable. The numbers in front of the model equation indicate the level of nestedness. For Test C, there are two nested model sets, each with a different model 3. The Naive model is a model that uses the previous data point in the time series as the prediction; thus the Naive model has no estimated parameters.") 311 | fullcap=paste("Table ", ref(paste0(tabset,"spawner-model-linear"), pre=pre), ". ", thecap, sep="") 312 | kable(seltable, align="lccccccc", caption=fullcap, escape=FALSE) 313 | ``` 314 | 315 | ```{r, results="asis", echo=FALSE} 316 | cat("\\clearpage") 317 | ``` 318 | 319 | 320 | ```{r seltableA1b, echo=FALSE} 321 | #set up table 322 | seltable = data.frame( 323 | Model=paste("Time dependency test A ", min(respdat$Year),"-", max(respdat$Year), " data", sep=""), 324 | Residual.df="", 325 | MASE="", 326 | Adj.R2="", 327 | F="", 328 | p.value="", 329 | AIC="", LOOCV="", stringsAsFactors=FALSE) 330 | 331 | #5 is most complex 332 | m5 = gam(spawners0 ~ spawners1+spawners2, data=respdat) 333 | m0=m5 334 | m1 = gam(spawners0 ~ spawners1, data=m0$model) 335 | m2 = gam(spawners0 ~ s(spawners1, sp=0.6), data=m0$model) 336 | m3 = gam(spawners0 ~ s(spawners1, sp=0.6) + s(spawners2, sp=0.6), data=m0$model) 337 | a=anova(m1,m2,m3, test="F") 338 | 339 | #linear on S1 model 340 | i=1; mod=paste("m",i,sep="") 341 | aa = summary(get(mod)) 342 | tmp1=data.frame( 343 | Model="1. $ln(S_t)$ = $\\alpha$ + $\\beta ln(S_{t-1})$ + $\\epsilon_t$", 344 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 345 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 346 | Adj.R2=100*round(aa$r.sq, digits=3), 347 | F="", p.value="", 348 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 349 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 350 | ) 351 | seltable=rbind(seltable,tmp1) 352 | 353 | #linear ln N_t 354 | i=2; mod=paste("m",i,sep="") 355 | aa = summary(get(mod)) 356 | tmp1=data.frame( 357 | Model="2. $ln(S_t)$ = $\\alpha$ + $s(ln(S_{t-1}))$ + $\\epsilon_t$", 358 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 359 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 360 | Adj.R2=100*round(aa$r.sq, digits=3), 361 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 362 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 363 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 364 | ) 365 | seltable=rbind(seltable,tmp1) 366 | 367 | #linear ln Catch1 + ln Catch2 368 | i=3; mod=paste("m",i,sep="") 369 | aa = summary(get(mod)) 370 | tmp1=data.frame( 371 | Model="3. $ln(S_t)$ = $\\alpha$ + $s_1(ln(S_{t-1}))$ + $s_2(ln(S_{t-2}))$ + $\\epsilon_t$", 372 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 373 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 374 | Adj.R2=100*round(aa$r.sq, digits=3), 375 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 376 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 377 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 378 | ) 379 | seltable=rbind(seltable,tmp1) 380 | 381 | ## Space 382 | tmp1 = data.frame( 383 | Model="\\kern 1em", 384 | Residual.df="\\kern 1em", 385 | MASE="\\kern 1em", 386 | Adj.R2="", 387 | F="\\kern 1em", 388 | p.value="\\kern 1em", 389 | AIC="", LOOCV="") 390 | tmp2 = data.frame( 391 | Model=paste("Time dependency test B ", min(respdat$Year),"-", max(respdat$Year), " data", sep=""), 392 | Residual.df="", 393 | MASE="", 394 | Adj.R2="", 395 | F="", 396 | p.value="", 397 | AIC="", LOOCV="") 398 | seltable=rbind(seltable,tmp1,tmp2) 399 | 400 | #5 is most complex 401 | m5 = gam(spawners0 ~ nspawners1+nspawners2, data=respdat) 402 | m0=m5 403 | m1 = gam(spawners0 ~ nspawners1, data=m0$model) 404 | m2 = gam(spawners0 ~ s(nspawners1, sp=0.6), data=m0$model) 405 | m3 = gam(spawners0 ~ s(nspawners1, sp=0.6) + s(nspawners2, sp=0.6), data=m0$model) 406 | a=anova(m1,m2,m3, test="F") 407 | 408 | #linear on N1 409 | i=1; mod=paste("m",i,sep="") 410 | aa = summary(get(mod)) 411 | tmp1=data.frame( 412 | Model="1. $ln(S_t)$ = $\\alpha$ + $\\beta ln(N_{t-1})$ + $\\epsilon_t$", 413 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 414 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 415 | Adj.R2=100*round(aa$r.sq, digits=3), 416 | F="", p.value="", 417 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 418 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 419 | ) 420 | seltable=rbind(seltable,tmp1) 421 | 422 | #linear ln N_t 423 | i=2; mod=paste("m",i,sep="") 424 | aa = summary(get(mod)) 425 | tmp1=data.frame( 426 | Model="2. $ln(S_t)$ = $\\alpha$ + $s(ln(N_{t-1}))$ + $\\epsilon_t$", 427 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 428 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 429 | Adj.R2=100*round(aa$r.sq, digits=3), 430 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 431 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 432 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 433 | ) 434 | seltable=rbind(seltable,tmp1) 435 | 436 | #linear ln Catch1 + ln Catch2 437 | i=3; mod=paste("m",i,sep="") 438 | aa = summary(get(mod)) 439 | tmp1=data.frame( 440 | Model="3. $ln(S_t)$ = $\\alpha$ + $s_1(ln(N_{t-1}))$ + $s_2(ln(N_{t-2}))$ + $\\epsilon_t$", 441 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 442 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 443 | Adj.R2=100*round(aa$r.sq, digits=3), 444 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 445 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 446 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 447 | ) 448 | seltable=rbind(seltable,tmp1) 449 | 450 | ## Space 451 | tmp1 = data.frame( 452 | Model="\\kern 1em", 453 | Residual.df="\\kern 1em", 454 | MASE="\\kern 1em", 455 | Adj.R2="", 456 | F="\\kern 1em", 457 | p.value="\\kern 1em", 458 | AIC="", LOOCV="") 459 | tmp2 = data.frame( 460 | Model=paste("Time dependency test C ", min(respdat$Year),"-", max(respdat$Year), " data", sep=""), 461 | Residual.df="", 462 | MASE="", 463 | Adj.R2="", 464 | F="", 465 | p.value="", 466 | AIC="", LOOCV="") 467 | seltable=rbind(seltable,tmp1,tmp2) 468 | 469 | #5 is most complex 470 | m5 = gam(spawners0 ~ nspawners1+spawners1, data=respdat) 471 | m0=m5 472 | m1 = gam(spawners0 ~ 1, data=m0$model) 473 | m2 = gam(spawners0 ~ s(nspawners1, sp=0.6), data=m0$model) 474 | m3 = gam(spawners0 ~ s(nspawners1, sp=0.6) + s(spawners1, sp=0.6), data=m0$model) 475 | a=anova(m1,m2,m3, test="F") 476 | 477 | #nonlinear ln N_t 478 | i=2; mod=paste("m",i,sep="") 479 | aa = summary(get(mod)) 480 | tmp1=data.frame( 481 | Model="1. $ln(S_t)$ = $\\alpha$ + $s(ln(N_{t-1}))$ + $\\epsilon_t$", 482 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 483 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 484 | Adj.R2=100*round(aa$r.sq, digits=3), 485 | F="", p.value="", 486 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 487 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 488 | ) 489 | seltable=rbind(seltable,tmp1) 490 | 491 | #nonlinear ln N1 + ln S1 492 | i=3; mod=paste("m",i,sep="") 493 | aa = summary(get(mod)) 494 | tmp1=data.frame( 495 | Model="2. $ln(S_t)$ = $\\alpha$ + $s_1(ln(N_{t-1}))$ + $s_2(ln(S_{t-1}))$ + $\\epsilon_t$", 496 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 497 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 498 | Adj.R2=100*round(aa$r.sq, digits=3), 499 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 500 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 501 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 502 | ) 503 | seltable=rbind(seltable,tmp1) 504 | 505 | #5 is most complex 506 | m5 = gam(spawners0 ~ nspawners1+spawners2, data=respdat) 507 | m0=m5 508 | m1 = gam(spawners0 ~ 1, data=m0$model) 509 | m2 = gam(spawners0 ~ s(nspawners1, sp=0.6), data=m0$model) 510 | m3 = gam(spawners0 ~ s(nspawners1, sp=0.6) + s(spawners2, sp=0.6), data=m0$model) 511 | a=anova(m1,m2,m3, test="F") 512 | 513 | #linear ln N1 + ln S2 514 | i=3; mod=paste("m",i,sep="") 515 | aa = summary(get(mod)) 516 | tmp1=data.frame( 517 | Model="3. $ln(S_t)$ = $\\alpha$ + $s_1(ln(N_{t-1}))$ + $s_2(ln(S_{t-2}))$ + $\\epsilon_t$", 518 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 519 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 520 | Adj.R2=100*round(aa$r.sq, digits=3), 521 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 522 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 523 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 524 | ) 525 | seltable=rbind(seltable,tmp1) 526 | 527 | load("FittedLooPred.Rdata") 528 | ## Space 529 | tmp1 = data.frame( 530 | Model="\\kern 1em", 531 | Residual.df="\\kern 1em", 532 | MASE="\\kern 1em", 533 | Adj.R2="", 534 | F="\\kern 1em", 535 | p.value="\\kern 1em", 536 | AIC="", LOOCV="") 537 | tmp2 = data.frame( 538 | Model=paste("Time varying test D ", min(respdat$Year),"-", max(respdat$Year), " data", sep=""), 539 | Residual.df="", 540 | MASE="", 541 | Adj.R2="", 542 | F="", 543 | p.value="", 544 | AIC="", LOOCV="") 545 | seltable=rbind(seltable,tmp1,tmp2) 546 | 547 | #DLM 548 | mod <- FittedLooPred1984$Fitted[["dlm(intercept)"]] 549 | modloo <- FittedLooPred1984$LooPred[["dlm(intercept)"]] 550 | err <- mod$model$data[1,]-modloo$pred 551 | tmp1=data.frame( 552 | Model="1. $ln(S_t)$ = $\\alpha_t$ + $\\epsilon_t$", 553 | Residual.df=mod$samp.size-attr(MARSS:::logLik.marssMLE(mod), "df"), 554 | MASE=round(mean(abs(MARSS:::residuals.marssMLE(mod, silent=TRUE)$model.residuals), na.rm=TRUE)/NE,digits=3), 555 | Adj.R2="", 556 | F="", p.value="", 557 | AIC=round(mod$AICc, digits=2), 558 | LOOCV=round(sqrt(mean(err^2, na.rm=TRUE)), digits=3) 559 | ) 560 | seltable=rbind(seltable,tmp1) 561 | 562 | mod <- FittedLooPred1984$Fitted[["dlm(intercept, slope)"]] 563 | modloo <- FittedLooPred1984$LooPred[["dlm(intercept, slope)"]] 564 | err <- mod$model$data[1,]-modloo$pred 565 | tmp1=data.frame( 566 | Model="2. $ln(S_t)$ = $\\alpha_t$ + $\\beta_t t$ + $\\epsilon_t$", 567 | Residual.df=mod$samp.size-attr(MARSS:::logLik.marssMLE(mod), "df"), 568 | MASE=round(mean(abs(MARSS:::residuals.marssMLE(mod, silent=TRUE)$model.residuals), na.rm=TRUE)/NE,digits=3), 569 | Adj.R2="", 570 | F="", p.value="", 571 | AIC=round(mod$AICc, digits=2), 572 | LOOCV=round(sqrt(mean(err^2, na.rm=TRUE)), digits=3) 573 | ) 574 | seltable=rbind(seltable,tmp1) 575 | 576 | mod <- FittedLooPred1984$Fitted[["dlm(Jul-Sep(t-1))"]] 577 | modloo <- FittedLooPred1984$LooPred[["dlm(Jul-Sep(t-1))"]] 578 | err <- mod$model$data[1,]-modloo$pred 579 | tmp1=data.frame( 580 | Model="3a. $ln(S_t)$ = $\\alpha$ + $\\beta_t ln(S_{t-1})$ + $\\epsilon_t$", 581 | Residual.df=mod$samp.size-attr(MARSS:::logLik.marssMLE(mod), "df"), 582 | MASE=round(mean(abs(MARSS:::residuals.marssMLE(mod, silent=TRUE)$model.residuals), na.rm=TRUE)/NE,digits=3), 583 | Adj.R2="", 584 | F="", p.value="", 585 | AIC=round(mod$AICc, digits=2), 586 | LOOCV=round(sqrt(mean(err^2, na.rm=TRUE)), digits=3) 587 | ) 588 | seltable=rbind(seltable,tmp1) 589 | 590 | mod <- FittedLooPred1984$Fitted[["dlm(Oct-Mar(t-1))"]] 591 | modloo <- FittedLooPred1984$LooPred[["dlm(Oct-Mar(t-1))"]] 592 | err <- mod$model$data[1,]-modloo$pred 593 | tmp1=data.frame( 594 | Model="3b. $ln(S_t)$ = $\\alpha$ + $\\beta_t ln(N_{t-1})$ + $\\epsilon_t$", 595 | Residual.df=mod$samp.size-attr(MARSS:::logLik.marssMLE(mod), "df"), 596 | MASE=round(mean(abs(MARSS:::residuals.marssMLE(mod, silent=TRUE)$model.residuals), na.rm=TRUE)/NE,digits=3), 597 | Adj.R2="", 598 | F="", p.value="", 599 | AIC=round(mod$AICc, digits=2), 600 | LOOCV=round(sqrt(mean(err^2, na.rm=TRUE)), digits=3) 601 | ) 602 | seltable=rbind(seltable,tmp1) 603 | 604 | ``` 605 | 606 | ```{r print-tableA1b, echo=FALSE} 607 | colnames(seltable)=c("Model", "Residual df", "MASE", "Adj.R2", "F", "p value", "AICc", "LOOCV") 608 | if(isLatex) colnames(seltable)=c("Model", "\\shortstack{Residual\\\\df}", "MASE", "\\shortstack{Adj.\\\\$R^2$}", "F", "\\shortstack{p\\\\value}", "AICc", "\\shortstack{LOOCV\\\\RMSE}") 609 | 610 | thecap=paste0("Model selection tests of time-dependency the catch during spawning months using non-linear or time-varying linear responses instead of time-constant linear responses as in Table ", ref(paste0(tabset,"spawner-model-linear"), pre=pre), ". See Table ", ref(paste0(tabset,"spawner-model-linear"), pre=pre), " for an explanation of the parameters and model set-up.") 611 | fullcap=paste("Table ", ref(paste0(tabset,"spawner-model-nonlinear"), pre=pre), ". ", thecap, sep="") 612 | kable(seltable, align="lccccccc", caption=fullcap, escape=FALSE) 613 | ``` 614 | 615 | ```{r, results="asis", echo=FALSE} 616 | cat("\\clearpage") 617 | ``` 618 | 619 | 620 | ```{r seltableA-spawner-1956, echo=FALSE} 621 | respdat = dat.spawners[which(dat.spawners$Year==1956):which(dat.spawners$Year==(Yr1-1)),] 622 | 623 | #set up table 624 | seltable = data.frame( 625 | Model=paste("Time dependency test A ", min(respdat$Year),"-", max(respdat$Year), " data", sep=""), 626 | Residual.df="", 627 | MASE="", 628 | Adj.R2="", 629 | F="", 630 | p.value="", 631 | AIC="", LOOCV="", stringsAsFactors=FALSE) 632 | 633 | #5 is most complex 634 | m5 = gam(spawners0 ~ spawners1+spawners2, data=respdat) 635 | m0=m5 636 | m1 = gam(spawners0 ~ spawners1, data=m0$model) 637 | m2 = gam(spawners0 ~ s(spawners1, sp=0.6), data=m0$model) 638 | m3 = gam(spawners0 ~ s(spawners1, sp=0.6) + s(spawners2, sp=0.6), data=m0$model) 639 | a=anova(m1,m2,m3, test="F") 640 | 641 | #linear on S1 model 642 | i=1; mod=paste("m",i,sep="") 643 | aa = summary(get(mod)) 644 | tmp1=data.frame( 645 | Model="1. $ln(S_t)$ = $\\alpha$ + $\\beta ln(S_{t-1})$ + $\\epsilon_t$", 646 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 647 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 648 | Adj.R2=100*round(aa$r.sq, digits=3), 649 | F="", p.value="", 650 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 651 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 652 | ) 653 | seltable=rbind(seltable,tmp1) 654 | 655 | #linear ln N_t 656 | i=2; mod=paste("m",i,sep="") 657 | aa = summary(get(mod)) 658 | tmp1=data.frame( 659 | Model="2. $ln(S_t)$ = $\\alpha$ + $s(ln(S_{t-1}))$ + $\\epsilon_t$", 660 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 661 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 662 | Adj.R2=100*round(aa$r.sq, digits=3), 663 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 664 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 665 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 666 | ) 667 | seltable=rbind(seltable,tmp1) 668 | 669 | #linear ln Catch1 + ln Catch2 670 | i=3; mod=paste("m",i,sep="") 671 | aa = summary(get(mod)) 672 | tmp1=data.frame( 673 | Model="3. $ln(S_t)$ = $\\alpha$ + $s_1(ln(S_{t-1}))$ + $s_2(ln(S_{t-2}))$ + $\\epsilon_t$", 674 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 675 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 676 | Adj.R2=100*round(aa$r.sq, digits=3), 677 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 678 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 679 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 680 | ) 681 | seltable=rbind(seltable,tmp1) 682 | 683 | ## Space 684 | tmp1 = data.frame( 685 | Model="\\kern 1em", 686 | Residual.df="\\kern 1em", 687 | MASE="\\kern 1em", 688 | Adj.R2="", 689 | F="\\kern 1em", 690 | p.value="\\kern 1em", 691 | AIC="", LOOCV="") 692 | tmp2 = data.frame( 693 | Model=paste("Time dependency test B ", min(respdat$Year),"-", max(respdat$Year), " data", sep=""), 694 | Residual.df="", 695 | MASE="", 696 | Adj.R2="", 697 | F="", 698 | p.value="", 699 | AIC="", LOOCV="") 700 | seltable=rbind(seltable,tmp1,tmp2) 701 | 702 | #5 is most complex 703 | m5 = gam(spawners0 ~ nspawners1+nspawners2, data=respdat) 704 | m0=m5 705 | m1 = gam(spawners0 ~ nspawners1, data=m0$model) 706 | m2 = gam(spawners0 ~ s(nspawners1, sp=0.6), data=m0$model) 707 | m3 = gam(spawners0 ~ s(nspawners1, sp=0.6) + s(nspawners2, sp=0.6), data=m0$model) 708 | a=anova(m1,m2,m3, test="F") 709 | 710 | #linear on N1 711 | i=1; mod=paste("m",i,sep="") 712 | aa = summary(get(mod)) 713 | tmp1=data.frame( 714 | Model="1. $ln(S_t)$ = $\\alpha$ + $\\beta ln(N_{t-1})$ + $\\epsilon_t$", 715 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 716 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 717 | Adj.R2=100*round(aa$r.sq, digits=3), 718 | F="", p.value="", 719 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 720 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 721 | ) 722 | seltable=rbind(seltable,tmp1) 723 | 724 | #linear ln N_t 725 | i=2; mod=paste("m",i,sep="") 726 | aa = summary(get(mod)) 727 | tmp1=data.frame( 728 | Model="2. $ln(S_t)$ = $\\alpha$ + $s(ln(N_{t-1}))$ + $\\epsilon_t$", 729 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 730 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 731 | Adj.R2=100*round(aa$r.sq, digits=3), 732 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 733 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 734 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 735 | ) 736 | seltable=rbind(seltable,tmp1) 737 | 738 | #linear ln Catch1 + ln Catch2 739 | i=3; mod=paste("m",i,sep="") 740 | aa = summary(get(mod)) 741 | tmp1=data.frame( 742 | Model="3. $ln(S_t)$ = $\\alpha$ + $s_1(ln(N_{t-1}))$ + $s_2(ln(N_{t-2}))$ + $\\epsilon_t$", 743 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 744 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 745 | Adj.R2=100*round(aa$r.sq, digits=3), 746 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 747 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 748 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 749 | ) 750 | seltable=rbind(seltable,tmp1) 751 | 752 | ## Space 753 | tmp1 = data.frame( 754 | Model="\\kern 1em", 755 | Residual.df="\\kern 1em", 756 | MASE="\\kern 1em", 757 | Adj.R2="", 758 | F="\\kern 1em", 759 | p.value="\\kern 1em", 760 | AIC="", LOOCV="") 761 | tmp2 = data.frame( 762 | Model=paste("Time dependency test C ", min(respdat$Year),"-", max(respdat$Year), " data", sep=""), 763 | Residual.df="", 764 | MASE="", 765 | Adj.R2="", 766 | F="", 767 | p.value="", 768 | AIC="", LOOCV="") 769 | seltable=rbind(seltable,tmp1,tmp2) 770 | 771 | #5 is most complex 772 | m5 = gam(spawners0 ~ nspawners1+spawners1, data=respdat) 773 | m0=m5 774 | m1 = gam(spawners0 ~ 1, data=m0$model) 775 | m2 = gam(spawners0 ~ s(nspawners1, sp=0.6), data=m0$model) 776 | m3 = gam(spawners0 ~ s(nspawners1, sp=0.6) + s(spawners1, sp=0.6), data=m0$model) 777 | a=anova(m1,m2,m3, test="F") 778 | 779 | #nonlinear ln N_t 780 | i=2; mod=paste("m",i,sep="") 781 | aa = summary(get(mod)) 782 | tmp1=data.frame( 783 | Model="1. $ln(S_t)$ = $\\alpha$ + $s(ln(N_{t-1}))$ + $\\epsilon_t$", 784 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 785 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 786 | Adj.R2=100*round(aa$r.sq, digits=3), 787 | F="", p.value="", 788 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 789 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 790 | ) 791 | seltable=rbind(seltable,tmp1) 792 | 793 | #nonlinear ln N1 + ln S1 794 | i=3; mod=paste("m",i,sep="") 795 | aa = summary(get(mod)) 796 | tmp1=data.frame( 797 | Model="2. $ln(S_t)$ = $\\alpha$ + $s_1(ln(N_{t-1}))$ + $s_2(ln(S_{t-1}))$ + $\\epsilon_t$", 798 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 799 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 800 | Adj.R2=100*round(aa$r.sq, digits=3), 801 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 802 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 803 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 804 | ) 805 | seltable=rbind(seltable,tmp1) 806 | 807 | #5 is most complex 808 | m5 = gam(spawners0 ~ nspawners1+spawners2, data=respdat) 809 | m0=m5 810 | m1 = gam(spawners0 ~ 1, data=m0$model) 811 | m2 = gam(spawners0 ~ s(nspawners1, sp=0.6), data=m0$model) 812 | m3 = gam(spawners0 ~ s(nspawners1, sp=0.6) + s(spawners2, sp=0.6), data=m0$model) 813 | a=anova(m1,m2,m3, test="F") 814 | 815 | #linear ln N1 + ln S2 816 | i=3; mod=paste("m",i,sep="") 817 | aa = summary(get(mod)) 818 | tmp1=data.frame( 819 | Model="3. $ln(S_t)$ = $\\alpha$ + $s_1(ln(N_{t-1}))$ + $s_2(ln(S_{t-2}))$ + $\\epsilon_t$", 820 | Residual.df=round(a[["Resid. Df"]][i],digits=1), 821 | MASE=round(mean(abs(residuals(get(mod))))/NE,digits=3), 822 | Adj.R2=100*round(aa$r.sq, digits=3), 823 | F=round(a$F[i],digits=2), p.value=round(a[["Pr(>F)"]][i], digits=3), 824 | AIC=round(SardineForecast:::AICc(get(mod)), digits=2), 825 | LOOCV=round(SardineForecast:::loogam(get(mod))$RMSE, digits=3) 826 | ) 827 | seltable=rbind(seltable,tmp1) 828 | ``` 829 | 830 | ```{r print-tableA1c, echo=FALSE} 831 | colnames(seltable)=c("Model", "Residual df", "MASE", "Adj.R2", "F", "p value", "AICc", "LOOCV") 832 | if(isLatex) colnames(seltable)=c("Model", "\\shortstack{Residual\\\\df}", "MASE", "\\shortstack{Adj.\\\\$R^2$}", "F", "\\shortstack{p\\\\value}", "AICc", "\\shortstack{LOOCV\\\\RMSE}") 833 | 834 | thecap=paste0("Table ",ref(paste0(tabset,"spawner-model-nonlinear"), pre=pre), " with 1956-",Yr1-1, " data instead of ", Yr1, " to ", Yr2, " data. See Table ",ref(paste0(tabset,"spawner-model-linear"), pre=pre), " for an explanation of the parameters and model set-up.") 835 | fullcap=paste("Table ", ref(paste0(tabset,"spawner-model-1956"), pre=pre), ". ", thecap, sep="") 836 | kable(seltable, align="lccccccc", caption=fullcap, escape=FALSE) 837 | ``` 838 | 839 | 840 | 841 | -------------------------------------------------------------------------------- /Main.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: '\Large Example journal article on oil sardine (\textit{Sardinella longiceps})' 3 | csl: "apa-edit.csl" 4 | header-includes: 5 | - \usepackage[labelformat=empty]{caption} 6 | - \usepackage{setspace} 7 | - \onehalfspacing 8 | - \usepackage{etoolbox} 9 | - \AtBeginEnvironment{tabular}{\singlespacing} 10 | - \setlength\parindent{24pt} 11 | - \usepackage{mathptmx} 12 | - \usepackage[margin=1in]{geometry} 13 | - \usepackage[fontsize=12.5pt]{scrextend} 14 | - \usepackage{lineno} 15 | - \linenumbers 16 | output: 17 | pdf_document: default 18 | word_document: default 19 | bibliography: "Sardine.bib" 20 | --- 21 | 22 | 23 | ```{r child = 'setup.Rmd'} 24 | #Setup code common across all Rmds 25 | #This will load the data and process the data 26 | #To ensure that the same data is always used 27 | ``` 28 | 29 | \noindent{\large Eli E. Holmes$^1$, Author Two$^2$, Author Three$^3$, Author Four$^1$} 30 | 31 | 32 | 1. Northwest Fisheries Science Center, NOAA, Seattle, WA. 33 | 34 | 2. Author Two address 35 | 36 | 3. Author Three address 37 | 38 | \noindent{\bf Running title}: An example article 39 | 40 | \clearpage 41 | 42 | # Acknowledgements {-} 43 | 44 | We thank the U.S. National Marine Fisheries Service for support, and we acknowledge the many researchers involved in collecting and maintaining the long-term data set. 45 | 46 | \clearpage 47 | 48 | **This shows you a realistic Rmd for a journal article. This was an early version and I've cut out many paragraphs here and there to shorten it, but it is still has all the parts.** 49 | 50 | Note that the repository is a self-contained paper with all the data and the analyses are redone completely whenever Main.Rmd is re-knit. So if the data change, all the analyses will be updated. 51 | 52 | \begin{abstract} 53 | 54 | Commercial landings of sardine are known for strong year-to-year fluctuations. A key driver is thought to be environmental variability, to which small forage fish are especially sensitive. We examined the environmental drivers associated with landings fluctuations in the Indian oil sardine using a 32-year time series of quarterly catch. Past research suggested a variety of influential variables: precipitation, upwelling intensity, ocean temperature (SST), chlorophyll concentration and large-scale coupled atmosphere–ocean phenomena (ENSO). Using the life history of the Indian oil sardine, we developed hypotheses concerning how these variables might affect landings and tested them using generalized additive models which allow non-linear response curves and dynamic linear models which allow time-varying responses. We found significant correlation for three variables: upwelling intensity, an ENSO index, and the multi-year average nearshore SST. Upwelling intensity can have both a positive effect (fueling higher food availability) and a negative effect at extreme intensity (surface anoxia). The negative effect was apparent for both monsoon and post-monsoon catch. However, the most significant correlation (adjusted R$^2$ of 67.5\%) was between the 2.5 year average nearshore SST and post-monsoon landings. The multi-year average SST also been identified as a predictor for Pacific and southern African sardine fluctuations, suggesting that the average SST over the sardine lifespan successfully captures a variety of factors which predict future abundance. 55 | \newline\newline 56 | \noindent{\bf Keywords}: Indian oil sardine, catch prediction, GAM modeling, climate, sea surface temperature, remote sensing, Southeast Arabian Sea 57 | 58 | \end{abstract} 59 | 60 | \clearpage 61 | 62 | # Introduction {-} 63 | 64 | 65 | Environmental variability is known to be a key driver of population variability of small forage fish such as sardines, anchovy and herring [@AlheitHagen1997; @Curyetal2000; @Checkleyetal2017]. In particular, ocean temperature and upwelling dynamics, along with density-dependent feedback, have been identified as important in affecting recruitment success and biomass of European and Pacific sardines (*Sardina pilchardus* and *Sardinops sagax*) [@JacobsonMacCall1995; @RykaczewskiCheckley2008; @Alheitetal2012; @LindegrenCheckley2012; @Lindegrenetal2013; @Garza-Giletal2015]. Like other sardines, the Indian oil sardine (*Sardinella longiceps* Valenciennes, 1847) shows strong inter-annual fluctuations and larger decadal booms and busts. The Indian oil sardine offers an instructive case study to investigate the effects of environmental variability, particularly temperature and upwelling dynamics, as they occupy an ocean system that is warmer than that occupied by other sardines and have a strong seasonal cycle driven by the Indian summer monsoon. 66 | 67 | 68 | The Indian oil sardine is one of the most commercially important fish resources along the southwest coast of India (Figure `r ref("fig:studyarea")`) and historically has comprised approximately 25% of the marine catch in the Indian fisheries [@Vivekanandanetal2003]. Landings of the Indian oil sardine are highly seasonal, peaking after the summer monsoon period in October-December and reaching a nadir in spring before the summer monsoon in April-June (Figure `r ref("fig:catch")`). At the same time, the landings of this small pelagic finfish are highly variable from year to year. Small pelagics are well known to exhibit high variability in biomass due to the effects of environmental conditions on survival and recruitment, but in this fishery, environmental conditions also affect exposure of sardines to the fishery. Until recently, the Indian oil sardine fishery was artisanal and based on small human or low powered boats with no refrigeration. The fishery was confined to nearshore waters, and thus migration of sardines in and out of the coastal zone greatly affected exposure to the fishery and hence landings. 69 | 70 | 71 | Researchers have examined a variety of environmental variables for their correlation with landings of the Indian oil sardine. Precipitation during the monsoon and the day of the monsoon arrival are thought to act as either a direct or indirect cue for spawning [@MurtyEdelman1966; @AntonyRaja1969; @AntonyRaja1974; @Srinath1998; @Jayaprakash2002; @XuBoyce2009; @PitchaikaniLipton2012]. Although many studies have looked for and some have found correlations between precipitation and landings, the reported relationships are positive in some studies and negative in others [@Madhupratapetal1994]. Researchers have also looked for and found correlations with various metrics of upwelling intensity [@MurtyEdelman1966; @LonghurstWooster1990; @Madhupratapetal1994; @Srinath1998; @Jayaprakash2002; @Thara2011], with direct measures of productivity such as nearshore zooplankton and phytoplankton abundance [@Nair1952; @NairSubrahmanyan1955; @Madhupratapetal1994; @Georgeetal2012; @Piontkovskietal2015; @PitchaikaniLipton2012; @Menonetal2019], and with nearshore sea surface temperature (SST) [@Annigeri1969; @PrabhuDhulkhed1970; @Pillai1991; @Suprabaetal2016]. 72 | 73 | ## Catch modeling versus biomass modeling 74 | 75 | Modeling and forecasting landings data using statistical models fit to annual or seasonal catch time series has a long tradition in fisheries and has been applied to many species [@Mendelssohn1981; @CohenStone1987; @NobelSathianandan1991; @StergiouChristou1996; @Lloretetal2000; @Georgakarakosetal2006; @Hansenetal2006; @Pristaetal2011; @FarmerFroeschke2015; @Lawer2016], including oil sardines [@Srinath1998; @VenugopalanSrinath1998]. These models can be used to identity the variables correlated with catch fluctuations and can be used to provide landings forecasts which are useful for fishery managers and the fishing industry. An example of the former is using catch forecasts to set or give warnings of seasonal fishery closures if the forecasted catch is higher than the allowed catch limits [@FarmerFroeschke2015]. An example of the latter is the annual Gulf and Atlantic menhaden forecast produced by NOAA Fisheries [@Schaafetal1975; @Hansenetal2006]. This multiple regression model has been used for the last 45 years to produce an annual forecast of menhaden landings, which is used for planning purposes by the industry, not only the fishers but also fish catch sellers and buyers, businesses which provide fisheries gear, and banks which provide financing [@Hansenetal2006]. 76 | 77 | ### Study Area 78 | 79 | Our analysis focuses on the Kerala coast (Figure `r ref("fig:studyarea")`) region of India, where the majority of the Indian oil sardines are landed and where oil sardines comprise ca. 40% of the marine fish catch [@Srinath1998; @Vivekanandanetal2003]. This area is in the Southeast Arabian Sea, one of world’s major upwelling zones, with seasonal peaks in primary productivity driven by upwelling caused by winds during the Indian summer monsoon [@Madhupratapetal2001; @Habeebrehmanetal2008] between June and September. Within the study area, the coastal zone off Kerala between 9$^\circ$N to 13$^\circ$N has especially intense upwelling due to the combined effects of wind stress and remote forcing [@Smitha2010; @Smithaetal2008]. The result is a strong temperature differential between the nearshore and offshore and high primary productivity and surface chlorophyll concentration in this region during summer and early fall [@Madhupratapetal2001; @Habeebrehmanetal2008; @Jayarametal2010; @Smitha2010; @Raghavanetal2010; @Chauhanetal2011]. The primary productivity peaks subside after September while mesozooplankton abundances increase and remain high in the post-monsoon period [@Madhupratapetal2001]. 80 | 81 | ### Oil sardine life cycle and fishery 82 | 83 | 84 | The Indian oil sardine fishery is restricted to the narrow strip of the western India continental shelf, within 20 km from the shore (Figure `r ref("fig:studyarea")`). The yearly cycle of the fishery begins at the start of spawning during June to July, corresponding with the onset of the summer monsoon [@Chidambaram1950; @AntonyRaja1969] and the initiation of strongly cooler nearshore SST due to upwelling (Figure `r ref("fig:SSTts")`). At this time, the mature fish migrate from offshore to coastal spawning areas, and the spawning begins during the summer monsoon period when temperature, salinity and suitable food availability are conducive for larval survival [@Chidambaram1950; @MurtyEdelman1966; @JayaprakashPillai2000; @Krishnakumaretal2008; @Nairetal2016]. Although peak spawning occurs in June to July, spawning continues into September [@AntonyRaja1969; @Hornell1910; @HornellNayudu1923; @PrabhuDhulkhed1970] and early- and late-spawning cohorts are evident in the length distributions of the 0-year fish. Spawning occurs in waters outside of the traditional range of the fishery [@AntonyRaja1964], and after spawning the adults migrate closer to the coast where the spent fish become exposed to the fishery. 85 | 86 | After eggs are spawned, they develop rapidly into larvae [@Nair1959]. The phytoplankton bloom that provide sardine larvae food is dependent upon nutrient influx from coastal upwelling and runoff from rivers during the summer monsoon and early fall. The blooms start in the south near the southern tip of India in June, increase in intensity and spread northward up the coast [@Smitha2010]. Variation in the bloom initiation time and intensity leads to changes in the food supply and to corresponding changes in the growth and survival of larvae and in the later recruitment of 0-year sardines into the fishery [@Georgeetal2012]. Oil sardines grow rapidly during their first few months, and 0-year fish (40mm to 100mm) from early spawning appear in the catch in August and September in most years [@Nairetal2016; @AntonyRaja1970]. As the phytoplankton bloom spreads northward, the oil sardines follow, and the oil sardine fishery builds from south to north during the post-monsoon period. Oil sardines remain inshore feeding throughout the winter months, until March to May when the inshore waters warm considerably and sardines move offshore to deeper waters [@Chidambaram1950]. Catches of sardines are correspondingly low during this time for all size classes. The age at first maturity occurs at approximately 150 mm size [@Nairetal2016], which is reached within one year. When the summer monsoon returns, the oil sardine cycle begins anew. 87 | 88 | 93 | 94 | 95 | # Materials and Methods {-} 96 | 97 | ## Sardine landing data 98 | 99 | Quarterly fish landing data have been collected by the Central Marine Fisheries Research Institute (CMFRI) in Kochi, India, since the early 1950s using a stratified multi-stage sample design [@Srinathetal2005]. The survey visits the fish landing centers along the entire southwest coast of India and samples the catch from the variety of boat types and gear types used in the coastal fishery. Landings estimates are available for all the coastal states, however we model the catch for the state of Kerala only, where the longest time series is available and the overwhelming majority of oil sardines are landed (Figure `r ref("fig:catch")`). 100 | 101 | 106 | 107 | ## Remote sensing data 108 | 109 | We analyzed monthly composites of the following environmental data derived from satellite data: sea surface temperature (SST), chlorophyll-a (CHL), upwelling (UPW), the Oceanic Niño Index (ONI), the Dipole Mode Index (DMI) and precipitation. The monthly time series and means of the covariates are shown in Figure `r ref("fig:COVts")`. 110 | 111 | We used the chlorophyll-a products developed by the Ocean Biology Processing Group in the Ocean Ecology Laboratory at the NASA Goddard Space Flight Center. For 1997 to 2002, we used the chlorophyll-a 2014.0 Reprocessing (R2014.0) product from the Sea-viewing Wide Field-of-view Sensor (SeaWiFS) on the Orbview-2 satellite. These data are on a 0.1 degree grid. For 2003 to 2017, we used the MODIS-Aqua product on a 0.05 degree grid. These CHL data are taken from measurements by the Moderate Resolution Imaging Spectroradiometer (MODIS) on NASA's Aqua Spacecraft. The SST and CHL data were averaged across thirteen 1 degree by 1 degree boxes which roughly parallel the bathymetry (Figure `r ref("fig:studyarea")`). The SST and CHL satellite data were retrieved from NOAA remote-sensing data servers; see Appendix G for data sources and references. 112 | 113 | For an index of coastal upwelling, we used three indices. The first was the sea surface temperature differential between near shore and 3 degrees offshore based on the index described by Naidu et al. [-@Naiduetal1999] and BR et al. [-@Smithaetal2008]. For SST, we used the remote sensing sea surface temperature data sets described above. This SST-based upwelling index has been validated as a more reliable metric of upwelling off the coast of Kerala compared to wind-based upwelling indices [@Smithaetal2008]. 114 | 115 | The Oceanic Niño Index (ONI) is a measure of the SST anomaly in the east-central Pacific and is a standard index of the El Niño/Southern Oscillation (ENSO) cycle. The ONI index is 3-month running mean of ERSST.v5 SST anomalies in the Niño 3.4 region, based on centered 30-year base periods updated every 5 years. The ONI was downloaded from the NOAA National Weather Service Climate Prediction Center. The Dipole Mode Index (DMI) is defined by the SSTA difference between the 116 | western Indian Ocean (10°S–10°N, 50°E–70°E) and the southeastern Indian Ocean (10°S–0°, 90°E–110°E). The DMI has been shown to predict anoxic events in our study area [@Vallivattathillametal2017]. The DMI data were downloaded from the NOAA Earth System Research Laboratory. See Appendix G for the data servers where the ENSO data were downloaded and computation notes and references. 117 | 118 | 119 | ## Hypotheses 120 | 121 | Our statistical tests were structured around specific hypotheses (Table `r ref("tab:hypotheses")`) concerning which remote sensing covariates in which months should correlate with landings in specific quarters. These hypotheses were based on biological information concerning how environmental conditions affect sardine survival and recruitment and affect exposure of Indian oil sardines to the coastal fishery. The Jul-Sep catch overlaps the summer monsoon and the main spawning months. This is also the quarter where small 0-year fish from early spawning often appear in the catch, sometimes in large numbers. Variables that affect or are correlated with movement of sardines inshore should be correlated with Jul-Sep landings. In addition, pre-spawning (Mar-May) environmental conditions should be correlated with the spawning strength as adult oil sardines experience an acceleration of growth during this period along with egg development. The post-monsoon catch (Oct-May) is a mix of 0-year fish (less than 12 months old) and mature fish (greater than 12 months old). Variables that are correlated with spawning strength and larval and juvenile survival should correlate with the post-monsoon catch both in the current year and in future years, one to two years after. 122 | 123 | 124 | ## Statistical models 125 | 126 | 127 | Preliminarily, we tested ARIMA models on both the Jul-Sep and Oct-Mar catch time series and found little support for auto-regressive errors (ARIMA models with a MA component) based on diagnostic tests of the residuals and model selection. The best supported ARIMA models were simple AR models ($x_t = b x_{t-1} + \epsilon_t$). This lack of strong auto-correlation in residuals has been found in other studies that tested ARIMA models for forecasting small pelagic catch [@StergiouChristou1996]. We thus used AR-only models, however we tested both linear and non-linear models using generalized additive models [GAMs, @Wood2017] of the form $x_t = s(x_{t-1}) + \epsilon_t$ and tested time-varying linear models with dynamic linear models (DLM). GAMs allow one to model the effect of a covariate as a flexible non-linear function while DLMs allow the effect of the covariate to vary over time. Our GAM approach is analogous to that taken by Jacobson and MacCall [-@JacobsonMacCall1995] in a study of the effects of SST on Pacific sardine recruitment. 128 | 129 | We compared the following catch models: 130 | 131 | * null: $ln(C_{i,t}) = ln(C_{j,t-1})$ 132 | * random walk: $ln(C_{i,t}) = \alpha + ln(C_{j,t-1})) + \epsilon_t$ 133 | * linear AR-1: $ln(C_{i,t}) = \alpha + \beta ln(C_{j,t-1})) + \epsilon_t$ 134 | * linear AR-2: $ln(C_{i,t}) = \alpha + \beta_1 ln(C_{j,t-1})) + \beta_2 ln(C_{k,t-2})) + \epsilon_t$ 135 | * DLM AR-1: $ln(C_{i,t}) = \alpha_t + \beta_t ln(C_{j,t-1})) + \epsilon_t$ 136 | * GAM AR-1: $ln(C_{i,t}) = \alpha + s(ln(C_{j,t-1})) + \epsilon_t$ 137 | * GAM AR-2: $ln(C_{i,t}) = \alpha + s_1(ln(C_{j,t-1})) + s_2(ln(C_{k,t-2})) + \epsilon_t$ 138 | 139 | \noindent $ln(C_{i,t})$ is the log catch in the current year $t$ in season $i$. We modeled two different catches: $S_t$ (Jul-Sep) and $N_t$ (Oct-Jun). The catches were logged to stabilize and normalize the variance. $s()$ is a non-linear function estimated by the GAM algorithm. The model is primarily statistical, meaning it should not be thought of as a population growth model. We tested models with prior year and two years prior Oct-Mar catch ($N_{t-1}$ and $N_{t-2}$) and Jul-Sep catch ($S_{t-1}$ and $S_{t-2}$) as the explanatory catch variable. $S_t$ was not used as a predictor for $N_t$ because $S_t$ is the quarter immediately prior to $N_t$ and would not be available for a forecast model since time is required to process landings data. The catch models were fit to 1984 to 2015 catch data, corresponding to the years when the SST, upwelling and precipitation data were available. 140 | 141 | Once the catch models were determined, the covariates were studied individually and then jointly. As with the catch models, F-tests, AIC and LOOCV (leave-one-out cross-validation) on nested sets of models were used to evaluate the support for models with covariates. The smoothing term was fixed at an intermediate value (sp=0.6) instead of being treated as an estimated variable. Our models for catch with covariates took the form 142 | $ln(C_{i,t}) = M + \alpha + s_1(V_{1,t}) + s_2(V_{2,t-1}) + \epsilon_t$, $ln(C_{i,t}) = M + \alpha + \beta_1 V_{1,t} + \beta_2 V_{2,t-1} + \epsilon_t$, and $ln(C_{i,t}) = M + \alpha + \beta_t V_{1,t} + \epsilon_t$ 143 | where $M$ was the best catch model from step 1 and $V$ is a covariate. Thus models with covariates modeled as a linear, non-linear and time-varying effect were compared. 144 | 145 | 146 | # Results {-} 147 | 148 | ## Catches in prior seasons as explanatory variables 149 | 150 | Using the 1984-2015 catch data, the time-period that overlaps our available environmental data, the Jul-Sep catch models were compared against a "naive" model in which the forecasted Jul-Sep catch is the Jul-Sep catch in the prior year. The "naive" model has no estimated parameters and is a standard null model for time series modeling. Models with $ln(N_{t-1})$ (Oct-Mar catch in prior year) as the explanatory covariate were strongly supported over the naive model and over models with $ln(S_{t-1})$ (Jul-Sep catch in prior year) as the explanatory variable (Tables `r ref("tabappA:spawner-model-linear", pre="A")` and `r ref("tabappA:spawner-model-nonlinear", pre="A")`). Addition of the catch two years prior, $ln(N_{t-2})$ or $ln(S_{t-2})$, was not supported (by AIC or F-tests) for either the linear or non-linear models. We tested the support for non-linearity in the effect of the prior year catch by comparing models with $ln(N_{t-1})$ or $ln(S_{t-1})$ included as a linear effect or as a non-linear effect using GAMs. 151 | 152 | As diagnostic checks, we repeated the model comparisons with the landings data set from 1956 to 1983. The results were the same for the Jul-Sep catch (Table `r ref("tabappA:spawner-model-1956", pre="A")`) with the model with $ln(N_{t-1})$ included as a non-linear covariate giving the lowest AIC and LOOCV. For the Oct-Mar catch (Table `r ref("tabappA:nonspawner-model-time-c", pre="A")`), the results were very similar but not identical. The model with $ln(N_{t-1})$ included as a non-linear covariate had the lowest LOOCV while the models with $ln(N_{t-1})$ and $ln(S_{t-2})$ or $ln(S_{t-2})$ had the lowest AIC (though less than 1 from the AIC of the $ln(N_{t-1})$ model). We also did an influential years test using leave-one-out cross-validation (Appendix F). This test involved leaving out one year and repeating the model selection tests. This analysis supported the selected base models using the 1984-2015 data. The dynamic linear models (allowing a time-varying effect of prior catch) performed poorly for the Jul-Set catch with high AIC and LOOCV. For the Oct-Mar catch, the performance was mixed with higher AIC but lower LOOCV for one of the DLMs. 153 | 154 | Based on the model selection tests, the following non-linear model was chosen as the base model for Jul-Sep ($S_t$) catch: 155 | $$M0: ln(S_t) = \alpha + s(ln(N_{t-1})) + \epsilon_t.$$ 156 | Two base non-linear models were chosen for Oct-Mar ($N_t$) catch: 157 | $$M1: ln(N_t) = \alpha + s_1(ln(N_{t-1})) + s_2(ln(S_{t-2})) + \epsilon_t$$ 158 | $$M2: ln(N_t) = \alpha + s(ln(N_{t-1})) + \epsilon_t$$ 159 | Note that although M0 was the best model for Jul-Sep catch, it was only weakly explanatory. The maximum adjusted $R^2$ was less than 30% (Table `r ref("tabappA:spawner-model-nonlinear", pre="A")`). For the Oct-Mar catch, M1 and M2 were more explanatory with an adjusted $R^2$ of 45.3% for M1 and 56.6% for M2 (Table `r ref("tabappA:nonspawner-model-time-b", pre="A")`). 160 | 161 | 162 | ## Environmental covariates as explanatory variables 163 | 164 | There was no support for using precipitation during the summer monsoon (June-July) or pre-monsoon period (April-May) as an explanatory variable for the Jul-Sep or Oct-Mar catch (hypotheses S1 and S2; Tables `r ref("tabappB:spawner-model-precip", pre="B")`, `r ref("tabappB:nonspawner-model-precip", pre="B")` and `r ref("tabappB:nonspawner-model-precipM2", pre="B")`). This was the case whether precipitation in the current or previous season was used, if precipitation was included as a non-linear or linear effect, and if either precipitation during early monsoon (June-July) or pre-monsoon (April-May) was used as the covariate. Jul-Sep catch overlaps with the late spawning period and precipitation is often thought to trigger spawning, however we were unable to find any consistent association of catch with precipitation. Raja [-@AntonyRaja1974] posited that the appropriate time period for the effect of rainfall is the weeks before and after the new moon when spawning is postulated to occur and not the total rainfall during the monsoon season. Thus the lack of correlation may be due to using too coarse of a time average for the precipitation. 165 | 166 | Instead we found support for the covariates indirectly and directly associated with productivity and food availability: upwelling intensity and surface chlorophyll. The correlation between landings and upwelling was only found for upwelling in the current season. No correlation was found when we used the upwelling index from the prior season. The correlation between landings and upwelling was found for both Jul-Sep and Oct-Mar landings and with either SST-based upwelling index: average nearshore SST along the Kerala coast during June-September or the average SST nearshore versus offshore differential (UPW) off Kochi in June-September (Table `r ref("tab:covariate-models")`, `r ref("tabappB:spawner-model-sst", pre="B")`, `r ref("tabappB:nonspawner-model-sst", pre="B")` and `r ref("tabappB:nonspawner-model-sstM2", pre="B")`). These two upwelling indices are correlated but not identical. The model with average June-September nearshore SST was more supported than the model using the SST differential off Kochi. For Jul-Sep catch, this model with a non-linear response had an adjusted $R^2$ of 41.0 versus an adjusted $R^2$ of 24.4 for the model with no covariates (Table `r ref("tabappB:spawner-model-sst", pre="B")`), and for Oct-Mar catch, the adjusted $R^2$ was 61.8 versus 56.6 (Table `r ref("tabappB:nonspawner-model-sst", pre="B")`). Note, that this covariate is June-September in the current season and overlaps with the July-September catch. Thus this model cannot be used to forecast Jul-Sep catch and gives only a month-prior forecast for Oct-Mar, but it does help us understand what factors may be influencing catch. 167 | 168 | 169 | # Discussion 170 | 171 | Sardines in all the world's ecosystems exhibit large fluctuations in abundance [@Checkleyetal2017]. These small forage fish are strongly influenced by natural variability in the ocean environment. Upwelling, influenced by both large-scale forces such as regimes shifts and El Niño/Southern Oscillation patterns [@AlheitHagen1997; @Schwartzloseetal2010] and by seasonal wind and current patterns, brings nutrient rich and oxygen rich waters to the surface. This drives the seasonal variability in phytoplankton resources and in turn sardine prey [@Bakunetal2008]. Local variability in temperature, salinity, and oxygen levels have both direct and indirect effects on sardine reproduction, recruitment and survival [@Checkleyetal2017]. Sardines are also influenced by competition and predation by other species and well-known for their sensitivity to over-fishing which has been linked to many fishery collapses [@Kripaetal2018]. 172 | 173 | Many studies on Pacific sardines have looked at the correlation between ocean surface temperature (SST) and recruitment. Temperature can have direct effect on larval survival and growth and an indirect effect on food availability. Studies in the California Current System, have found that SST explains (a portion of) year-to-year variability in Pacific sardine recruitment [@JacobsonMacCall1995; @Checkleyetal2009; @LindegrenCheckley2012; @Checkleyetal2017] and that the average nearshore temperature over multiple seasons is the relevant explanatory variable. Similar to these studies, we found that the average nearshore SST over multiple seasons was the covariate that explained the most variability in catch both in the monsoon and post-monsoon months. McClatchie et al. [-@McClatchieetal2010] found no relationship with SST and Pacific sardine recruitment, however their analysis used a linear relationship while the other studies, and ours, that found a relationship allowed non-linearity. Both Jacobson and MacCall (1995) and Checkley et al. (2017) found a step-like response function for temperature: below a threshold value the effect of temperature was linear and above the threshold, the effect was flat and at lower temperatures the effect was negative and became positive as temperature increased. Our analysis found a similar pattern with a negative effect when the 2.5-year average temperature was below $28.35^\circ$C and positive above and with the positive effect leveling off above $28.5^\circ$C (Figure `r ref("fig:cov-effects")`). 174 | 175 | 176 | # Conclusions 177 | 178 | The temperature of the Western Indian Ocean, of which the Southeast Arabian Sea is a part, has been increasing over the last century at a rate higher than any other tropical ocean [@Roxyetal2014] and the warming has been most extreme during the summer monsoon months. This ocean climate change is affecting oil sardine distributions, with significant landings now occurring north of Goa [@Vivekanandanetal2009]. Continued warming is expected to affect the productivity of the region via multiple pathways, including both the direct effects of temperature change on the physiology and behavior of organisms and multiple of indirect effects [@Moustahfidetal2018]. These indirect effects include changes to salinity, oxygen concentrations, currents, wind patterns, ocean stratification and upwelling spatial patterns, phenology, and intensity. Incorporating environmental covariates into landings forecasts has the potential to improve fisheries management for small pelagics such as oil sardines in the face of a changing ocean environment [@Tommasietal2016; @Haltuchetal2019]. However, monitoring forecast performance and covariate performance in models will be crucial as a changing ocean environment may also change the association between landings and average sea surface temperature. 179 | 180 | 181 | 182 | # References 183 | 184 |
185 | 186 | \clearpage 187 | 188 | # Figure Legends 189 | 190 | Figure `r ref("fig:studyarea")`. Southwest coast of India with the latitude/longitude boxes used for the satellite data. Kerala State is marked in grey and the oil sardine catch from this region is being modeled. For the SST covariate, 'nearshore' SST (ns-SST) was the average of boxes 2 to 5 (0 to 80km offshore), and 'regional' SST (r-SST) was the average of boxes 2 to 5 and 7 to 10 (0 to 160km offshore). 191 | 192 | ```{r catch-dat, echo=FALSE,message=FALSE,warning=FALSE} 193 | # Here I am computing values which will applear in the text 194 | dat <- oilsardine_qtr 195 | catchmeans <- round(tapply(dat$Kerala, dat$Qtr, mean, na.rm=TRUE)) 196 | names(catchmeans) <- paste("Q",1:4,sep="") 197 | catchmeds <- round(tapply(dat$Kerala, dat$Qtr, median, na.rm=TRUE)) 198 | names(catchmeds)=paste("Q",1:4,sep="") 199 | ``` 200 | 201 | Figure `r ref("fig:catch")`. Quarterly catch data 1956-2014 from Kerala. The catches have a strong seasonal pattern with the highest catches in quarter 4 (Oct-Dec). Note that the fishery is closed July 1 to mid-August, thus the fishery is only open 1.5 months in quarter 3 (Jul-Sep). The mean catch (metric tonnes) in quarters 1 to 4 are `r round(catchmeans["Q1"]/1000,1)`, `r round(catchmeans["Q2"]/1000,1)`, `r round(catchmeans["Q3"]/1000,1)`, and `r round(catchmeans["Q4"]/1000,1)` metric tonnes respectively. 202 | 203 | Figure `r ref("fig:SSTts")`. Key oil sardine life history events overlaid on the monthly sea surface temperature in the nearshore and offshore and the nearshore chlorophyll-a concentration. 204 | 205 | Figure `r ref("fig:COVts")`. Remote sensing covariates used in the analysis. All data are monthly averages over Box 4 in Figure `r ref("fig:studyarea")` on the Kerala coast off of Kochi. Panel A) Upwelling Index. The upwelling index is the difference between the nearshore sea surface temperature (SST) and the offshore SST defined as 3 degrees longitude offshore. Panel B) Nearshore surface chlorophyll-a (CHL). The CHL data are only available from 1997 onward. Panel C) Sea surface temperature from Advanced Very High Resolution Radiometer (AVHRR). Panel D) Average daily rainfall (mm/day) off the Kerala coast. 206 | 207 | Figure `r ref("fig:cov-effects")`. Effects of the two most influential covariates estimated from the GAM models: 2.5 year average nearshore (boxes 2-5) SST and upwelling intensity in June-September (spawning months). Panel A) Effect of the 2.5 year average nearshore SST on Jul-Sep catch (late spawning and early post-spawning months). Panel B) Effect of upwelling (nearshore/offshore SST differential) during June-September in the current season on Jul-Sep catch. The index is the difference between offshore and inshore SST, thus a negative value indicates warmer coastal surface water than offshore. Panel C) Effect of the 2.5 year average nearshore SST on Oct-Mar catch (post-monsoon, age-0, -1, -2 year fish). Panel D) Effect of upwelling (nearshore/offshore SST differential) during June-September in the current season on Oct-Mar catch. 208 | 209 | Figure `r ref("fig:fitted")`. Fitted versus observed catch with models with and without the 2.5 year average nearshore SST included as a covariate. The line is the one-to-one line (prediction equals observed). Panel A) Fitted versus observed log catch in Jul-Sep (late monsoon) with only Oct-Mar catch in the previous season as the covariate: $S_t = s(N_{t-1}) + \epsilon_t$. Panel B) Fitted versus observed log catch in Jul-Sep with the 2.5-year average SST added as a covariate to the model in panel A. This model was: $S_t = s(N_{t-1}) + s(V_{t}) + \epsilon_t$. Panel C) Fitted versus observed log Oct-Mar catch with only Oct-Mar catch in the previous season and Jul-Sep catch two seasons prior as the covariates: $N_t = s(N_{t-1}) + s(S_{t-2}) + \epsilon_t$. Panel D) Fitted versus observed log Oct-Mar catch with 2.5-year average SST ($V$) added. This model was $N_t = s(N_{t-1}) + s(S_{t-2}) + s(V_t) + \epsilon_t$. 210 | 211 | 212 | ```{r, results="asis", echo=FALSE} 213 | cat("\\clearpage") 214 | ``` 215 | 216 | 217 | ```{r child = 'Tables.Rmd', echo=FALSE} 218 | ``` 219 | 220 | ```{r child = 'Figures.Rmd', echo=FALSE} 221 | ``` 222 | 223 | ```{r, results="asis", echo=FALSE} 224 | cat("\\clearpage") 225 | ``` 226 | 227 | 228 | -------------------------------------------------------------------------------- /apa-edit.csl: -------------------------------------------------------------------------------- 1 | 2 | 1519 | --------------------------------------------------------------------------------