# ====================================================================
# Created by: Sean Anderson, sean@seananderson.ca
# Created: Mar 18, 2012
# Last modified: Mar 29, 2012
# Purpose: Get the stock status as defined by the updated
# algorithm in Froese et al. 2012. Mar. Biol.
# ====================================================================
get_froese_etal_2012_status <- structure(function# Return the Froese et al. 2012 stock status based on a catch series.
### Return the fisheries stock status from a catch series using the updated algorithm in:
### @article{Froese:etal:2012,
### Author = {Froese, Rainer and Zeller, Dirk and Kleisner, Kristin and Pauly, Daniel},
### Journal = {Marine Biology},
### Title = {What catch data can tell us about the status of global fisheries},
### Volume = {In press},
### Year = {2012}}
(catch
### A time series of catch with no missing values.
##
##references<<Froese, R., Zeller, D., Kleisner, K., and Pauly, D. What catch data can tell us about the status of global fisheries? Mar. Biol. In press. doi: 10.1007/s00227-012-1909-6
##
##seealso<< \code{\link{plot_status_stacked}}, \code{\link{plot_status_ts}}
) {
x <- catch
status_labels <- c("Undeveloped", "Developing", "Rebuilding", "Fully exploited", "Overexploited", "Collapsed")
years <- 1:length(catch) # fake years to work with
d <- data.frame(year = years, catch = catch, status = factor(NA, levels = 1:6, labels = status_labels))
c_max <- max(x)
year_c_max <- years[x == c_max][1]
# Check if Cmax occurs in final year. If it does then increase Cmax by
# 50% and make it happen one year after the last year.
# We will remove this fake year at the end before returning the
# results.
if(year_c_max == max(years)) {
c_max_1.5 <- TRUE
c_max <- c_max * 1.5
d <- rbind(d, data.frame(year = 9999, catch = c_max, status = factor(NA, levels = 1:6, labels = status_labels)))
} else {
c_max_1.5 <- FALSE
}
year_c_max <- years[x == c_max][1]
year_0.5_c_max <- years[x >= 0.5 * c_max][1]
# undeveloped
d[years < year_0.5_c_max & x < 0.1 * c_max, "status"] <- factor(1, levels = 1:6, labels = status_labels)
# developing
d[years < year_0.5_c_max & x >= 0.1 * c_max & x <= 0.5 * c_max, "status"] <- factor(2, levels = 1:6, labels = status_labels)
# fully exploited
d[years >= year_0.5_c_max & x > 0.5 * c_max, "status"] <- factor(4, levels = 1:6, labels = status_labels)
# overexploited
d[years >= year_0.5_c_max & x <= 0.5 * c_max & x >= 0.1 * c_max, "status"] <- factor(5, levels = 1:6, labels = status_labels)
# collapsed
d[years >= year_0.5_c_max & x < 0.1 * c_max, "status"] <- factor(6, levels = 1:6, labels = status_labels)
# if all 0s then set to undeveloped:
if(length(unique(d$catch)) == 1 & unique(d$catch)[1] %in% 0) d$status <- factor(1, levels = 1:6, labels = status_labels)
# figure out how many collapsed followed by recoveries there are:
# check all collapses to see if a full exploited comes after:
#browser()
rows_with_collapsed <- (1:nrow(d))[d$status == "Collapsed"]
#rows_where_collapse_begins <- rows_with_collapsed[diff(c(-99, rows_with_collapsed)) != 1]
rows_where_collapse_ends <- rows_with_collapsed[diff(c(rows_with_collapsed, 9999)) != 1]
# if the last year is a collapse then we aren't going to deal with it,
# because it can't recover by definition, so remove it here from the
# vector:
#rows_where_collapse_begins <- rows_where_collapse_begins[!rows_where_collapse_begins %in% nrow(d)]
rows_where_collapse_ends <- rows_where_collapse_ends[!rows_where_collapse_ends %in% nrow(d)]
#n_collapses <- length(rows_where_collapse_begins)
n_collapses <- length(rows_where_collapse_ends)
# so we can check the last one: (unless the last one is the start of a
# collapse)
#if(max(rows_where_collapse_begins) != nrow(d))
#rows_where_collapse_begins <- c(rows_where_collapse_begins, (nrow(d)+1))
rows_where_collapse_ends <- c(rows_where_collapse_ends, (nrow(d)+1))
# check if should stay collapsed to end of time series:
# if there is never a fully exploited after than the whole series
# should stay collapsed from there on:
# In the final year, accept C[0.28 C/Cmax as indicative of subsequent fully exploited status
# So, make the extra year at the end have a status of Fully exploited
# if this extra year already exists than fill that status
# otherwise create an extra year and give it that status while
# assigning it a catch equal to the last year's catch value
fully_exploited_0.28 <- FALSE # default value
if(catch[length(years)] >= 0.28 * c_max & c_max_1.5 == TRUE) {
fully_exploited_0.28 <- TRUE
d[nrow(d), "status"] <- factor(4, levels = 1:6, labels = status_labels)
}
if(catch[length(years)] >= 0.28 * c_max & c_max_1.5 == FALSE) {
fully_exploited_0.28 <- TRUE
d <- rbind(d, data.frame(year = 9999, catch = catch[length(years)], status = factor(4, levels = 1:6, labels = status_labels)))
}
#browser()
d$adjusted_status <- d$status
if(n_collapses > 0) {
for(i in 1:n_collapses) {
rows_to_check <- (rows_where_collapse_ends[i]+1):(rows_where_collapse_ends[i+1])
dat_to_check <- d[rows_to_check, "status"]
# if it recovers at some point before the next collapse (or end of
# the time series) then we need to add rebuilding years:
if("Fully exploited" %in% dat_to_check) {
#data_collapse_to_fully_exploited <- d[(rows_where_collapse_begins[i]+1):nrow(d), ]
#row_with_first_fully_exploited <- (1:nrow(data_collapse_to_fully_exploited))[data_collapse_to_fully_exploited$status == "Fully exploited"][1]
first_fully_exploited_row <- min(rows_to_check[d[rows_to_check, "status"] == "Fully exploited"], na.rm = TRUE) # na.rm is needed because rows_to_check is one bigger than the number of rows so there will be NAs (indexing non-existent rows)
#print(first_fully_exploited_row)
#print(min(rows_to_check))
#browser()
d[min(rows_to_check):first_fully_exploited_row, ][d[min(rows_to_check):first_fully_exploited_row, ]$status=="Overexploited", "adjusted_status"] <- factor(3, levels = 1:6, labels = status_labels) # these are now rebuilding
#d[(rows_where_collapse_begins[i] + 1):(rows_where_collapse_begins[i] + row_with_first_fully_exploited - 1), "adjusted_status"] <- factor(3, levels = 1:6, labels = status_labels) # these are now rebuilding
}
}
}
# if we added a 1.5Cmax fake year at the end, remove it before giving
# back results:
if(c_max_1.5 | fully_exploited_0.28) d <- d[-nrow(d),]
# One final tweak:
# Despite what Table 2 says, if the last year has the max year of
# catch, adjust the max to 1.5 * c_max but then only let years be
# classified as "developing" or "underdeveloped". Nothing else is
# allowed.
#browser()
if(c_max_1.5) {
# undeveloped
d[x < 0.1 * c_max, "adjusted_status"] <- factor(1, levels = 1:6, labels = status_labels)
# developing
d[x >= 0.1 * c_max, "adjusted_status"] <- factor(2, levels = 1:6, labels = status_labels)
#browser()
}
return(list(status = d$adjusted_status, c_max_1.5 = c_max_1.5, fully_exploited_0.28 = fully_exploited_0.28))
### A list containing the named elements: ``status'', the stock
### status; ``c_max_1.5'', whether the maximum was assumed to be 1.5
### times the actual maximum catch; and ``fully_exploited_0.28'',
### whether the stock was assumed to be rebuilt in the last year of
### the series because the catch that year was 0.28 times or more of
### the maximum catch.
}
,ex=function(){
set.seed(3)
x <- c(1:20, 20:1, rep(2, 5), 2:20, 19:1, rep(2, 10), 2:8)*10 + rnorm(100, 6, 8)
years <- 1901:2000
dat <- data.frame(year = years, catch = x)
plot(dat[,1:2], type = "o", pch = 20)
transform(dat, status = get_froese_etal_2012_status(catch)$status)
}
)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.