Since 2008, I have experienced to give several seminars in foreign countries and provide lectures for international students/trainees in my country. In most cases, I used ppt slides to illustrate some theories and methods and then employed excel sheets and example codes of R for hands-on exercises. Still I have been using those materials but I have been also developing my handout for convenience for audiences as well as myself.
The first part of this manuscript was originally prepared for a seminar given in the Inland Fishery Resources Development And Management Department (IFRDMD) in Indonesia on December 26-28, 2018. The manuscript was extended this time to cover several additional topics for seminar given in the National Aquatic Resources Research & Development Agency (NARA) on March 13-15, 2019. However, still the contents have been updated and modified because of necessities to improve texts and correct some codes based on feedback from participants of the seminar/lecture. In addition, I may develop it to a printed version of the text. Therefore, please DO NOT pass this document to anyone else without author’s permission. I hope this is understandable.
I would like to express my sincere appreciation for the invitation by NARA to give me a nice opportunity of the seminar and visit Colombo. I would also like to thank my friend, Sujeewa Haputhantri, for his excellent coordination and thank Steve Creech for his kind arrangement.
Before starting the seminar, please visit the following website and download the applications which we will use in the seminar.
First, please visit the following web site and download “R 3.5.xx for Windows” for example:
https://cran.r-project.org/
%
Then please visit the web site below and download the free version of “RStudio Desktop”:
https://www.rstudio.com/products/rstudio/download/
%
I will explain how you can create a memo/report of your analysis with R in a easy way with Rmarkdown. I’m writing this handout using it.
Please install the following packages in R by using a command before the seminar.
install.packages("package name")
install.packages("knitr")
install.packages("rmarkdown")
install.packages("kableExtra")
install.packages("ggplot2")
install.packages("gridExtra")
install.packages("mgcv")
install.packages("fields")
install.packages("ggmap")
install.packages("marmap")
install.packages("mapdata")
install.packages("shiny")
Then you can call those libraries.
library(knitr)
library(rmarkdown)
library(kableExtra)
library(ggplot2)
library(gridExtra)
library(mgcv)
library(fields)
library(ggmap)
library(marmap)
library(mapdata)
library(shiny)
#May not be used (for TK-memo)
#library(boot) # for regression diagnosis
#library(MASS)
#library(MuMIn)
#library(dplyr)
I would like to begin with a very brief introduction of stock assessment and management in a general sense. Message here are as follows:
You may see a lack of information when you try to conduct stock assessment and develop any management plans. However, no one has a perfect information. Not late to start to collect data and information on biology/ecology, abundance, and other key parameters. If you don’t think it seriously at this moment, you have the same problem 5 or 10 years later. Let’s set short-term targets and also medium- or longer-term objectives.
Statistical works including just visual presentation of data and map and summaries as simple tables are of course useful. However, more elaborated analyses such as modelling and its exploration, statistical inference (estimation, hypothesis testing and forecasting), and risk assessment are so useful and mandate for current and future stock assessment and management.
Others in the slides…
a <- c(1,2,3,4,5)
a
[1] 1 2 3 4 5
sum(a)
[1] 15
mean(a)
[1] 3
a+10
[1] 11 12 13 14 15
5*a
[1] 5 10 15 20 25
a^2
[1] 1 4 9 16 25
log(a)
[1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379
a[3]
[1] 3
a[c(1,2,3)]
[1] 1 2 3
a[-c(2,4)]
[1] 1 3 5
b <- seq(10,50,10)
a+b
[1] 11 22 33 44 55
a*b
[1] 10 40 90 160 250
b/a
[1] 10 10 10 10 10
ss <- 0
for(i in 1:10){
ss <- ss + i
}
ss
[1] 55
# Just in case, this is done simply as
a<- seq(1,10)
a
[1] 1 2 3 4 5 6 7 8 9 10
sum(a)
[1] 55
Start with your capital $20 and contiune 100 times betting with $1.
p <- 0.5
Bet <- 1
Capital <- 20
Maxit <- 100 + 1
X <- numeric(Maxit)
X[1] <- Capital
for(j in 2:Maxit)
{
if(X[j-1]>0) X[j] <- X[j-1] + sample(Bet*c(-1,1),1,prob=c(1-p,p))
}
plot(X, type="l", ylim=c(0, max(X)*1.2), xlab="Trial", ylab="State")
abline(Capital, 0, lty=2, col="red")
We now define a function for the computation above and then run it under different setting.
Gambling1 <- function(p, Bet, Capital, Maxit=101, Fig=F)
{
X <- numeric(Maxit)
X[1] <- Capital
for(j in 2:Maxit)
{
if(X[j-1]>0) X[j] <- X[j-1] + sample(Bet*c(-1,1),1,prob=c(1-p,p))
}
if(Fig==T)
{
plot(X, type="l", ylim=c(0, max(X)*1.2), xlab="Trial", ylab="State")
abline(Capital, 0, lty=2, col="red")
}
}
Let us run function “Gambling1”.
par(mfrow=c(2,2), mar=c(3,3,3,3))
Gambling1(p=0.5, Bet=1, Capital=20, Fig=T)
Gambling1(p=0.5, Bet=1, Capital=20, Fig=T)
Gambling1(p=0.5, Bet=1, Capital=10, Fig=T)
Gambling1(p=0.5, Bet=1, Capital=10, Fig=T)
We are now extending the function above to deal with multiple simulations.
Gambling2 <- function(p, Bet, Capital, Maxit=101, Nsim=100)
{
X <- array(0, c(Nsim, Maxit))
for(i in 1:Nsim)
{
X[i,1] <- Capital
for(j in 2:Maxit)
{
Tmp <- X[i,(j-1)] + sample(Bet*c(-1,1),1,prob=c(1-p,p))
if(Tmp >0) X[i,j] <- Tmp
if(Tmp<=0) X[i,j] <- -10
}
}
plot(X[1,], type="l", ylim=c(0, max(X)*1.2),
xlab="Trial", ylab="State", col="grey")
for(i in 1:Nsim) points(X[i,], type="l", col="grey")
abline(Capital, 0, lty=2, col="red")
hist(X[,Maxit], col="orange", xlab="Final state", main="")
return(X)
}
Then again let us run function “Gambling2”
par(mfrow=c(2,2), mar=c(3,3,3,3))
Res <- Gambling2(p=0.5, Bet=1, Capital=20, Maxit=100, Nsim=100)
Res <- Gambling2(p=0.5, Bet=1, Capital=20, Maxit=1000, Nsim=100)
We will conduct a very simple analysis for body proportion of Japanese fish species with statistical testing and visual presentation. We first read a data file named as “Horsemackerel.csv”.
# Read the data file
Data <- read.csv("Data/Horsemackerel.csv", header=T)
head(Data)
Species TL FL SL HL BD ED
1 Maaji 297 259 235 65 59 15.4
2 Maaji 285 263 255 65 61 15.2
3 Maaji 285 255 263 65 63 15.1
4 Maaji 319 275 269 71 63 16.6
5 Maaji 297 259 235 65 59 15.1
6 Maaji 194 172 160 45 42 13.6
# Extract the data column and create a new object "proportion"
Data$BD
[1] 59 61 63 63 59 42 42 50 46 44 40 53 34 38 38 36 36 36 34 38 37 37 40
[24] 36 34 38 37 37 40 38 31 30 36 31 39 37 36 41 31 30 36 31 37 41 45 37
[47] 38 31 30 36 31 37 41 45 37 38 31 30 36 31 37 41 45 37 38 39 31 30 36
[70] 31 39 37 36 41 31 30 36 31 37 41 45 37 38 39 39 37 37 36 36 35
[ reached getOption("max.print") -- omitted 85 entries ]
Data$SL
[1] 235 255 263 269 235 160 174 182 171 168 152 203 137 149 150 145 146
[18] 145 136 148 137 145 155 145 136 148 137 145 155 145 118 122 138 133
[35] 142 129 134 152 137 143 157 150 148 150 175 166 161 137 143 157 150
[52] 148 150 175 166 161 137 143 157 150 148 150 175 166 161 141 118 122
[69] 138 133 142 129 134 152 137 143 157 150 148 150 175 166 161 205 213
[86] 215 221 189 193 197
[ reached getOption("max.print") -- omitted 85 entries ]
Proportion <- Data$BD/Data$SL
# Add "Prop" into the current data set "Data"
Data <- cbind(Data, Prop=Proportion)
attach(Data)
# Exracting data
SP <- as.numeric(Species)
SPname <- levels(Species)
SP
[1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[36] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
[71] 2 2 2 2 2 2 2 2 2 2 2 2 2 4 4 4 4 4 4 4
[ reached getOption("max.print") -- omitted 85 entries ]
SPname
[1] "Kaiwari" "Maaji" "Maruaji" "Moro"
# Scatter plot andboxplot
par(mfrow=c(1,2)) #Splitting screen
plot(BD~SL, pch=SP, col=SP, xlab="Standard Length (SL)", ylab="Body Depth (BD)")
legend(220, 85, legend=levels(Species), pch=1:4, col=1:4, bty="n")
boxplot(Prop~Species, ylab="Proportion")
# Histogram of proportion by species
par(mfcol=c(2,2))
for(i in 1:length(SPname)) hist(Prop[SP==i], xlab="Prop", main=paste(SPname[i]), col="gray")
A library “ggplot2” provides us beautiful figures, but it requires a bit training of syntax, so I shall use a quicker version of command on ggplot.
plot1 <- qplot(SL, BD, col=Species)
plot2 <- qplot(Species, Prop, geom="boxplot")
plot3 <- qplot(Species, Prop, geom="boxplot", col=Species)
plot4 <- qplot(Prop, facets=Species~., fill=Species, data=Data)
grid.arrange(plot1, plot2, plot3, plot4, nrow=2, ncol=2)
y <- split(Prop, Species)
y$Kaiwari
[1] 0.4893617 0.5074627 0.5056818 0.5080645 0.4916667 0.4556213 0.4528302
[8] 0.4962406 0.4714286 0.4771242 0.4838710 0.4887640 0.4842767 0.4838710
[15] 0.4842767 0.4887640 0.4714286 0.4771242 0.4838710 0.4864865 0.4831461
[22] 0.4410256 0.4462810 0.4410256 0.4462810 0.4410256 0.4462810 0.4831461
[29] 0.4864865 0.4410256 0.4462810
length(y$Kaiwari)
[1] 31
sapply(y, length)
Kaiwari Maaji Maruaji Moro
31 83 15 46
lapply(y, length)
$Kaiwari
[1] 31
$Maaji
[1] 83
$Maruaji
[1] 15
$Moro
[1] 46
Ns <- sapply(y, length)
Mean <- sapply(y, mean)
SD <- sapply(y, sd)
data.frame(Nsample=Ns, Mean, SD)
Nsample Mean SD
Kaiwari 31 0.4738781 0.02159171
Maaji 83 0.2477849 0.02045780
Maruaji 15 0.2273268 0.01283770
Moro 46 0.1908011 0.01381693
lapply(y, t.test, mu=0.2)
$Kaiwari
One Sample t-test
data: X[[i]]
t = 70.624, df = 30, p-value < 2.2e-16
alternative hypothesis: true mean is not equal to 0.2
95 percent confidence interval:
0.4659582 0.4817980
sample estimates:
mean of x
0.4738781
$Maaji
One Sample t-test
data: X[[i]]
t = 21.28, df = 82, p-value < 2.2e-16
alternative hypothesis: true mean is not equal to 0.2
95 percent confidence interval:
0.2433179 0.2522520
sample estimates:
mean of x
0.2477849
$Maruaji
One Sample t-test
data: X[[i]]
t = 8.2442, df = 14, p-value = 9.634e-07
alternative hypothesis: true mean is not equal to 0.2
95 percent confidence interval:
0.2202175 0.2344360
sample estimates:
mean of x
0.2273268
$Moro
One Sample t-test
data: X[[i]]
t = -4.5155, df = 45, p-value = 4.527e-05
alternative hypothesis: true mean is not equal to 0.2
95 percent confidence interval:
0.1866980 0.1949042
sample estimates:
mean of x
0.1908011
res.t.test <- lapply(y, t.test, mu=0.2)
# variance same?
var.test(y[[2]],y[[3]])
F test to compare two variances
data: y[[2]] and y[[3]]
F = 2.5395, num df = 82, denom df = 14, p-value = 0.05378
alternative hypothesis: true ratio of variances is not equal to 1
95 percent confidence interval:
0.9838916 5.1560229
sample estimates:
ratio of variances
2.539471
# t-test
t.test(y[[2]],y[[3]], var.equal=T)
Two Sample t-test
data: y[[2]] and y[[3]]
t = 3.7332, df = 96, p-value = 0.0003205
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
0.009580294 0.031336083
sample estimates:
mean of x mean of y
0.2477849 0.2273268
t.test(y[[2]],y[[3]])
Welch Two Sample t-test
data: y[[2]] and y[[3]]
t = 5.1098, df = 28.765, p-value = 1.91e-05
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
0.01226681 0.02864956
sample estimates:
mean of x mean of y
0.2477849 0.2273268
Under an assumption of “common variance” across species,
res.lm <- lm(Prop~Species)
summary(res.lm)
Call:
lm(formula = Prop ~ Species)
Residuals:
Min 1Q Median 3Q Max
-0.041118 -0.012597 0.002215 0.011178 0.043030
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.473878 0.003342 141.80 <2e-16 ***
SpeciesMaaji -0.226093 0.003917 -57.73 <2e-16 ***
SpeciesMaruaji -0.246551 0.005852 -42.13 <2e-16 ***
SpeciesMoro -0.283077 0.004324 -65.47 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.01861 on 171 degrees of freedom
Multiple R-squared: 0.9653, Adjusted R-squared: 0.9647
F-statistic: 1584 on 3 and 171 DF, p-value: < 2.2e-16
res.lm <- lm(Prop~Species-1)
summary(res.lm)
Call:
lm(formula = Prop ~ Species - 1)
Residuals:
Min 1Q Median 3Q Max
-0.041118 -0.012597 0.002215 0.011178 0.043030
Coefficients:
Estimate Std. Error t value Pr(>|t|)
SpeciesKaiwari 0.473878 0.003342 141.80 <2e-16 ***
SpeciesMaaji 0.247785 0.002042 121.32 <2e-16 ***
SpeciesMaruaji 0.227327 0.004804 47.32 <2e-16 ***
SpeciesMoro 0.190801 0.002743 69.55 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.01861 on 171 degrees of freedom
Multiple R-squared: 0.9959, Adjusted R-squared: 0.9958
F-statistic: 1.048e+04 on 4 and 171 DF, p-value: < 2.2e-16
res.anova1 <- anova(res.lm)
res.anova1
Analysis of Variance Table
Response: Prop
Df Sum Sq Mean Sq F value Pr(>F)
Species 4 14.5072 3.6268 10476 < 2.2e-16 ***
Residuals 171 0.0592 0.0003
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
In case of “heterogeneity in variance”,
res.bartlett <- bartlett.test(Prop~Species)
res.bartlett
Bartlett test of homogeneity of variances
data: Prop by Species
Bartlett's K-squared = 12.515, df = 3, p-value = 0.005813
res.anova2 <- oneway.test(Prop~Species, var.equal = FALSE)
res.anova2
One-way analysis of means (not assuming equal variances)
data: Prop and Species
F = 1373.1, num df = 3.00, denom df = 54.97, p-value < 2.2e-16
pairwise.t.test(Prop,Species)
Pairwise comparisons using t tests with pooled SD
data: Prop and Species
Kaiwari Maaji Maruaji
Maaji < 2e-16 - -
Maruaji < 2e-16 0.00013 -
Moro < 2e-16 < 2e-16 9.8e-10
P value adjustment method: holm
pairwise.t.test(Prop,Species, pool.sd = FALSE)
Pairwise comparisons using t tests with non-pooled SD
data: Prop and Species
Kaiwari Maaji Maruaji
Maaji < 2e-16 - -
Maruaji < 2e-16 1.9e-05 -
Moro < 2e-16 < 2e-16 1.9e-09
P value adjustment method: holm
pairwise.t.test(Prop,Species, pool.sd = FALSE, p.adj = "bonf")
Pairwise comparisons using t tests with non-pooled SD
data: Prop and Species
Kaiwari Maaji Maruaji
Maaji < 2e-16 - -
Maruaji < 2e-16 0.00011 -
Moro < 2e-16 < 2e-16 5.7e-09
P value adjustment method: bonferroni
We shall start with some regression analyses for estimating biological parameters using some regression methods.
In R, lots of types of regression analyses can be conducted (see table below).
%
The common allometric function is defined as follows: \[ W = a L^b. \]
Our example data set is a combination of length and weight observed for rainbow trouts in Ohizumi experimental station in Japan.
We shall start reading the data and showing a simple scatter plot.
# Reading and plotting the data
Data <- read.csv("Data/Rainbowtrout.csv", header=T)
names(Data)
[1] "Length" "Weight"
head(Data)
Length Weight
1 7.5 10
2 9.2 9
3 9.5 25
4 9.7 35
5 10.5 20
6 10.6 35
Length <- Data$Length
Weight <- Data$Weight
plot(Length, Weight, xlab="Length (cm)", ylab="Weight (g)",
main="Allometric data for rainbow trouts")
Then we conduct a simple regression analysis for the following simple linear model.
\[ \log W_i = \log a + b \log L_i + \varepsilon_i, \quad \varepsilon_i \sim N(0,\sigma^2). \]
# Conducting regression analysis
res <- lm(log(Weight)~log(Length))
summary(res)
Call:
lm(formula = log(Weight) ~ log(Length))
Residuals:
Min 1Q Median 3Q Max
-0.59889 -0.08977 -0.00832 0.14493 0.69146
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -3.04898 0.28442 -10.72 6.67e-13 ***
log(Length) 2.60235 0.08474 30.71 < 2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.286 on 37 degrees of freedom
Multiple R-squared: 0.9622, Adjusted R-squared: 0.9612
F-statistic: 943.1 on 1 and 37 DF, p-value: < 2.2e-16
plot(log(Length), log(Weight))
abline(res)
We can extract the parameter estimates of \(\alpha=\log a\) and \(\beta=b\).
# List of objects
names(res)
[1] "coefficients" "residuals" "effects" "rank"
[5] "fitted.values" "assign" "qr" "df.residual"
[9] "xlevels" "call" "terms" "model"
names(summary(res))
[1] "call" "terms" "residuals" "coefficients"
[5] "aliased" "sigma" "df" "r.squared"
[9] "adj.r.squared" "fstatistic" "cov.unscaled"
# Extracting parameter estimates (the both are same meanings)
summary(res)$coef
Estimate Std. Error t value Pr(>|t|)
(Intercept) -3.048982 0.28442057 -10.71998 6.667534e-13
log(Length) 2.602353 0.08474089 30.70953 6.255463e-28
coef(res)
(Intercept) log(Length)
-3.048982 2.602353
alpha.est <- as.numeric(coef(res)[1])
beta.est <- as.numeric(coef(res)[2])
# Parameter transformation
a.est <- exp(alpha.est)
b.est <- beta.est
Est <- c(a.est, b.est); Est
[1] 0.04740718 2.60235273
We can also extract confidence intervals of parameter estimates.
# Use a function "confint"
confint(res)
2.5 % 97.5 %
(Intercept) -3.625272 -2.472691
log(Length) 2.430651 2.774054
confint(res)[1,]
2.5 % 97.5 %
-3.625272 -2.472691
confint(res)[2,]
2.5 % 97.5 %
2.430651 2.774054
# Alternatively....
confint(res, "(Intercept)")
2.5 % 97.5 %
(Intercept) -3.625272 -2.472691
confint(res, "log(Length)")
2.5 % 97.5 %
log(Length) 2.430651 2.774054
# For the following summary
alpha.ci <- confint(res)[1,]
beta.ci <- confint(res)[2,]
a.ci <- exp(alpha.ci)
b.ci <- beta.ci
CI <- rbind(a.ci, b.ci); CI
2.5 % 97.5 %
a.ci 0.02664184 0.08435757
b.ci 2.43065137 2.77405408
Then a summary is given as follows:
Out <- cbind(Est, CI)
row.names(Out) <- c("a", "b")
Out
Est 2.5 % 97.5 %
a 0.04740718 0.02664184 0.08435757
b 2.60235273 2.43065137 2.77405408
kable(Out)
Est | 2.5 % | 97.5 % | |
---|---|---|---|
a | 0.0474072 | 0.0266418 | 0.0843576 |
b | 2.6023527 | 2.4306514 | 2.7740541 |
In case of PDF using LaTeX Syntax,
# For latex output (may not be effective in html document)
kable(Out, booktabs=T, longtable=F, caption="Summary of parameter estimates.") %>%
kable_styling(latex_options = c("striped", "hold_position"))
Est | 2.5 % | 97.5 % | |
---|---|---|---|
a | 0.0474072 | 0.0266418 | 0.0843576 |
b | 2.6023527 | 2.4306514 | 2.7740541 |
In the general formulation of regression analysis, \[ y_i = \alpha + \beta x_i + \varepsilon_i, \quad \varepsilon_i \sim N(0,\sigma^2). \] the standardized residual defined as \[ e_i = \frac{(observation)-(fitted)}{estimate \ of \ sd} = \frac{y_i-(\hat{\alpha} + \hat{\beta} x_i )}{\hat{\sigma}} \] would be distributed to the standard normal distribution N(0,1). Let’s see if this is the case or not.
# Diagnostics
names(summary(res))
[1] "call" "terms" "residuals" "coefficients"
[5] "aliased" "sigma" "df" "r.squared"
[9] "adj.r.squared" "fstatistic" "cov.unscaled"
sigma.est <- summary(res)$sigma
# Standardized residuals, which should be distributed to N(0,1)
e <- (log(Weight)-res$fitted.values)/sigma.est
# Plot and histogram
plot(res$fitted.values, e, ylim=c(-2.5, 2.5), ylab="Standardized residuals")
abline(0,0)
abline(qnorm(0.025),0,lty=2)
abline(qnorm(0.975),0,lty=2)
hist(e, xlab="Standardized residuals", main="Histogram of standardized residuals")
# Default plots in "lm" in R
par(mfrow=c(2,2), mar=c(4,4,3,2))
plot(res)
There two types of confidence intervals: - Confidence interval for regression estimates
- Confidence interval for prediction
# Confidence interval of the curve
plot(Length, Weight, xlab="Length (mm)", ylab="Weight (g)", main="With CI for estimates")
pred <- exp(predict(res, int="c", level = 0.95))
matlines(Length, pred, lty=c(1,2,2), col=1)
# Confidence interval of the prediction
plot(Length, Weight, xlab="Length (mm)", ylab="Weight (g)", main="With CI for prediction")
pred <- exp(predict(res, int="p", level = 0.95))
matlines(Length, pred, lty=c(1,2,2), col=1)
Why “generalized”
- Distribution assumption (not necessarily “normal distribution”)
- Binomial, Poisson, Gamma distributions etc.
- Regression covariates are linked with a “link function”
GLM in R
- “glm” (almost same syntax as “lm”)
- Estimate, CI, testing, AIC, …
Assumption
- You are analyzing “age at sexual maturity (ASM)” of a fish species
- You observe the numbers of mature and immature individuals by age
Structural model
- Maturity is a function of age, \(p(a)\)
- \(p(a)\) should be a monotonically increasing function of \(a\) like a sigmoid function:
Logistic function
\(p(a)=\displaystyle \frac{e^{\beta_0 + \beta_1 a}}{1+e^{\beta_0 + \beta_1 a}} \ \Longrightarrow \ \log \frac{p(a)}{1-p(a)} = \beta_0 + \beta_1 a\)
Probit function
\(p(a)=\displaystyle \int_{-\infty}^a f(z) dz\)
# Definition of logistic function (the parameters are beta0 and beta1)
LogisticFn <- function(x,beta0,beta1) {1.0/(1.0+exp(-beta0-beta1*x))}
Age <- seq(0,10,0.01)
# beta0=-5, beta1=1
plot(Age, LogisticFn(Age,-5,1), type="l", ylab="Maturity", lty=1)
# beta0=-2.5, beta1=0.5
points(Age, LogisticFn(Age,-2.5,0.5), type="l", lty=2)
# beta0=-10, beta1=2
points(Age, LogisticFn(Age,-10,2), type="l", lty=3)
# legends
legend(0, 1, lty=1:3,
legend=c("beta0=-5, beta1=1","beta0=-2.5, beta1=0.5","beta0=-10, beta1=2"),bty="n")
Distributional assumption
- Two state (mature/immature) -> Binomial distribution
- \(N_a\): number of sampled individuals of age \(a\)
- \(Y_a\): number of mature individuals among \(N_a\) individuals
- \(p(a)\): maturity (probability) in age \(a\)
- \(Y_a \sim Bin(N_a, p(a))\)
set.seed <- 2018
Amin <- 1
Amax <- 10
AgeRange <- Age <- Amin:Amax
NAgeClass<- length(AgeRange)
# True beta0=-5, beta1=1
Nvec <- rep(10, NAgeClass)
pvec <- LogisticFn(AgeRange, -5, 1)
pvec
[1] 0.01798621 0.04742587 0.11920292 0.26894142 0.50000000 0.73105858
[7] 0.88079708 0.95257413 0.98201379 0.99330715
# Generation of simulation data
Yvec <- rbinom(NAgeClass, Nvec, pvec)
Yvec
[1] 0 0 1 1 4 6 8 9 10 10
Maturity.obs <- Yvec/Nvec
Maturity.obs
[1] 0.0 0.0 0.1 0.1 0.4 0.6 0.8 0.9 1.0 1.0
# Plotting the data
plot(Age, LogisticFn(Age,-5,1), type="l", ylab="Maturity")
points(Age, Maturity.obs, pch="*")
legend(6, 0.4, lty=1:0, pch=c("","*"), legend=c("True","Observed"), bty="n")
Res.glm.logit <- glm(cbind(Yvec,Nvec-Yvec)~Age, family=binomial)
Res.glm.logit
Call: glm(formula = cbind(Yvec, Nvec - Yvec) ~ Age, family = binomial)
Coefficients:
(Intercept) Age
-6.196 1.106
Degrees of Freedom: 9 Total (i.e. Null); 8 Residual
Null Deviance: 82.16
Residual Deviance: 2.005 AIC: 19.62
# Summary
summary(Res.glm.logit)
Call:
glm(formula = cbind(Yvec, Nvec - Yvec) ~ Age, family = binomial)
Deviance Residuals:
Min 1Q Median 3Q Max
-0.6076 -0.3936 -0.1285 0.3960 0.6784
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -6.1955 1.2441 -4.980 6.36e-07 ***
Age 1.1062 0.2141 5.166 2.40e-07 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 82.1559 on 9 degrees of freedom
Residual deviance: 2.0048 on 8 degrees of freedom
AIC: 19.621
Number of Fisher Scoring iterations: 5
# Parameter estimates
Res.glm.logit$coef
(Intercept) Age
-6.195516 1.106192
beta0.est <- Res.glm.logit$coef[1]
beta1.est <- Res.glm.logit$coef[2]
# CI of the paramters
confint(Res.glm.logit)
2.5 % 97.5 %
(Intercept) -9.0616959 -4.098096
Age 0.7465759 1.601501
# Visual presentation of results
plot(Age, LogisticFn(Age,-5,1), type="l", ylab="Maturity")
points(Age, Maturity.obs)
points(Age, LogisticFn(Age,beta0.est,beta1.est), type="l", col="red")
# Estimates
pred.se<-predict (Res.glm.logit, se.fit=TRUE) #Linear predictor
#Linear predictor's CI
Lower <- pred.se$fit - qnorm(0.975, 0, 1)* pred.se$se.fit
Upper <- pred.se$fit + qnorm(0.975, 0, 1)* pred.se$se.fit
#Logistic transformation of CI
logit.t<-function(x){ 1/(1+exp(-x)) }
pred.logit<- sapply(pred.se$fit, logit.t)
Lower.logit <- sapply(Lower, logit.t)
Upper.logit<- sapply(Upper, logit.t)
pcon.logit<-cbind(pred.logit, Lower.logit, Upper.logit)
plot(AgeRange, Maturity.obs, xlim=c(0,10), ylim=c(0,1))
matlines(AgeRange, pcon.logit, lty=c(1,2,2), col="blue", lwd=1.5)
As in the case of allometric function, we will conduct a regression analysis. However, we will analyze the data without any transformation using the “nonlinear regression model”.
A common and general formulation is as follows: \[ y_i = f(x_i, \theta) + \varepsilon_i, \quad \varepsilon_i \sim N(0,\sigma^2). \]
Here, we use a data set for alfonsino (in Japanese, “Kinmedai”). Like in the case of rainbow trouts, we shall read the data file.
Data <- read.csv("Data/Alfonsino.csv", header=T)
Age <- Data$Age
Length <- Data$Length
Sex <- as.numeric(Data$Sex) #"1" for female, "2" for male
mark <- c(19,2)
color <- c("red","blue")
plot(Length~Age,pch=mark[Sex],col=color[Sex],xlim=c(0,25),ylim=c(0,50))
legend(18,20,pch=mark,col=color,legend=c("Female","Male"),bty="n")
We will employ the famous von Bertalanffy growth function defined as \[ L_t = L_{\infty} (1-e^{-K (t-t_0)}). \]
# Definition of von Bertalanffy
growth.VB <- function(t,Linf,K,t0) Linf*(1.0-exp(-K*(t-t0)))
We then estimate the parameters \((L_{\infty}, K, t_0, \sigma)\) using “nls” function in R.
We now assume a same growth function between female and male fish. We call the model as “res000” (“0” means common and “1” does different).
# Setting a set of initial values for parameters (except for sigma)
start <- list(Linf=max(Length),K=0.1,t0=0)
# Estimation
res.000 <- nls(Length~growth.VB(t=Age,Linf, K, t0), start=start)
# Showing the estimation summary
summary(res.000)
Formula: Length ~ growth.VB(t = Age, Linf, K, t0)
Parameters:
Estimate Std. Error t value Pr(>|t|)
Linf 47.95842 2.91479 16.453 < 2e-16 ***
K 0.08936 0.02413 3.704 0.00027 ***
t0 -6.38637 2.14489 -2.977 0.00324 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 2.564 on 215 degrees of freedom
Number of iterations to convergence: 4
Achieved convergence tolerance: 5.63e-06
# Confidence interval for the growth paramters
confint(res.000)
2.5% 97.5%
Linf 44.10249477 58.3766050
K 0.04465578 0.1360594
t0 -12.34296242 -3.3029532
# Visual presentation
taxis <- seq(0,25,0.5); tlen <- length(taxis);
pred.000 <- predict(res.000, list(Age=taxis))
plot(Length~Age,xlim=c(0,25),ylim=c(0,50), main="Results under res.000 with prediction CI")
points(taxis, pred.000, type="l")
points(taxis, pred.000-1.96*sigma(res.000), type="l", lty=2)
points(taxis, pred.000+1.96*sigma(res.000), type="l", lty=2)
# Diagnostics
e <- residuals(res.000)/sigma(res.000)
plot(fitted(res.000), e, xlab="Fitted values", ylab="Standardized residuals")
abline(0,0); abline(-1.96,0,lty=2); abline(1.96,0,lty=2);
# Setting a set of initial values for female and male simultaneously
start <- list(Linf=rep(max(Length),2),K=c(0.1,0.1),t0=c(0,0))
# Estimation
res.111 <- nls(Length~growth.VB(t=Age,Linf[Sex], K[Sex], t0[Sex]), start=start)
# Showing the estimation summary
summary(res.111)
Formula: Length ~ growth.VB(t = Age, Linf[Sex], K[Sex], t0[Sex])
Parameters:
Estimate Std. Error t value Pr(>|t|)
Linf1 48.15050 4.52391 10.644 < 2e-16 ***
Linf2 47.70053 3.75965 12.687 < 2e-16 ***
K1 0.09797 0.04315 2.270 0.02418 *
K2 0.08646 0.02995 2.887 0.00429 **
t01 -5.12851 3.38334 -1.516 0.13106
t02 -6.94091 2.80413 -2.475 0.01410 *
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 2.567 on 212 degrees of freedom
Number of iterations to convergence: 4
Achieved convergence tolerance: 3.178e-06
# Confidence interval for the growth paramters
confint(res.111)
2.5% 97.5%
Linf1 43.09967561 81.7105984
Linf2 43.18112305 66.9658334
K1 0.02164258 0.1833475
K2 0.03031102 0.1453427
t01 -18.02360053 -0.9526554
t02 -16.13978541 -3.1310768
# Visual presentation
taxis <- seq(0,25,0.5); tlen <- length(taxis);
pred.female.111 <- predict(res.111, list(Age=taxis, Sex=rep(1,tlen)))
pred.male.111 <- predict(res.111, list(Age=taxis, Sex=rep(2,tlen)) )
plot(Length~Age,pch=mark[Sex],col=color[Sex],xlim=c(0,25),ylim=c(0,50),
main="Results under res.111 with prediction CI")
points(taxis, pred.female.111, type="l", col="red", lty=1)
points(taxis, pred.female.111-1.96*sigma(res.111), type="l", col="red", lty=2)
points(taxis, pred.female.111+1.96*sigma(res.111), type="l", col="red", lty=2)
points(taxis, pred.male.111, type="l", col="blue", lty=1)
points(taxis, pred.male.111-1.96*sigma(res.111), type="l", col="blue", lty=2)
points(taxis, pred.male.111+1.96*sigma(res.111), type="l", col="blue", lty=2)
legend(18,20,pch=mark,col=color,lty=c(1,2),legend=c("Female","Male"),bty="n")
# Diagnostics for female
e <- residuals(res.111)/sigma(res.111)
plot(fitted(res.111)[Sex==1], e[Sex==1], col="red",
xlab="Fitted values", ylab="Standardized residuals")
abline(0,0); abline(-1.96,0,lty=2); abline(1.96,0,lty=2);
# Diagnostics for male
plot(fitted(res.111)[Sex==2], e[Sex==2], col="blue",
xlab="Fitted values", ylab="Standardized residuals")
abline(0,0); abline(-1.96,0,lty=2); abline(1.96,0,lty=2);
We now try to compare which model is appropriate in terms of model fitting. Statistical hypothesis testing can be used for sequential, but the easiest way is to use AIC (Akaike Information Criterion), which is defined as \[ AIC = -2*max(loglikelihood) + 2*(Num \ of \ parameters). \] Smaller AIC values indicate better models. In R, a function “AIC” can be used to get the value.
# AIC values.
AIC(res.000)
[1] 1034.122
AIC(res.111)
[1] 1037.531
# Plot (not very different)
plot(Length~Age,pch=mark[Sex],col=color[Sex],xlim=c(0,25),ylim=c(0,50))
points(taxis, pred.000, type="l", lwd=2)
points(taxis, pred.female.111, type="l", col="red", lty=1)
points(taxis, pred.male.111, type="l", col="blue", lty=2)
Note 1: you can analyze the data with another assumption such as a case that only \(L_{\infty}\) is different between sex (as res.100) by modifying the code above.
Note 2: the code above assume a constant sigma across all the ages. In our example, the age coverage is limited, and the residuals show a similar level of variance over the ages. However, in case the date include broad range of ages, better approach is to assume heteroscedastic variance or taking logarithm of the length data.
Aims: including some extensions which I was not able to explain in September seminar
See “DeLury_Excel_rev.xlsx” if you wished to use MS-Excel.
Here is a very simple underlying formula.
\[ CPUE_t = q N_1 - q K_t \]
# Reading data
Data <- read.csv("Data/DeLury_R.csv")
Data
Period Catch Effort CPUE CumCatch CumEffort
1 1 60 170.6 0.352 0 0.0
2 2 274 453.8 0.604 60 170.6
3 3 240 513.4 0.467 334 624.4
4 4 244 714.4 0.342 574 1137.8
5 5 301 679.1 0.443 818 1852.2
6 6 151 419.9 0.360 1119 2531.3
7 7 127 470.3 0.270 1270 2951.2
8 8 90 318.4 0.283 1397 3421.5
9 9 31 136.8 0.227 1487 3739.9
10 10 7 177.6 0.039 1518 3876.7
CPUE <- Data$CPUE
CumCatch <- Data$CumCatch
CumEffort <- Data$CumEffort
plot(CumCatch, CPUE)
# De Lury method 1
Res.DeLury1 <- lm(CPUE~CumCatch)
summary(Res.DeLury1)
Call:
lm(formula = CPUE ~ CumCatch)
Residuals:
Min 1Q Median 3Q Max
-0.16798 -0.03658 0.01883 0.06804 0.10617
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 5.098e-01 6.013e-02 8.478 2.87e-05 ***
CumCatch -1.995e-04 5.883e-05 -3.391 0.00949 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.1034 on 8 degrees of freedom
Multiple R-squared: 0.5897, Adjusted R-squared: 0.5384
F-statistic: 11.5 on 1 and 8 DF, p-value: 0.00949
abline(Res.DeLury1, col="blue")
# Estimates by De Lury method 1
Para1 <- coef(Res.DeLury1); Para1
(Intercept) CumCatch
0.509796545 -0.000199483
q.est1 <- -Para1[2]
N.est1 <- Para1[1]/q.est1
data.frame(q.est1, N.est1)
q.est1 N.est1
CumCatch 0.000199483 2555.589
\[ \log(CPUE)_t = \log(q N_1) - q L_t - M(t-1) \]
By assuming \(M=0\), then
# De Lury method 2
Res.DeLury2 <- lm(log(CPUE)~CumEffort)
summary(Res.DeLury2)
Call:
lm(formula = log(CPUE) ~ CumEffort)
Residuals:
Min 1Q Median 3Q Max
-1.36018 -0.09308 0.18410 0.37092 0.46580
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.5562541 0.3303927 -1.684 0.1308
CumEffort -0.0003425 0.0001338 -2.560 0.0336 *
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.5946 on 8 degrees of freedom
Multiple R-squared: 0.4503, Adjusted R-squared: 0.3816
F-statistic: 6.553 on 1 and 8 DF, p-value: 0.03365
plot(CumEffort, log(CPUE))
abline(Res.DeLury2, col="blue")
# Estimates by De Lury method 2
Para2 <- coef(Res.DeLury2); Para2
(Intercept) CumEffort
-0.5562540837 -0.0003424973
q.est2 <- -Para2[2]
N.est2 <- exp(Para2[1])/q.est2
data.frame(q.est2, N.est2)
q.est2 N.est2
CumEffort 0.0003424973 1674.036
Assume that there are observation of CPUE for a total of five fishing areas over 20 years (very ideal!). In addition, there have been two fishing gears used ever.
Narea <- 5
Nyear <- 20
Ngear <- 2
Noperation <- 50 #number of fishing operations per year
Ref_mu <- 2
AreaEffect <- log(c(1,2,3,4,5))
YearEffect <- log(seq(1,2,length.out=Nyear))
GearEffect <- log(c(1,1.2))
AreaSelection <- rep(1,Nyear)
GearSelection <- seq(0.3, 0.7, length.out=Nyear)
Data <- as.matrix(array(NA, c(Nyear*Noperation, 4)))
colnames(Data) <- c("Catch", "Year", "Area", "Gear")
for(y in 1:Nyear){
for(i in 1:50){
Tmp_Area <- sample(1:Narea, 1)
Tmp_Gear <- sample(1:Ngear, 1, prob=c(GearSelection[y], 1-GearSelection[y]))
Tmp_mu <- Ref_mu*exp(YearEffect[y] + AreaEffect[Tmp_Area] + GearEffect[Tmp_Gear])
Tmp_Catch <- rpois(1,Tmp_mu)
Data[(y-1)*Noperation + i, ] <- c(Tmp_Catch, y, Tmp_Area, Tmp_Gear)
}
}
Data <- as.data.frame(Data)
# GLM analysis
Res1 <- glm(Catch~factor(Year), family="poisson", data=Data)
Res1
Call: glm(formula = Catch ~ factor(Year), family = "poisson", data = Data)
Coefficients:
(Intercept) factor(Year)2 factor(Year)3 factor(Year)4
1.7884 0.1689 0.2810 0.3540
factor(Year)5 factor(Year)6 factor(Year)7 factor(Year)8
0.3278 0.5122 0.4919 0.3726
factor(Year)9 factor(Year)10 factor(Year)11 factor(Year)12
0.4459 0.4858 0.4373 0.4960
factor(Year)13 factor(Year)14 factor(Year)15 factor(Year)16
0.3931 0.4816 0.7097 0.8290
factor(Year)17 factor(Year)18 factor(Year)19 factor(Year)20
0.6399 0.5930 0.8521 0.6780
Degrees of Freedom: 999 Total (i.e. Null); 980 Residual
Null Deviance: 3915
Residual Deviance: 3521 AIC: 7446
# Extraction of CPUE trend, which is the trend estimate of population abundance
plot(Ref_mu*exp(YearEffect), type="l")
points(exp(Res1$coefficients[1:20]))
The data we are using as an example is loaded as follows:
data(mack, package="gamair")
str(mack)
'data.frame': 634 obs. of 16 variables:
$ egg.count : num 0 0 0 1 4 3 0 1 0 0 ...
$ egg.dens : num 0 0 0 18.3 90.2 ...
$ b.depth : num 4342 4334 4286 1438 166 ...
$ lat : num 44.6 44.6 44.6 44 44 ...
$ lon : num -4.65 -4.48 -4.3 -2.87 -2.07 -2.13 -2.27 -2.35 -2.42 -2.48 ...
$ time : num 8.23 9.68 10.9 19.33 8.78 ...
$ salinity : num 35.7 35.7 35.7 35.7 NA ...
$ flow : num 417 405 377 420 354 373 375 364 375 362 ...
$ s.depth : num 104 98 101 98 101 100 100 102 100 100 ...
$ temp.surf : num 15 15.4 15.9 16.6 16.7 16.6 17.1 17.1 17.3 16.9 ...
$ temp.20m : num 15 15.4 15.9 16.6 16.7 16.6 17.1 17.1 17.3 16.9 ...
$ net.area : num 0.242 0.242 0.242 0.242 0.242 0.242 0.242 0.242 0.242 0.242 ...
$ country : Factor w/ 4 levels "EN","fr","IR",..: 4 4 4 4 4 4 4 4 4 4 ...
$ vessel : Factor w/ 4 levels "CIRO","COSA",..: 2 2 2 2 2 2 2 2 2 2 ...
$ vessel.haul: num 22 23 24 93 178 179 181 182 183 184 ...
$ c.dist : num 0.84 0.859 0.893 0.396 0.04 ...
loc <- cbind(mack$lon, mack$lat)
plot(loc, cex=2*mack$egg.count/max(mack$egg.count), xlab="Lon", ylab="Lat")
points(loc, pch=19, cex=0.3, col="red")
The assumption of modelling is like below (sorry for simple text…) but this is a conventional GAM with the spatial correlation and environmental covariates.
\[\begin{equation} Y_i \sim Pois(\lambda_i) \end{equation}\] \[\begin{equation} \log \lambda_i = log(net.area) + s(temp.20m) + s(lon, lat) \end{equation}\]Res.gam <- gam(egg.count ~ offset(net.area) -1 + s(temp.20m) + s(lon, lat),
family="poisson", data=mack)
summary(Res.gam)
Family: poisson
Link function: log
Formula:
egg.count ~ offset(net.area) - 1 + s(temp.20m) + s(lon, lat)
Approximate significance of smooth terms:
edf Ref.df Chi.sq p-value
s(temp.20m) 8.871 8.989 276 <2e-16 ***
s(lon,lat) 28.947 28.999 3154 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
R-sq.(adj) = 0.644 Deviance explained = 76.9%
UBRE = 5.833 Scale est. = 1 n = 634
zz <- Res.gam$fitted.values
plot(Res.gam)
quilt.plot(mack$lon, mack$lat, zz, xlab="Lon", ylab="Lat")
qmplot(lon, lat, zz, data=mack, zoom = 5)
ggplot(mack) +
geom_point(aes(x=lon,y=lat,alpha=0.2,size=zz,col=zz)) +
coord_quickmap()
Lon.range = c(-15, 0)
Lat.range = c(44, 60)
dat <- getNOAA.bathy(Lon.range[1],Lon.range[2],Lat.range[1],Lat.range[2],res=5)
autoplot(dat, geom=c("r", "c"), colour="white", size=0.1)+
scale_fill_etopo()+
labs(x="Longitude",y="Latitude",fill="Depth") + ggtitle("Map") +
geom_point(data=mack,aes(x=lon,y=lat,alpha=0.2,size=zz,col=zz))+
coord_quickmap()
# Create nice color palettes
blues <- c("lightsteelblue4", "lightsteelblue3",
"lightsteelblue2", "lightsteelblue1")
greys <- c(grey(0.6), grey(0.93), grey(0.99))
# Mapping
plot(dat, im=TRUE, land=TRUE, bpal=list(c(min(dat),0,blues),c(0,max(dat),greys)),
lwd=.05, las=1, xlim=c(-15,0))
map("worldHires", res=0, lwd=0.7, add=TRUE)
points(mack$lon, mack$lat, cex=zz/50, pch=19, col=rgb(1,0,0,0.2))
%
%
%
\[ B_{t+1} = B_t + rB_t \left\{1-\left(\frac{B_t}{K}\right)^z \right\} - C_t \]
Assume that the CPUE is proportional to the population biomass as follows: \[ CPUE = q B. \]
Here \(q\) is a proportional coefficient called “catchability coefficient”.
Let us assume the following time series model and try to estimate the parameters in the model. \[ \log CPUE_t = \log q + log B_t + \varepsilon_t, \quad \varepsilon_t \sim N(0, \sigma^2) \]
# Data for Indian Ocean albacore
Data <- read.csv("Data/Albacore.csv", header=T)
Year <- Data$Year
Catch <- Data$Catch
CPUE <- Data$CPUE
CV <- Data$CV
TT <- length(Year)
start.year <- min(Year)
final.year <- max(Year)
par(mai = c(1, 1.1, 1, 1.1))
plot(Year, Catch, type = "h", lwd=5, col="gray", ylab="Catch (tons)")
par(new =T)
plot(Year, CPUE, type="l", lwd=2, col="red", axes=FALSE, ylab="", ylim=c(0,2))
axis(4); mtext("CPUE", side=4, line=3)
PDM.PT<-function(r, K, z, B1, TT, Catch)
{
TT <- TT
B<-rep(NA,TT)
B[1]<-B1
for(t in 1:(TT-1))
{
tmp<-B[t]+r*B[t]*(1-(B[t]/K)^z)-Catch[t]
B[t+1]<-max(tmp,0.001)
}
B
}
NLL.PT <- function(par,z)
{
r<-exp(par[1])
K<-exp(par[2])
q<-exp(par[3])
sigma <-exp(par[4])
B<-PDM.PT(r, K, z, K, TT, Catch)
yobs <- log(CPUE)
mu <- log(q) + log(B)
pdf <- dnorm(yobs, mu, sigma, log=T)
loglike <- sum(pdf, na.rm=T)
negloglike <- -loglike
return(negloglike)
}
init.MSY <- 2*mean(Catch)
init.r <- 0.4
init.K <- 4*init.MSY/init.r
init<-log(c(init.r, init.K, 10^(-6), 1))
NLL.PT(init, z=1)
[1] 46.552
NLL.PT(2*init, z=1)
[1] 74.13025
res.SC<-optim(init, NLL.PT, z=1, method="BFGS", control=list(reltol=10^(-8)))
res <- res.SC; res
$par
[1] -0.9788076 12.7297969 -12.4127161 -1.4274852
$value
[1] -0.2648306
$counts
function gradient
172 51
$convergence
[1] 0
$message
NULL
r.est<-exp(res$par[1])
K.est<-exp(res$par[2])
q.est<-exp(res$par[3])
sigma.est<-exp(res$par[4])
MSY.est <- r.est*K.est/4
MSYL.est <- K.est/2
data.frame(r.est, K.est, q.est, sigma.est)
r.est K.est q.est sigma.est
1 0.3757589 337660.7 4.066548e-06 0.2399115
Predicted <- PDM.PT(r.est, K.est, z=1, K.est, TT, Catch)
# Fittness
par(mfrow=c(2,2))
plot(log(CPUE), log(q.est*Predicted), xlim=c(-1,1), ylim=c(-1,1)); abline(0,1)
# Time series plots for CPUE observation and its prediction by the model
plot(Year, CPUE, ylim=c(0, max(CPUE, na.rm=T)) )
points(Year, q.est*Predicted, type="l")
# Times series of estimated biomass
plot(Year, Predicted, type="l", ylim=c(0, 1.1*K.est), xaxs="i",yaxs="i")
# Times series of depletion level against the carrying capacity (B/K)
plot(Year, Predicted/K.est, type="l", ylim=c(0,1), xaxs="i",yaxs="i", ylab="Depletion")
rect(xleft=-1, ybottom=0, xright=2010, ytop=0.4, lwd=0, col=rgb(1,0,0,0.3))
rect(xleft=-1, ybottom=0.4, xright=2010, ytop=0.6, lwd=0, col=rgb(1,1,0,0.3))
rect(xleft=-1, ybottom=0.6, xright=2010, ytop=1, lwd=0, col=rgb(0,1,0, 0.3))
# Definition of B-ratio and F-ratio
Bratio <- Predicted/MSYL.est
Fratio <- Catch/(MSY.est) #actually Hratio
plot(Bratio,Fratio,type="n",xlim=c(0,2),ylim=c(0,2),
xlab="B/Bmsy",ylab="F/Fmsy", main="Kobe plot")
rect(xleft=0,ybottom=0,xright=1,ytop=1,lwd=0,col="#FEFF63FF")
rect(xleft=0,ybottom=1,xright=1,ytop=2,lwd=0,col="#FF4949FF")
rect(xleft=1,ybottom=1,xright=2,ytop=2,lwd=0,col="#FFBE7DFF")
rect(xleft=1,ybottom=0,xright=2,ytop=1,lwd=0,col="#85FF68FF")
points(Bratio,Fratio,type="l",lwd=1.8)
points(Bratio[1:(T-1)],Fratio[1:(T-1)],lwd=1,cex=3,pch=21,bg="skyblue")
points(Bratio[T],Fratio[T],lwd=1,cex=3,pch=21,bg="blue")
num <- c(seq((start.year-1900),99,1),seq(0,(final.year-2000),1))
text(Bratio,Fratio,labels=num,adj=0.5,cex=1, col="white")
Please download rjags_4-3.zip from
http://sourceforge.net/projects/mcmc-jags/files/rjags/4/
And, in R session
#install.packages("rjags")
#library(rjags)
#
#install.packages("runjags")
#library(runjags)
#install.packages("jagsUI")
library(jagsUI)
Data <- read.csv("Example_BSPM/ALB_DB_5016.csv", header=T)
Year <- Data$Year
Catch <- Data$Catch
CPUE.R3 <- Data$CPUE_R3
CPUE.R4 <- Data$CPUE_R4
TT <- length(Year)
par(mai = c(1, 1.1, 1, 1.1))
plot(Year, Catch, type = "h", lwd=5, col="gray", ylab="Catch (tons)")
par(new =T)
plot(Year, CPUE.R3, type="l", lwd=2, col="red", axes=FALSE, ylab="", ylim=c(0,2))
points(Year, CPUE.R4, type="l", lwd=2, col="blue")
axis(4); mtext("CPUE", side=4, line=3)
start.year <- Year[1]
final.year <- Year[TT]
Year.est <- start.year:(final.year+1)
CPUE.R3.ind<-which(!is.na(CPUE.R3))
CPUE.R3_rem <- CPUE.R3[CPUE.R3.ind]
CPUE.R4.ind<-which(!is.na(CPUE.R4))
CPUE.R4_rem <- CPUE.R4[CPUE.R4.ind]
N <- length(Year.est)
N.R3 <- length(CPUE.R3_rem)
N.R4 <- length(CPUE.R4_rem)
#Data
JAGS.data <- list(N1=N.R3,N2=N.R4,N=N,Catch=Catch,CPUE.1=CPUE.R3_rem,CPUE.2=CPUE.R4_rem,Period_CPUE.1=CPUE.R3.ind,Period_CPUE.2=CPUE.R4.ind,Dep=1)
#Parameters
Params<-c("B","D","F","Fratio","Bratio","CPUE.1.est","CPUE.2.est","r","K","MSY","BMSY","FMSY","inv.sigma2_CPUE.1","inv.sigma2_CPUE.2","inv.tau2","q_CPUE.1","q_CPUE.2","sigma_CPUE.1","sigma_CPUE.2","tau")
sink("Example_BSPM/BSPM.txt")
cat("
model{
##observation-process
##CPUE.1
for(i in 1:N1){
CPUE.1[i] ~ dlnorm(L_CPUE.1.est[i],inv.sigma2_CPUE.1)
L_CPUE.1.est[i] <- log(CPUE.1.est[i])
CPUE.1.est[i] <- q_CPUE.1*D[Period_CPUE.1[i]]*K
}
##CPUE.2
for(i in 1:N2){
CPUE.2[i] ~ dlnorm(L_CPUE.2.est[i],inv.sigma2_CPUE.2)
L_CPUE.2.est[i] <- log(CPUE.2.est[i])
CPUE.2.est[i] <- q_CPUE.2*D[Period_CPUE.2[i]]*K
}
##state-process(1950-2016)
for(i in 2:N){
D[i] ~ dlnorm(Dtmp[i],inv.tau2)
tmp[i] <- D[i-1]+r*D[i-1]*beta[i-1]-Catch[i-1]/K
beta[i-1] <- 1-D[i-1]
Dtmp[i] <- log(max(tmp[i],0.001))
}
##B(1950-2016)
for(i in 1:N){
B[i] <- K*D[i]
Bratio[i] <- B[i]/BMSY
}
##F(1950-2015)
for(i in 1:(N-1)){
F[i] <- Catch[i]/B[i]
Fratio[i] <- F[i]/FMSY
}
##projection of CPUE.1
for(i in 1:N1){
CPUE.1.pred[i] ~ dlnorm(L_CPUE.1.est[i],inv.sigma2_CPUE.1)
}
##projection of CPUE.2
for(i in 1:N2){
CPUE.2.pred[i] ~ dlnorm(L_CPUE.2.est[i],inv.sigma2_CPUE.2)
}
##prior
r~dunif(0,3)
K~dunif(0,10000000)
D[1] ~ dlnorm(L_Dep,inv.tau2)
L_Dep <- 0
q_CPUE.1~dunif(0,0.01)
q_CPUE.2~dunif(0,0.01)
inv.sigma2_CPUE.1 <- 1/(sigma_CPUE.1*sigma_CPUE.1)
sigma_CPUE.1 ~dunif(0,2)
inv.sigma2_CPUE.2 <- 1/(sigma_CPUE.2*sigma_CPUE.2)
sigma_CPUE.2 ~dunif(0,2)
inv.tau2 <- 1/(tau*tau)
tau ~dunif(0,2)
MSY <- (r*K)/4
BMSY <- K/2
FMSY <- MSY/BMSY
}
", fill=TRUE)
sink()
# Set WD
setwd(NewDir)
# MCMC option
n.chains <- 3
n.burnin <- 50000
n.thin <- 100
n.iter <- 350000
# Definition of model run
res <- jags(data=JAGS.data, model.file="BSPM.txt",
parameters.to.save=Params, n.chains=n.chains,
n.burnin=n.burnin, n.thin=n.thin, n.iter=n.iter)
saveRDS(res, file = "res.obj")
#res <- readRDS("Example_BSPM/res.obj")
B.med <- res$q50$B
B.LB <- res$q2.5$B
B.UB <- res$q97.5$B
K.med <- res$q50$K
BMSY.med <- res$q50$BMSY
D.med <- res$q50$D
D.LB <- res$q2.5$D
D.UB <- res$q97.5$D
plot(Year.est, B.med, type="l", ylim=c(0, 1.2*K.est),
xaxs="i",yaxs="i", ylab="Biomass (tons)")
points(Year.est, B.LB, type="l", lty=2)
points(Year.est, B.UB, type="l", lty=2)
abline(K.med,0)
abline(BMSY.med,0)
RED<-rgb(1, 0, 0, alpha=0.2)
YEL<-rgb(1, 1, 0, alpha=0.2)
GRE<-rgb(0, 1, 0, alpha=0.2)
plot(Year.est, D.med, type="l", ylim=c(0,1.2),
xaxs="i",yaxs="i", ylab="Depletion")
rect(xleft=-1, ybottom=0, xright=2020, ytop=0.4, lwd=0, col=RED)
rect(xleft=-1, ybottom=0.4, xright=2020, ytop=0.6, lwd=0, col=YEL)
rect(xleft=-1, ybottom=0.6, xright=2020, ytop=2, lwd=0, col=GRE)
points(Year.est, D.LB, type="l", lty=2)
points(Year.est, D.UB, type="l", lty=2)
abline(1,0)
#we need these packages
library(reshape)
library(MASS)
Kobe_CI <- function(start.year,final.year,Bratio,Fratio,rec.Bratio,rec.Fratio,plot_ylim){
T <- (final.year-start.year)+1
Year <- start.year:final.year
xy <- data.frame(x=rec.Bratio,y=rec.Fratio)
xy <- subset(xy,xy$y<=plot_ylim)
xx <- xy$x
yy <- xy$y
d <- kde2d(xx,yy,c(bandwidth.nrd(xx),bandwidth.nrd(yy)),n=100)
tes<-function(x,y)(sum(d$z[d$z>x])*(max(d$x)-min(d$x))/100*(max(d$y)-min(d$y))/100)/(sum(d$z)*(max(d$x)-min(d$x))/100*(max(d$y)-min(d$y))/100)-y
d2<-d
H<-seq(0.01,1,0.01)
H<-rev(H)
for(i in 1:99){
h1<-uniroot(tes,range(d),H[i])$root
d2$z[h1<d$z]<-H[i]
}
h1<-uniroot(tes,range(d),H[100])$root
d2$z[h1<d$z]<-H[100]
par(cex.axis=1,cex.lab=1)
par(mar=c(4,4,1,1))
plot(Bratio,Fratio,type="n",xlim=c(0,plot_ylim),ylim=c(0,plot_ylim),xlab="B/Bmsy",ylab="F/Fmsy",bty="n")
rect(xleft=0,ybottom=0,xright=1,ytop=1,lwd=0,col="#FEFF63FF")
rect(xleft=0,ybottom=1,xright=1,ytop=plot_ylim,lwd=0,col="#FF4949FF")
rect(xleft=1,ybottom=1,xright=plot_ylim,ytop=plot_ylim,lwd=0,col="#FFBE7DFF")
rect(xleft=1,ybottom=0,xright=plot_ylim,ytop=1,lwd=0,col="#85FF68FF")
.filled.contour(d2$x,d2$y,d2$z,col=rgb(0.9, 0.9, 0.9, alpha=0.8),levels=c(0,0.8))
contour(d2,levels=0.8,add=T,lty=0,drawlabels=F)
points(Bratio,Fratio,type="l",lwd=1.8)
points(Bratio[1:10],Fratio[1:10],lwd=1,cex=1.5,col="black",pch=21,bg="slateblue")
points(Bratio[11:20],Fratio[11:20],lwd=1,cex=1.5,col="black",pch=21,bg="cadetblue")
points(Bratio[21:30],Fratio[21:30],lwd=1,cex=1.5,col="black",pch=21,bg="deepskyblue")
points(Bratio[31:(T-1)],Fratio[31:(T-1)],lwd=1,cex=1.5,col="black",pch=21,bg="lightblue1")
points(Bratio[T],Fratio[T],lwd=1,cex=1.5,col="black",pch=21,bg="white")
num <- c(seq((start.year-1900),99,1),seq(0,(final.year-2000),1))
text(Bratio,Fratio,labels=num,adj=0.5,cex=0.5)
legend(plot_ylim,plot_ylim-1.2,paste(c("80%CI")),pt.bg=rgb(0.9, 0.9, 0.9, alpha=0.8),bty="n",cex=0.8,pch=22,pt.cex=2,xjust=1,yjust=1)
#par(mar=c(6,6,0,0))
par(new=T,fig=c(0.3,0.9,0.45,0.95))
ratio.d <- data.frame(x=rec.Bratio,y=rec.Fratio)
ratio.red <- subset(ratio.d, 0<=x & x<=1 & 1<=y)
ratio.ora <- subset(ratio.d,1<=x & 1<=y)
ratio.yel <- subset(ratio.d,0<=x & x<=1 & 0<=y & y<=1)
ratio.gre <- subset(ratio.d,1<=x & 0<=y & y<=1)
pie(c(length(ratio.gre$x)/length(ratio.d$x),length(ratio.ora$x)/length(ratio.d$x),length(ratio.red$x)/length(ratio.d$x),length(ratio.yel$x)/length(ratio.d$x)),labels=round(c(length(ratio.gre$x)/length(ratio.d$x),length(ratio.ora$x)/length(ratio.d$x),length(ratio.red$x)/length(ratio.d$x),length(ratio.yel$x)/length(ratio.d$x)),3),radius=0.9,cex=0.7,col=c("#85FF68FF","#FFBE7DFF","#FF4949FF","#FEFF63FF"),cex.lab=0.8)
}
Kobe_CI(1950,2016,res$q50$Bratio[-N],res$q50$Fratio,res$sims.list$Bratio[,(N-1)],res$sims.list$Fratio[,(N-1)],3)
(to come later)
setwd(CurrentDir)
For working “age-structured model”, mostly you have to combine multiple sources of information such as CPUE series and age- or length-composition of catch as well as the total catch. There have been several candidate methods with developed software. Stock Synthesis 3 (SS3) is one of them. I have been involved in some tuna RFMO, and the SS3 is one of most common platforms, especially in IOTC.
For formal use of SS3, you need to register USA’s NOAA site to download necessary “exe” file etc. And the set-up and preparation of data are not straightforward for use of your own data, and I don’t think all of the participants are using such an advanced method. Therefore, I will briefly demonstrate how to run. That being said, I will leave a memo for installation and test runs. Please feel free to ask me more.
For downloading SS3, please visit the following website and register for “Stock Synthesis version 3.0”.
Previously “r4ss” was on CRAN to download, but it has not been renewed currently. So we shall install it from a GitHub site using a package “devtools”. After installation, you can call the library.
install.packages("devtools")
devtools::install_github("r4ss/r4ss", force = TRUE, build_vignettes = TRUE)
library(r4ss)
#browseVignettes("r4ss")
Unless you see “error” messages, no problems (you don’t need to worry about “warning”). See https://github.com/r4ss/r4ss more details.
At first, we will start demonstration to see what results are available by executing SS3. We shall use a set of example files stored in r4ss package.
To see the syntax, you call call the help files as follows:
?SS_output
?SS_plots
The files necessary to run SS3 are as follows:
While you can give any names for the “data” and “control” files, please use “Starter” and “Forecast” files as they are. When you open “starter.ss” file,
Filename.dat
Filename.ctl
are described at the first two effective lines.
Now, follow the next a couple of steps:
As you can see the first line, there is a warning message “Some stats skipped because the .par file not found”. The SS3 code is written by ADMB, and usually once an ADMB code is compiled and then executed, several important files are created:
Hope you succeed in computation. Then use “r4ss” to draw outputs. Sorry for letting you the same thing twice, but the current way is the usual SS3 procedure.
#Run "ss_opt.exe"
path <- getwd()
mywd <- file.path(path, "/Example_SS3/Simple") ## for you!
replist <- SS_output(dir=mywd)
SS_plots(replist, png=T, pdf=F) #default plot
Just in case, if you prefer “pdf” to “html” as an output format, run as follows:
SS_plots(replist, png=F, pdf=T)
%
%
I will distribute a set of files for this shiny demonstration on site.
# Define UI for application that draws a histogram
ui <- fluidPage(
## Title line
titlePanel("Example of Management Strategy Evaluation"),
## First line
fluidRow(
column(6, wellPanel(
textInput("Objectives", h4("What is your management objective?"),
value="Enter your objectives"),
numericInput(inputId = "Objective1", label = "Prob(B > Bmsy) = ",
value = 0.5, step=0.1, min=0, max=1)
)),
column(6, wellPanel(
numericInput(inputId = "Nyear", label = "Management Period:",
value = 10, step=1, width = "50%"),
numericInput(inputId = "Nsim", label = "Number of simulation replicas:",
value = 500, max=1000, step=100, width = "50%")
))
),
## Second line
fluidRow(
column(3, wellPanel(
h4("Configulation of Operating Models"),
numericInput(inputId = "Dinitial", label = "Initial Depletion (D0):",
value = 0.4, step=0.05, min=0.1, max=0.9),
numericInput(inputId = "r", label = "Intrinsic Rate of Increase (r):",
value = 0.1, step=0.01, min=0.01, max=0.5),
numericInput(inputId = "K", label = "Carrying Capacity (K):",
value = 10000, step=1000),
numericInput(inputId = "z", label = "Shape Parameter (z):",
value = 1, step=0.1, min=0.1, max=3),
numericInput(inputId = "EstCV", label = "Precision of Abun Estimate (CV):",
value = 0.1, step=0.05, min=0, max=0.5),
numericInput(inputId = "ProCV", label = "Extent of Process Error (tau):",
value = 0.05, step=0.01, min=0, max=0.2)
)),
column(3, wellPanel(
h4("Setting your Management Procedure"),
numericInput(inputId = "LRP", label = "Limit Reference Point:",
value = 0.1, step=0.05, min=0, max=0.5),
numericInput(inputId = "TRP", label = "Target Reference Point:",
value = 0.4, step=0.05),
numericInput(inputId = "MaxChange", label="Max Allowable Change in catch (%):",
value = 30, step=5),
selectInput(inputId = "Assessment",
label = "Do assessment? (this does not work yet):",
choices = list("Yes, parameters are updated"=1,
"No, assessment is not conducted"=2), selected=1),
submitButton("Run"),
downloadButton("report", "Download PDF")
)),
column(6, wellPanel(
h4("Simulation results"),
tabsetPanel(
tabPanel("Performance Mesures",tableOutput("Performance")),
tabPanel("Your Harvest Control Rule", plotOutput("HCR")),
tabPanel("Kobe Matrix", tableOutput("Kobe2"))
)
))
),
## Third line
fluidRow(
column(4,wellPanel(
plotOutput("Trajectories_B")
)),
column(4,wellPanel(
plotOutput("Trajectories_F")
)),
column(4,wellPanel(
plotOutput("Kobe1")
))
)
)
# Define server logic required to draw a histogram
server <- function(input, output){
Simulation <- reactive({
#Model-based
HCR <- function(Bcurrent, Dep, rest, Kest, zest, LRP, TRP)
{
Fmsy <- rest*(1/(1+zest))^(1/zest)
if(TRP > LRP){
if(Dep <= LRP) Quota <- 0
if(Dep > LRP & Dep < TRP) Quota <- (Fmsy/(TRP-LRP))*(Dep-LRP)*Bcurrent
if(Dep >= TRP) Quota <- Fmsy*Bcurrent
}
if(TRP-LRP==0){
if(Dep <= LRP) Quota <- 0
if(Dep >= LRP) Quota <- Fmsy*Bcurrent
}
return(Quota)
}
#Pella-Tomlinson Production model (incl. Shaefer model)
PDM.PT <- function(r, K, z, Dinitial, ProCV, Nyear)
{
Pmsy <- K*(1/(1+z))^(1/z)
Fmsy <<- r*(z/(1+z))
P <- numeric()
Catch <- numeric()
Bratio <- numeric()
Fratio <- numeric()
ProError <- rnorm(Nyear,0,ProCV)
P[1] <- K*Dinitial
for(t in 1:Nyear)
{
Pest <- P[t]*exp(rnorm(1,0,EstCV))
Catch[t] <- HCR(Pest, Pest/K, r, K, z, LRP, TRP)
if(t>=2){
if(Catch[t-1]>0) change <- (Catch[t] - Catch[t-1])/Catch[t-1]
if(Catch[t-1]==0) change <- 0
if(change > MaxChange/100) Catch[t] <- (1+MaxChange/100)*Catch[t-1]
if(change < -MaxChange/100) Catch[t] <- (1-MaxChange/100)*Catch[t-1]
}
tmp <- P[t] + r*P[t]*(1-(P[t]/K)^z) - Catch[t]
P[t+1] <- max(tmp*exp(ProError[t]),1)
}
Out <- NULL
Out$P <- P
Out$Bratio <- P/Pmsy
Out$Fratio <- Catch/(Fmsy*Pmsy)
Out$Catch <- Catch
return(Out)
}
Nyear <<- input$Nyear
Dinitial <<- input$Dinitial
r <<- input$r
K <<- input$K
z <<- input$z
ProCV <<- input$ProCV
EstCV <<- input$EstCV
LRP <<- input$LRP
TRP <<- input$TRP
MaxChange <<- input$MaxChange
Nsim <<- input$Nsim
P.mat <- array(0,c(Nsim, Nyear+1))
Bratio.mat <- array(0,c(Nsim, Nyear+1))
Catch.mat <- array(0,c(Nsim, Nyear))
Fratio.mat <- array(0,c(Nsim, Nyear))
for(i in 1:Nsim){
Res <- PDM.PT(r,K,z,Dinitial,ProCV,Nyear)
P.mat[i,] <- Res$P
Bratio.mat[i,] <- Res$Bratio
Fratio.mat[i,] <- Res$Fratio
Catch.mat[i,] <- Res$Catch
}
SimRes<-NULL
SimRes$P.mat <- P.mat
SimRes$Bratio.mat <- Bratio.mat
SimRes$Catch.mat <- Catch.mat
SimRes$Fratio.mat <- Fratio.mat
SimRes$P.med <- apply(P.mat,2,median)
SimRes$Bratio.med <- apply(Bratio.mat,2,median)
SimRes$Fratio.med <- apply(Fratio.mat,2,median)
return(SimRes)
})
output$Trajectories_B <- renderPlot({
SimRes <- Simulation()
par(mfrow=c(3,1), mar=c(2,2,2,2))
plot(0,0, main="Population size", xlim=c(0,Nyear),
ylim=c(0,K*1.1), xaxs="i", yaxs="i")
for(i in 1:Nsim) points(0:Nyear, SimRes$P.mat[i,], type="l", col="lightgray")
abline(K,0,lty=2)
points(0:Nyear, SimRes$P.med, type="l", col="blue", lwd=2)
plot(0,0, main="Depletion level", xlim=c(0,Nyear),
ylim=c(0,1.1), xaxs="i", yaxs="i")
for(i in 1:Nsim) points(0:Nyear, SimRes$P.mat[i,]/K, type="l", col="lightgray")
points(0:Nyear, SimRes$P.med/K, type="l", col="blue", lwd=2)
rect(-100,0,100,LRP, col=rgb(1, 0, 0, alpha=0.2))
rect(-100,LRP,100,TRP, col=rgb(1, 1, 0, alpha=0.2))
rect(-100,TRP,100,10, col=rgb(0, 1, 0, alpha=0.2))
plot(0,0, main="B-ratio", xlim=c(0,Nyear),
ylim=c(0,max(c(max(SimRes$Bratio.mat)*1.1,2))), xaxs="i", yaxs="i")
for(i in 1:Nsim) points(0:Nyear, SimRes$Bratio.mat[i,],
type="l", col="lightgray")
points(0:Nyear, SimRes$Bratio.med, type="l", col="blue", lwd=2)
rect(-100,0,100,1, col=rgb(1, 0, 0, alpha=0.2))
rect(-100,1,100,100, col=rgb(0, 1, 0, alpha=0.2))
})
output$Trajectories_F <- renderPlot({
SimRes <- Simulation()
par(mfrow=c(3,1), mar=c(2,2,2,2))
plot(0,0,main="Catch", xlim=c(0,Nyear), ylim=c(0,max(SimRes$Catch)*1.1),
xaxs="i", yaxs="i")
for(i in 1:Nsim) points(1:Nyear, SimRes$Catch[i,], type="l", col="lightgray")
Catch.med <- apply(SimRes$Catch.mat,2,median)
points(1:Nyear, Catch.med, type="l", col="blue", lwd=2)
plot(0,0,main="Change in catch (%)", xlim=c(0,Nyear), ylim=c(-100,100),
xaxs="i", yaxs="i")
for(i in 1:Nsim){
points(1:(Nyear-1),
100*(SimRes$Catch[i,-1]-SimRes$Catch[i,-Nyear])/SimRes$Catch[i,-Nyear],
type="l", col="lightgray")
abline(MaxChange, 0, lty=2, col="blue")
abline(0, 0, lty=2, col="gray")
abline(-MaxChange, 0, lty=2, col="blue")
plot(0,0,main="F-ratio", xlim=c(0,Nyear),
ylim=c(0,max(c(max(SimRes$Fratio.mat)*1.1, 2))), xaxs="i", yaxs="i")
for(i in 1:Nsim){
points(1:Nyear, SimRes$Fratio.mat[i,], type="l", col="lightgray")}
points(1:Nyear, SimRes$Fratio.med, type="l", col="blue", lwd=2)
rect(-100,0,100,1, col=rgb(0, 1, 0, alpha=0.2))
rect(-100,1,100,100, col=rgb(1, 0, 0, alpha=0.2))
})
output$Kobe1 <- renderPlot({
SimRes <- Simulation()
par(mfrow=c(1,1), xaxs="i", yaxs="i")
Bratio.med <- SimRes$Bratio.med[-(Nyear+1)]
Fratio.med <- SimRes$Fratio.med
xmax<-max(Bratio.med*1.05,2)
ymax<-max(Fratio.med*1.05,2)
plot(Bratio.med, Fratio.med, xlab="B-ratio",
ylab="F-ratio",xlim=c(0,xmax),ylim=c(0,ymax),col="red")
rect(0,1,1,ymax,col="lightsalmon")
rect(0,0,1,1,col="lightyellow")
rect(1,1,xmax,ymax,col="lightyellow")
rect(1,0,xmax,1,col="lightgreen")
points(SimRes$Bratio.mat[,Nyear],SimRes$Fratio.mat[,Nyear],
pch=19, cex=0.5, col="gray")
lines(Bratio.med,Fratio.med,type="o")
})
output$Performance <- renderTable({
SimRes <- Simulation()
Catch.med <- apply(SimRes$Catch.mat,2,median)
judge <- function(x) mean(x>1)
Prob1 <- apply(SimRes$Bratio.mat[,-1], 2, judge)
Prob2 <- apply(SimRes$Fratio.mat, 2, judge)
tmp<- data.frame(Year=1:Nyear, B.med=SimRes$P.med[-1],
Catch.med=Catch.med, Bratio.med=SimRes$Bratio.med[-1],
Fratio.med=SimRes$Fratio.med,
"Prob B greater than Bmsy="= Prob1,
"Prob F smaller than Fmsy" = 1-Prob2)
return(tmp)
})
output$HCR <- renderPlot({
SimRes <- Simulation()
plot(0,0,type="n",xlim=c(0,1), ylim=c(0,Fmsy*1.5),
xlab="Depeletion level", ylab="Fishing Intensity")
lines(c(0,LRP),c(0,0),lwd=2)
lines(c(LRP,TRP),c(0,Fmsy),lwd=2)
lines(c(TRP,1),c(Fmsy,Fmsy),lwd=2)
lines(c(TRP,TRP),c(0,Fmsy),lty=2)
lines(c(0,TRP),c(Fmsy,Fmsy),lty=2)
})
output$report <- downloadHandler(
filename = function(){
paste("MSE",format(Sys.time(), "%d-%b-%Y %H.%M"), ".pdf", sep=".")
},
content = function(file){
pdf(file)
hist(rnorm(10000,0,1), main="Temp")
dev.off()
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
%
The main package is “fishmethods”, we shall call another useful package specific to fishery stock assessment such as “FSA (http://derekogle.com/fishR/packages)” to use some convenient functions in it.
#"fishmethods"
#install.packages("fishmethods")
library(fishmethods)
#additional (https://www.rdocumentation.org/packages/FSA/versions/0.8.22)
#install.packages("FSA")
library(FSA)
#data(package="fishmethods", verbose=F)
Need population dynamics models to calculate biomass trajectory with CI.
PDM.SC <- function(par,Catch)
{
Nyear <- length(Catch)+1
r <- par[1]
K <- par[2]
Dinitial <- par[3]
P <- numeric(Nyear)
P[1] <- K*Dinitial
for(t in 2:Nyear)
{
tmp <- P[t-1] + r*P[t-1]*(1-P[t-1]/K) - Catch[t-1]
P[t] <- max(tmp,1)
}
#Out <- NULL
#Out$Biomass <- P
#Out$bbmsy <- P/(K/2)
Out <- P
return(Out)
}
#Another package "datalimited" (https://rdrr.io/github/datalimited/datalimited/)
#Note: need installation of JAGS ()
#install.packages("devtools")
#devtools::install_github("datalimited/datalimited")
library("datalimited")
Lingcod catch data from literature sources in Martell and Froese (2012).
CurrentDir <- getwd()
NewDir <- paste(CurrentDir, "/DataLimit/lingcod", sep="")
#dir.create(NewDir)
setwd(NewDir)
data(lingcod)
headtail(lingcod, 5)
year catch
1 1889 150.0
2 1890 100.0
3 1891 150.0
4 1892 300.0
5 1893 170.0
109 1997 57.2
110 1998 67.7
111 1999 71.2
112 2000 46.3
113 2001 46.3
summary(lingcod$catch)
Min. 1st Qu. Median Mean 3rd Qu. Max.
24.8 310.5 853.1 1155.0 1588.4 4339.0
set.seed(2019)
nsims <- 1000 #change into 10000 in actual computation
par(mfrow=c(4,3), mar=c(4,4,2,2))
outpt <- outpt.lingcod <-catchmsy(
year=lingcod$year,
catch=lingcod$catch,
catchCV=NULL,
catargs=list(dist="none",low=0,up=Inf,unit="MT"),
l0=list(low=0.8,up=0.8,step=0),
lt=list(low=0.01,up=0.25,refyr=2002),sigv=0,
k=list(dist="unif",low=4333,up=433300,mean=0,sd=0),
r=list(dist="unif",low=0.015,up=0.1,mean=0,sd=0),
M=list(dist="unif",low=0.18,up=0.18,mean=0.00,sd=0.00),
nsims=nsims,
graphs=1:11)
print(outpt$Initial)
Distr Lower Upper Mean SD
l0 increment 0.8 0.8 <NA> <NA>
k unif 4333 433300 0 0
r unif 0.015 0.1 0 0
M unif 0.18 0.18 0 0
lt <NA> 0.01 0.25 <NA> <NA>
refyr <NA> 2002 <NA> <NA> <NA>
print(outpt$Parameters)
Mean (ll=1) Median (ll=1) 2.5% (ll=1) 97.5% (ll=1)
k 127275.678 130452.4557 105084.4662 142118.2377
r 0.021 0.0181 0.0156 0.0315
M 0.180 0.1800 0.1800 0.1800
print(outpt$Estimates)
Mean Median 2.5% 97.5%
MSY 654.224 619.5212 549.6240 844.3805
BMSY 63637.839 65226.2278 52542.2331 71059.1188
FMSY 0.011 0.0091 0.0078 0.0157
Umsy 0.010 0.0083 0.0071 0.0143
OFL 189.364 195.8207 26.2610 291.1411
cmsy(yr, ct, interyr_index = 2L, interbio = c(0, 1), bio_step = 0.05, start_r = resilience(NA), start_k = c(max(ct), 50 * max(ct)), startbio = if (ct[1]/max(ct) < 0.2) c(0.5, 0.9) else c(0.2, 0.6), sig_r = 0.05, reps = 1e+05, revise_bounds = TRUE, finalbio = if (ct[length(ct)]/max(ct) > 0.5) c(0.3, 0.7) else c(0.01, 0.4))
set.seed(2019)
x <- x.lingcod <- cmsy(
yr=lingcod$year,
ct=lingcod$catch,
start_r = c(0.015,0.1),
start_k = c(max(lingcod$catch), 100*max(lingcod$catch)),
reps=1e4)
par(mfrow = c(2, 2))
plot(lingcod$year, lingcod$catch, type="o", xlab="Year", ylab="Catch (t)")
plot(lingcod$year, apply(x$biomass, 2, median)[-1], type="o", ylab="Estimated biomass", xlab="Year")
hist(x$bmsy)
plot(x$theta$r, x$theta$k, col = "#00000030")
“likeli”
“l0”
“k”
“r”
“M”
“MSY”
“Bmsy”
“Fmsy” “Umsy” “OFL”
“Btk”
par(mfrow=c(2,2))
#### catchmsy
Y1 <- c(lingcod$year, tail(lingcod$year,1)+1)
Accepted <- (outpt$Values$like==1)
Est.accepted <- as.matrix(outpt$Values[Accepted,c(4,3,2)])
Bio.accepted <- apply(Est.accepted, 1, PDM.SC, Catch=lingcod$catch)
Bio_qunantile <- apply(Bio.accepted, 1, quantile, prob=c(0.025, 0.25, 0.5, 0.75, 0.975))
Bio_qunantile <- data.frame(Year=Y1, Bio=t(Bio_qunantile))
colnames(Bio_qunantile) <-
c("Year", "Bio_q2.5", "Bio_q25", "Bio_q50", "Bio_q75", "Bio_q97.5")
#headtail(Bio_qunantile, 5)
Bmsy.accepted <- matrix(rep(Est.accepted[,2]/2, length(Y1)), byrow=T, nrow=length(Y1))
bbmsy.accepted <- apply(Est.accepted, 1, PDM.SC, Catch=lingcod$catch)/Bmsy.accepted
bbmsy_qunantile <- apply(bbmsy.accepted, 1, quantile, prob=c(0.025, 0.25, 0.5, 0.75, 0.975))
bbmsy_qunantile <- data.frame(Year=Y1, Bio=t(bbmsy_qunantile))
colnames(bbmsy_qunantile) <-
c("Year", "bbmsy_q2.5", "bbmsy_q25", "bbmsy_q50", "bbmsy_q75", "bbmsy_q97.5")
#headtail(bbmsy_qunantile, 5)
tmp1 <- ggplot(Bio_qunantile, aes(Year, Bio_q50)) + geom_line() +
geom_ribbon(aes(ymin=Bio_q25, ymax=Bio_q75), alpha = 0.2) +
geom_ribbon(aes(ymin=Bio_q2.5, ymax=Bio_q97.5), alpha = 0.1) +
geom_hline(yintercept = 1, lty = 2) + theme_light()
tmp2 <- ggplot(bbmsy_qunantile, aes(Year, bbmsy_q50)) + geom_line() +
geom_ribbon(aes(ymin=bbmsy_q25, ymax=bbmsy_q75), alpha = 0.2) +
geom_ribbon(aes(ymin=bbmsy_q2.5, ymax=bbmsy_q97.5), alpha = 0.1) +
geom_hline(yintercept = 1, lty = 2) + theme_light()
#### cmsy
Bio_qunantile <- apply(x$biomass, 2, quantile, prob=c(0.025, 0.25, 0.5, 0.75, 0.975))
Bio_qunantile <- data.frame(Year=Y1, Bio=t(Bio_qunantile))
colnames(Bio_qunantile) <-
c("Year", "Bio_q2.5", "Bio_q25", "Bio_q50", "Bio_q75", "Bio_q97.5")
#headtail(Bio_qunantile, 5)
tmp3 <- ggplot(Bio_qunantile, aes(Year, Bio_q50)) + geom_line() +
geom_ribbon(aes(ymin=Bio_q25, ymax=Bio_q75), alpha = 0.2) +
geom_ribbon(aes(ymin=Bio_q2.5, ymax=Bio_q97.5), alpha = 0.1) +
geom_hline(yintercept = 1, lty = 2) + theme_light()
tmp4 <- ggplot(x$bbmsy, aes(year, bbmsy_q50)) + geom_line() +
geom_ribbon(aes(ymin = bbmsy_q25, ymax = bbmsy_q75), alpha = 0.2) +
geom_ribbon(aes(ymin = bbmsy_q2.5, ymax = bbmsy_q97.5), alpha = 0.1) +
geom_hline(yintercept = 1, lty = 2) + theme_light()
grid.arrange(tmp1, tmp2, tmp3, tmp4, nrow=2, ncol=2)
rm(outpt)
rm(x)
setwd(CurrentDir)
Ricard, D., Minto, C., Jensen, O. P., & Baum, J. K. (2012). Examining the knowledge base and status of commercially exploited marine species with the RAM Legacy Stock Assessment Database. Fish and Fisheries, 13(4), 3 80-398.
http://doi.org/10.1111/j.1467-2979.2011.00435.x. http://ramlegacy.org
CurrentDir <- getwd()
NewDir <- paste(CurrentDir, "/DataLimit/blue_gren", sep="")
#dir.create(NewDir)
setwd(NewDir)
data(blue_gren)
headtail(blue_gren, 5)
yr ct
1 1979 512
2 1980 865
3 1981 511
4 1982 829
5 1983 935
29 2007 3190
30 2008 3960
31 2009 3290
32 2010 4220
33 2011 4220
summary(blue_gren$ct)
Min. 1st Qu. Median Mean 3rd Qu. Max.
511 2770 3370 4009 4540 9550
par(mfrow=c(4,3), mar=c(4,4,2,2))
outpt <- outpt.blue_gren <-catchmsy(
year=blue_gren$yr,
catch=blue_gren$ct,
catchCV=NULL,
catargs=list(dist="none",low=0,up=Inf,unit="MT"),
l0=list(low=0.8,up=1.0,step=0),
lt=list(low=0.1,up=0.5,refyr=2012),sigv=0,
k=list(dist="unif",low=2*max(blue_gren$ct),up=10*max(blue_gren$ct),mean=0,sd=0),
r=list(dist="unif",low=0.015,up=0.2,mean=0,sd=0),
M=list(dist="unif",low=0.18,up=0.18,mean=0.00,sd=0.00),
nsims=nsims)
print(outpt$Initial)
Distr Lower Upper Mean SD
l0 increment 0.8 1 <NA> <NA>
k unif 19100 95500 0 0
r unif 0.015 0.2 0 0
M unif 0.18 0.18 0 0
lt <NA> 0.1 0.5 <NA> <NA>
refyr <NA> 2012 <NA> <NA> <NA>
print(outpt$Parameters)
Mean (ll=1) Median (ll=1) 2.5% (ll=1) 97.5% (ll=1)
k 87441.38 88301.7915 76385.4376 95351.051
r 0.17 0.1745 0.1236 0.197
M 0.18 0.1800 0.1800 0.180
print(outpt$Estimates)
Mean Median 2.5% 97.5%
MSY 3707.645 3739.2823 2881.6559 4392.0042
BMSY 43720.688 44150.8957 38192.7188 47675.5254
FMSY 0.085 0.0872 0.0618 0.0985
Umsy 0.075 0.0766 0.0549 0.0860
OFL 1904.030 1667.7685 645.6965 3696.2264
cmsy(yr, ct, interyr_index = 2L, interbio = c(0, 1), bio_step = 0.05, start_r = resilience(NA), start_k = c(max(ct), 50 * max(ct)), startbio = if (ct[1]/max(ct) < 0.2) c(0.5, 0.9) else c(0.2, 0.6), sig_r = 0.05, reps = 1e+05, revise_bounds = TRUE, finalbio = if (ct[length(ct)]/max(ct) > 0.5) c(0.3, 0.7) else c(0.01, 0.4))
set.seed(2019)
x <- x.blue_gren <- cmsy(
yr=blue_gren$yr,
ct=blue_gren$ct,
start_r = c(0.015,0.2),
start_k = 2*c(max(blue_gren$ct), 10*max(blue_gren$ct)),
reps=1e4)
par(mfrow = c(2, 2))
plot(blue_gren$yr, blue_gren$ct, type="o", xlab="Year", ylab="Catch (t)")
plot(blue_gren$yr, apply(x$biomass, 2, median)[-1], type="o", ylab="Estimated biomass", xlab="Year")
hist(x$bmsy)
plot(x$theta$r, x$theta$k, col = "#00000030")
par(mfrow=c(2,2))
#### catchmsy
Y1 <- c(blue_gren$yr, tail(blue_gren$yr,1)+1)
Accepted <- (outpt$Values$like==1)
Est.accepted <- as.matrix(outpt$Values[Accepted,c(4,3,2)])
Bio.accepted <- apply(Est.accepted, 1, PDM.SC, Catch=blue_gren$ct)
Bio_qunantile <- apply(Bio.accepted, 1, quantile, prob=c(0.025, 0.25, 0.5, 0.75, 0.975))
Bio_qunantile <- data.frame(Year=Y1, Bio=t(Bio_qunantile))
colnames(Bio_qunantile) <-
c("Year", "Bio_q2.5", "Bio_q25", "Bio_q50", "Bio_q75", "Bio_q97.5")
#headtail(Bio_qunantile, 5)
Bmsy.accepted <- matrix(rep(Est.accepted[,2]/2, length(Y1)), byrow=T, nrow=length(Y1))
bbmsy.accepted <- apply(Est.accepted, 1, PDM.SC, Catch=blue_gren$ct)/Bmsy.accepted
bbmsy_qunantile <- apply(bbmsy.accepted, 1, quantile, prob=c(0.025, 0.25, 0.5, 0.75, 0.975))
bbmsy_qunantile <- data.frame(Year=Y1, Bio=t(bbmsy_qunantile))
colnames(bbmsy_qunantile) <-
c("Year", "bbmsy_q2.5", "bbmsy_q25", "bbmsy_q50", "bbmsy_q75", "bbmsy_q97.5")
#headtail(bbmsy_qunantile, 5)
tmp1 <- ggplot(Bio_qunantile, aes(Year, Bio_q50)) + geom_line() +
geom_ribbon(aes(ymin=Bio_q25, ymax=Bio_q75), alpha = 0.2) +
geom_ribbon(aes(ymin=Bio_q2.5, ymax=Bio_q97.5), alpha = 0.1)
tmp2 <- ggplot(bbmsy_qunantile, aes(Year, bbmsy_q50)) + geom_line() +
geom_ribbon(aes(ymin=bbmsy_q25, ymax=bbmsy_q75), alpha = 0.2) +
geom_ribbon(aes(ymin=bbmsy_q2.5, ymax=bbmsy_q97.5), alpha = 0.1) +
geom_hline(yintercept = 1, lty = 2) + theme_light()
#### cmsy
Bio_qunantile <- apply(x$biomass, 2, quantile, prob=c(0.025, 0.25, 0.5, 0.75, 0.975))
Bio_qunantile <- data.frame(Year=Y1, Bio=t(Bio_qunantile))
colnames(Bio_qunantile) <-
c("Year", "Bio_q2.5", "Bio_q25", "Bio_q50", "Bio_q75", "Bio_q97.5")
#headtail(Bio_qunantile, 5)
tmp3 <- ggplot(Bio_qunantile, aes(Year, Bio_q50)) + geom_line() +
geom_ribbon(aes(ymin=Bio_q25, ymax=Bio_q75), alpha = 0.2) +
geom_ribbon(aes(ymin=Bio_q2.5, ymax=Bio_q97.5), alpha = 0.1)
tmp4 <- ggplot(x$bbmsy, aes(year, bbmsy_q50)) + geom_line() +
geom_ribbon(aes(ymin = bbmsy_q25, ymax = bbmsy_q75), alpha = 0.2) +
geom_ribbon(aes(ymin = bbmsy_q2.5, ymax = bbmsy_q97.5), alpha = 0.1) +
geom_hline(yintercept = 1, lty = 2) + theme_light()
grid.arrange(tmp1, tmp2, tmp3, tmp4, nrow=2, ncol=2)
rm(outpt)
rm(x)
setwd(CurrentDir)
NewDir <- paste(CurrentDir, "/DataLimit/kawakawa", sep="")
#dir.create(NewDir)
setwd(NewDir)
kawakawa <- read.csv("IOTC_kawakawa.csv")
headtail(kawakawa, 5)
Year Catch
1 1950 5574
2 1951 3253
3 1952 3285
4 1953 3243
5 1954 4495
64 2013 167348
65 2014 155750
66 2015 152906
67 2016 150743
68 2017 159752
summary(kawakawa$Catch)
Min. 1st Qu. Median Mean 3rd Qu. Max.
3243 10087 38999 56292 89174 167348
l0 ~ U(0.8, 1.0)
lt ~ U(0.3, 0.7) k ~ U(maxC, 100*maxC)
r ~ U(0.01, 0.4)
M = 0.18
par(mfrow=c(4,3), mar=c(4,4,2,2))
outpt <- outpt.kw1 <- catchmsy(
year=kawakawa$Year,
catch=kawakawa$Catch,
catchCV=NULL,
catargs=list(dist="none",low=0,up=Inf,unit="MT"),
l0=list(low=0.8,up=1.0,step=0),
lt=list(low=0.3,up=0.7,refyr=2018),
sigv=0,
k=list(dist="unif",low=max(kawakawa$Catch),up=20*max(kawakawa$Catch),mean=0,sd=0),
r=list(dist="unif",low=0.01,up=0.4,mean=0,sd=0),
M=list(dist="unif",low=0.18,up=0.18,mean=0.00,sd=0.00),
nsims=nsims)
print(outpt$Initial)
Distr Lower Upper Mean SD
l0 increment 0.8 1 <NA> <NA>
k unif 167348 3346960 0 0
r unif 0.01 0.4 0 0
M unif 0.18 0.18 0 0
lt <NA> 0.3 0.7 <NA> <NA>
refyr <NA> 2018 <NA> <NA> <NA>
print(outpt$Parameters)
Mean (ll=1) Median (ll=1) 2.5% (ll=1) 97.5% (ll=1)
k 2272450.232 2234293.8870 1328337.5691 3250623.0935
r 0.238 0.2299 0.0966 0.3942
M 0.180 0.1800 0.1800 0.1800
print(outpt$Estimates)
Mean Median 2.5% 97.5%
MSY 124523.913 122742.7265 71323.7251 170301.2517
BMSY 1136225.116 1117146.9435 664168.7846 1625311.5468
FMSY 0.119 0.1150 0.0483 0.1971
Umsy 0.102 0.0996 0.0432 0.1642
OFL 120304.951 113297.4717 44966.0781 198913.5488
cmsy(yr, ct, interyr_index = 2L, interbio = c(0, 1), bio_step = 0.05, start_r = resilience(NA), start_k = c(max(ct), 50 * max(ct)), startbio = if (ct[1]/max(ct) < 0.2) c(0.5, 0.9) else c(0.2, 0.6), sig_r = 0.05, reps = 1e+05, revise_bounds = TRUE, finalbio = if (ct[length(ct)]/max(ct) > 0.5) c(0.3, 0.7) else c(0.01, 0.4))
set.seed(2019)
x <- x.kawakawa <- cmsy(
yr=kawakawa$Year,
ct=kawakawa$Catch,
start_r = c(0.015,0.1),
start_k = c(max(kawakawa$Catch), 20*max(kawakawa$Catch)),
reps=1e4)
par(mfrow = c(2, 2))
plot(kawakawa$Year, kawakawa$Catch, type="o", xlab="Year", ylab="Catch (t)")
plot(kawakawa$Year, apply(x$biomass, 2, median)[-1], type="o", ylab="Estimated biomass", xlab="Year")
hist(x$bmsy)
plot(x$theta$r, x$theta$k, col = "#00000030")
par(mfrow=c(2,2))
#### catchmsy
Y1 <- c(kawakawa$Year, tail(kawakawa$Year,1)+1)
Accepted <- (outpt$Values$like==1)
Est.accepted <- as.matrix(outpt$Values[Accepted,c(4,3,2)])
Bio.accepted <- apply(Est.accepted, 1, PDM.SC, Catch=kawakawa$Catch)
Bio_qunantile <- apply(Bio.accepted, 1, quantile, prob=c(0.025, 0.25, 0.5, 0.75, 0.975))
Bio_qunantile <- data.frame(Year=Y1, Bio=t(Bio_qunantile))
colnames(Bio_qunantile) <-
c("Year", "Bio_q2.5", "Bio_q25", "Bio_q50", "Bio_q75", "Bio_q97.5")
#headtail(Bio_qunantile, 5)
Bmsy.accepted <- matrix(rep(Est.accepted[,2]/2, length(Y1)), byrow=T, nrow=length(Y1))
bbmsy.accepted <- apply(Est.accepted, 1, PDM.SC, Catch=kawakawa$Catch)/Bmsy.accepted
bbmsy_qunantile <- apply(bbmsy.accepted, 1, quantile, prob=c(0.025, 0.25, 0.5, 0.75, 0.975))
bbmsy_qunantile <- data.frame(Year=Y1, Bio=t(bbmsy_qunantile))
colnames(bbmsy_qunantile) <-
c("Year", "bbmsy_q2.5", "bbmsy_q25", "bbmsy_q50", "bbmsy_q75", "bbmsy_q97.5")
#headtail(bbmsy_qunantile, 5)
tmp1 <- ggplot(Bio_qunantile, aes(Year, Bio_q50)) + geom_line() +
geom_ribbon(aes(ymin=Bio_q25, ymax=Bio_q75), alpha = 0.2) +
geom_ribbon(aes(ymin=Bio_q2.5, ymax=Bio_q97.5), alpha = 0.1)
tmp2 <- ggplot(bbmsy_qunantile, aes(Year, bbmsy_q50)) + geom_line() +
geom_ribbon(aes(ymin=bbmsy_q25, ymax=bbmsy_q75), alpha = 0.2) +
geom_ribbon(aes(ymin=bbmsy_q2.5, ymax=bbmsy_q97.5), alpha = 0.1) +
geom_hline(yintercept = 1, lty = 2) + theme_light()
#### cmsy
Bio_qunantile <- apply(x$biomass, 2, quantile, prob=c(0.025, 0.25, 0.5, 0.75, 0.975))
Bio_qunantile <- data.frame(Year=Y1, Bio=t(Bio_qunantile))
colnames(Bio_qunantile) <-
c("Year", "Bio_q2.5", "Bio_q25", "Bio_q50", "Bio_q75", "Bio_q97.5")
#headtail(Bio_qunantile, 5)
tmp3 <- ggplot(Bio_qunantile, aes(Year, Bio_q50)) + geom_line() +
geom_ribbon(aes(ymin=Bio_q25, ymax=Bio_q75), alpha = 0.2) +
geom_ribbon(aes(ymin=Bio_q2.5, ymax=Bio_q97.5), alpha = 0.1)
tmp4 <- ggplot(x$bbmsy, aes(year, bbmsy_q50)) + geom_line() +
geom_ribbon(aes(ymin = bbmsy_q25, ymax = bbmsy_q75), alpha = 0.2) +
geom_ribbon(aes(ymin = bbmsy_q2.5, ymax = bbmsy_q97.5), alpha = 0.1) +
geom_hline(yintercept = 1, lty = 2) + theme_light()
grid.arrange(tmp1, tmp2, tmp3, tmp4, nrow=2, ncol=2)
setwd(CurrentDir)
CurrentDir <- getwd()
NewDir <- paste(CurrentDir, "/DataLimit/albacore", sep="")
#dir.create(NewDir)
setwd(NewDir)
albacore <- read.csv("IOTC_ALB.csv")
headtail(albacore, 5)
Year Catch
1 1950 6
2 1951 7
3 1952 68
4 1953 1095
5 1954 2831
57 2006 30114
58 2007 44479
59 2008 48148
60 2009 40480
61 2010 40000
summary(albacore$Catch)
Min. 1st Qu. Median Mean 3rd Qu. Max.
6 12434 19357 20970 30114 48148
l0 ~ U(0.8, 1.0)
lt ~ U(0.3, 0.7) in 2011
k ~ U(5maxC, 10maxC)
r ~ U(0.01, 0.4)
M = 0.18
par(mfrow=c(4,3), mar=c(4,4,2,2))
outpt <- outpt.alb1 <- catchmsy(
year=albacore$Year,
catch=albacore$Catch,
catchCV=NULL,
catargs=list(dist="none",low=0,up=Inf,unit="MT"),
l0=list(low=0.8,up=1.0,step=0),
lt=list(low=0.3,up=0.7,refyr=2011),
sigv=0,
k=list(dist="unif",low=5*max(albacore$Catch),up=10*max(albacore$Catch),mean=0,sd=0),
r=list(dist="unif",low=0.01,up=0.4,mean=0,sd=0),
M=list(dist="unif",low=0.18,up=0.18,mean=0.00,sd=0.00),
nsims=nsims)
print(outpt$Initial)
Distr Lower Upper Mean SD
l0 increment 0.8 1 <NA> <NA>
k unif 240740 481480 0 0
r unif 0.01 0.4 0 0
M unif 0.18 0.18 0 0
lt <NA> 0.3 0.7 <NA> <NA>
refyr <NA> 2011 <NA> <NA> <NA>
print(outpt$Parameters)
Mean (ll=1) Median (ll=1) 2.5% (ll=1) 97.5% (ll=1)
k 410892.31 418524.4824 319202.0067 479507.9260
r 0.33 0.3397 0.2313 0.3968
M 0.18 0.1800 0.1800 0.1800
print(outpt$Estimates)
Mean Median 2.5% 97.5%
MSY 33647.621 32677.2793 26602.2970 44040.0946
BMSY 205446.156 209262.2412 159601.0033 239753.9630
FMSY 0.165 0.1699 0.1157 0.1984
Umsy 0.140 0.1433 0.1001 0.1652
OFL 29405.006 28489.9766 14494.2949 50620.7185
rm(outpt)
k ~ U(5maxC, 20maxC)
r ~ U(0.01, 0.6)
par(mfrow=c(4,3), mar=c(4,4,2,2))
outpt <- outpt.alb2 <- catchmsy(
year=albacore$Year,
catch=albacore$Catch,
catchCV=NULL,
catargs=list(dist="none",low=0,up=Inf,unit="MT"),
l0=list(low=0.8,up=1.0,step=0),
lt=list(low=0.3,up=0.7,refyr=2011),
sigv=0,
k=list(dist="unif",low=5*max(albacore$Catch),up=20*max(albacore$Catch),mean=0,sd=0),
r=list(dist="unif",low=0.1,up=0.6,mean=0,sd=0),
M=list(dist="unif",low=0.18,up=0.18,mean=0.00,sd=0.00),
nsims=nsims)
print(outpt$Initial)
Distr Lower Upper Mean SD
l0 increment 0.8 1 <NA> <NA>
k unif 240740 962960 0 0
r unif 0.1 0.6 0 0
M unif 0.18 0.18 0 0
lt <NA> 0.3 0.7 <NA> <NA>
refyr <NA> 2011 <NA> <NA> <NA>
print(outpt$Parameters)
Mean (ll=1) Median (ll=1) 2.5% (ll=1) 97.5% (ll=1)
k 552419.289 527158.5659 263522.086 922614.8950
r 0.289 0.2639 0.108 0.5664
M 0.180 0.1800 0.180 0.1800
print(outpt$Estimates)
Mean Median 2.5% 97.5%
MSY 34226.303 34644.0486 22180.0530 44358.2753
BMSY 276209.644 263579.2830 131761.0430 461307.4475
FMSY 0.144 0.1320 0.0540 0.2832
Umsy 0.122 0.1134 0.0482 0.2267
OFL 33380.951 33990.9295 13633.6452 50892.6777
rm(outpt)
l0 ~ U(0.9, 1.0)
lt ~ U(0.2, 0.8) in 2011
k ~ U(2maxC, 10maxC)
par(mfrow=c(4,3), mar=c(4,4,2,2))
outpt <- outpt.alb3 <-catchmsy(
year=albacore$Year,
catch=albacore$Catch,
catchCV=NULL,
catargs=list(dist="none",low=0,up=Inf,unit="MT"),
l0=list(low=0.9,up=1.0,step=0),
lt=list(low=0.2,up=0.8,refyr=2011),
sigv=0,
k=list(dist="unif",low=5*max(albacore$Catch),up=10*max(albacore$Catch),mean=0,sd=0),
r=list(dist="unif",low=0.1,up=0.4,mean=0,sd=0),
M=list(dist="unif",low=0.18,up=0.18,mean=0.00,sd=0.00),
nsims=nsims)
print(outpt$Initial)
Distr Lower Upper Mean SD
l0 increment 0.9 1 <NA> <NA>
k unif 240740 481480 0 0
r unif 0.1 0.4 0 0
M unif 0.18 0.18 0 0
lt <NA> 0.2 0.8 <NA> <NA>
refyr <NA> 2011 <NA> <NA> <NA>
print(outpt$Parameters)
Mean (ll=1) Median (ll=1) 2.5% (ll=1) 97.5% (ll=1)
k 410204.822 417572.7346 303335.3076 478909.3660
r 0.326 0.3356 0.2208 0.3962
M 0.180 0.1800 0.1800 0.1800
print(outpt$Estimates)
Mean Median 2.5% 97.5%
MSY 33121.288 32408.4650 25185.9618 44615.7517
BMSY 205102.411 208786.3673 151667.6538 239454.6830
FMSY 0.163 0.1678 0.1104 0.1981
Umsy 0.138 0.1417 0.0958 0.1650
OFL 27859.414 26897.0843 9681.2116 51673.6699
rm(outpt)
k ~ U(2maxC, 10maxC)
r ~ U(0.01, 0.6)
M = 0.3
par(mfrow=c(4,3), mar=c(4,4,2,2))
outpt <- outpt.alb4 <-catchmsy(
year=albacore$Year,
catch=albacore$Catch,
catchCV=NULL,
catargs=list(dist="none",low=0,up=Inf,unit="MT"),
l0=list(low=0.8,up=1.0,step=0),
lt=list(low=0.3,up=0.7,refyr=2011),
sigv=0,
k=list(dist="unif",low=5*max(albacore$Catch),up=10*max(albacore$Catch),mean=0,sd=0),
r=list(dist="unif",low=0.1,up=0.4,mean=0,sd=0),
M=list(dist="unif",low=0.3,up=0.3,mean=0.00,sd=0.00),
nsims=nsims)
print(outpt$Initial)
Distr Lower Upper Mean SD
l0 increment 0.8 1 <NA> <NA>
k unif 240740 481480 0 0
r unif 0.1 0.4 0 0
M unif 0.3 0.3 0 0
lt <NA> 0.3 0.7 <NA> <NA>
refyr <NA> 2011 <NA> <NA> <NA>
print(outpt$Parameters)
Mean (ll=1) Median (ll=1) 2.5% (ll=1) 97.5% (ll=1)
k 416288.52 420228.9659 325920.7899 477985.1768
r 0.33 0.3382 0.2349 0.3961
M 0.30 0.3000 0.3000 0.3000
print(outpt$Estimates)
Mean Median 2.5% 97.5%
MSY 34071.748 33316.5798 26923.8523 43214.3455
BMSY 208144.261 210114.4829 162960.3949 238992.5884
FMSY 0.165 0.1691 0.1175 0.1981
Umsy 0.132 0.1350 0.0960 0.1560
OFL 28900.940 27945.1198 14171.7147 46426.0078
rm(outpt)
setwd(CurrentDir)