The stockSMART updated plots and my by-hand dataset for 2023 SOE are the same except I included the status results from the December 2022 research track assessments for spiny dogfish and bluefish, both of which changed status. We need to decide whether we want these in the SOE or not.
As of January 5, SOE has my dataset with RT results
stocksmart
for 2023 SOE reportsAndy renamed the assessmentdata package stocksmart based on Stock SMART.
Two data frames are in the package, stockAssessmentData
and stockAssessmentSummary
.
In stockAssessmentData
we have time series. Columns are
StockName, Year, Value, Metric, Description, Units, AssessmentYear,
Jurisdiction, FMP, CommonName, ScientificName, ITIS, UpdateType,
StockArea, RegionalEcosystem and the reported metrics are Catch, Fmort,
Recruitment, Abundance, Index.
datatable(head(stockAssessmentData), rownames = FALSE)
In stockAssessmentSummary
we have assessment metadata.
Columns are Stock Name, Jurisdiction, FMP, Science Center, Regional
Ecosystem, FSSI Stock?, ITIS Taxon Serial Number, Scientific Name,
Common Name, Stock Area, Assessment Year, Assessment Month, Last Data
Year, Update Type, Review Result, Assessment Model, Model Version, Lead
Lab, Citation, Final Assessment Report 1, Final Assessment Report 2,
Point of Contact, Life History Data, Abundance Data, Catch Data,
Assessment Level, Assessment Frequency, Assessment Type, Model Category,
Catch Input Data, Abundance Input Data, Biological Input Data, Ecosystem
Linkage, Composition Input Data, F Year, Estimated F, F Unit, F Basis,
Flimit, Flimit Basis, Fmsy, Fmsy Basis, F/Flimit, F/Fmsy, Ftarget,
Ftarget Basis, F/Ftarget, B Year, Estimated B, B Unit, B Basis, Blimit,
Blimit Basis, Bmsy, Bmsy Basis, B/Blimit, B/Bmsy, MSY, MSY Unit.
datatable(head(stockAssessmentSummary), rownames = FALSE, options = list(scrollX = TRUE))
Build ecodata input spreadsheet from
stockAssessmentSummary
and use the ecodata code to make the
dataset for plotting:
assess2022 <- stockAssessmentSummary %>%
filter(`Science Center` == "NEFSC") %>%
select(c(`Stock Name`, Jurisdiction, FMP, `Science Center`,
`Stock Area`, `Assessment Year`, `Last Data Year`,
`F Year`, `Estimated F`, Flimit, Fmsy, `F/Flimit`,
`F/Fmsy`, Ftarget, `F/Ftarget`, `B Year`, `Estimated B`,
`B Unit`, Blimit, Bmsy, `B/Blimit`, `B/Bmsy`)) %>%
arrange(Jurisdiction, `Stock Name`, FMP, `Assessment Year`) %>%
rename(Entity.Name = `Stock Name`,
Assessment.Year = `Assessment Year`,
F.Fmsy = `F/Fmsy`,
B.Bmsy = `B/Bmsy`,
Estimated.F = `Estimated F`,
Estimated.B = `Estimated B`)
#write.csv(assess2022, here("assess.csv"))
# from get_stocks.R, ecodata 2020
#assess <- read.csv(file.path(data.dir, "2019assess.csv"))
assess <- assess2022
#decode <- read.csv(file.path(data.dir, "2019decoder.csv"))
decode <- read.csv(here("2020decoder.csv"))
write.csv(decode, here("decoder.csv"))
stock_status_stockSMART <-
assess %>%
dplyr::group_by(Entity.Name) %>%
dplyr::filter(Assessment.Year == max(Assessment.Year)) %>%
#Find last year assessment occurred for each stock
dplyr::ungroup() %>%
dplyr::left_join(.,decode, by = "Entity.Name") %>% #Join in list of managed species
dplyr::select(Entity.Name, Assessment.Year, F.Fmsy, B.Bmsy, Council, Code) %>%
#select column variables to keep
dplyr::mutate(id = 1:length(Entity.Name)) %>%
tidyr::gather(.,Var, Value,-id,-Entity.Name,-Assessment.Year,-Council,-Code) %>%
#wide to long
dplyr::select(-id) %>%
dplyr::rename(`Last assessment` = Assessment.Year,
Stock = Entity.Name) %>% #rename variables for clarity
dplyr::mutate(Units = "unitless") #%>%
#dplyr::mutate(Value = replace(Value, which(Code == "N Windowpane" & Var == "F.Fmsy"), NA))
Then test to see if we see the updates relative to SOE 2022 (updates through 2021) ecodata. I’m leaving out all the plot annotations for unknown status.
stock_status <-
stock_status_stockSMART %>%
mutate(Code = recode(Code, "Dogfish" = "Sp. Dogfish" )) %>%
spread(.,Var,Value) %>%
filter(Council %in% c("MAFMC","Both")) %>%
group_by(Stock) %>%
mutate(score = case_when(
(B.Bmsy <0.5) ~"a",
(F.Fmsy >1) ~ "a",
(F.Fmsy < 1 & B.Bmsy > 0.5 & B.Bmsy < 1) ~ "b",
(F.Fmsy < 1 & B.Bmsy > 1) ~ "c"))
#Plot constants
y.max <- 2.1 #2.0 mackerel cut off F/Fmsy is 2.08
x.max <- 2.6
#A dataframe that defines custom legend for stocks with unknown status
# unknown <- data.frame(text = c("Unknown Status", "Longfin Squid",
# "Shortfin Squid", "N. Goosefish", "S. Goosefish"),
# x = rep(0.9*x.max,5), y = seq(0.93*y.max,1.5,-.1))
# Custom Color
custom_color<- c("#56B4E9", "#009E73", "#0072B2")
#Plotting code
ggplot(data = stock_status) +
geom_vline(xintercept = 1, linetype = "dotted")+
geom_vline(xintercept = 0.5, linetype = "dashed")+
geom_hline(yintercept = 1, linetype = "dashed") +
geom_point(aes(x = B.Bmsy,
y = F.Fmsy,
shape = Council,
color = score)) +
geom_text_repel(aes(x = B.Bmsy, #geom_text_repel auto-jitters text around points
y = F.Fmsy,
label = Code,
color = score),
show.legend = FALSE, nudge_y = -0.01, nudge_x = 0.05) +
scale_color_brewer(palette = "Dark2",
breaks = stock_status$score) +
ylim(0,y.max) +
xlim(0,x.max) +
# geom_text(data = unknown, aes(x = x, y = y, label = text), #Custom legend for unknown stock status
# size = c(4.75,rep(4,4))) +
# annotate("rect", xmin = 0.8*x.max,
# xmax = x.max,
# ymin = 0.65*y.max,
# ymax = 0.90*y.max,
# alpha = 0.1) +
xlab(expression(~B/B[msy])) +
ylab(expression(~F/F[msy])) +
guides(color = FALSE) +
theme_ts()
#Get data, spread for plotting, and filter
stock_status <- ecodata::stock_status %>%
dplyr::mutate(Code = recode(Code, "Dogfish" = "Sp. Dogfish" ),
Code = recode(Code, "Mackerel" = "At. Mackerel")) %>%
tidyr::spread(.,Var,Value) %>%
dplyr::filter(Council %in% c("MAFMC","Both")) %>%
dplyr::group_by(Stock) %>%
dplyr::mutate(score = case_when(
(B.Bmsy <0.5) ~"a",
(F.Fmsy >1) ~ "a",
(F.Fmsy < 1 & B.Bmsy > 0.5 & B.Bmsy < 1) ~ "b",
(F.Fmsy < 1 & B.Bmsy > 1) ~ "c"))
#Plot constants
y.max <- 2.1 #1.75 mackerel cut off F/Fmsy is 1.8
x.max <- 2.6
#A dataframe that defines custom legend for stocks with unknown status
unknown <- data.frame(text = c("Unknown Status", "Longfin Squid",
"Shortfin Squid", "N. Goosefish", "S. Goosefish", "Blueline Tilefish", "Chub Mackerel"),
x = rep(0.9*x.max,7), y = seq(0.88*y.max,1.2,-0.1))
# Custom Color
custom_color<- c("#56B4E9", "#009E73", "#0072B2")
#Plotting code
ggplot2::ggplot(data = stock_status) +
ggplot2::geom_vline(xintercept = 1, linetype = "dotted")+
ggplot2::geom_vline(xintercept = 0.5, linetype = "dashed")+
ggplot2::geom_hline(yintercept = 1, linetype = "dashed") +
ggplot2::geom_point(aes(x = B.Bmsy,
y = F.Fmsy,
shape = Council,
color = score)) +
ggrepel::geom_text_repel(aes(x = B.Bmsy, #geom_text_repel auto-jitters text around points
y = F.Fmsy,
label = Code,
color = score),
show.legend = FALSE, nudge_y = -0.01, nudge_x = 0.05) +
ggplot2::scale_color_brewer(palette = "Dark2",
breaks = stock_status$score) +
ggplot2::ylim(0,y.max) +
ggplot2::xlim(0,x.max) +
ggplot2::geom_text(data = unknown, aes(x = x-0.5, y = y+0.2, label = text), #Custom legend for unknown stock status
size = c(4.75,rep(4,6))) +
#ggplot2::annotate("rect", xmin = 0.8*x.max,
# xmax = x.max
# ymin = 0.65*y.max,
# ymax = 0.90*y.max,
# alpha = 0.1) +
ggplot2::xlab(expression(~B/B[msy])) +
ggplot2::ylab(expression(~F/F[msy])) +
ggplot2::guides(color = FALSE) +
ecodata::theme_ts()
stock_status <- stock_status_stockSMART %>%
mutate(Code = recode(Code, "Dogfish" = "Sp. Dogfish" )) %>%
spread(.,Var,Value) %>%
filter(Council %in% c("NEFMC","Both")) %>%
group_by(Stock) %>%
mutate(score = case_when(
(B.Bmsy <0.5) ~"a",
(F.Fmsy >1) ~ "a",
(F.Fmsy < 1 & B.Bmsy > 0.5 & B.Bmsy < 1) ~ "b",
(F.Fmsy < 1 & B.Bmsy > 1) ~ "c"))
#Plot constants
y.max <- 1.5
x.max <- 10
all_missing <- stock_status %>%
filter(is.na(B.Bmsy),is.na(F.Fmsy)) %>%
dplyr::select(Code, Council)
b_missing <- stock_status %>%
filter(is.na(B.Bmsy), !is.na(F.Fmsy)) %>%
dplyr::select(Code, Council)
f_missing <- stock_status %>%
filter(is.na(F.Fmsy), !is.na(B.Bmsy)) %>%
dplyr::select(Code, Council)
#A dataframe that defines custom legend for stocks with unknown status
# all.df <- data.frame(text = all_missing$Code,
# x = rep(x.max*0.9,length(all_missing$Code)),
# #y = seq(1.45,1.05, length.out = 7))
# y = seq(1.45,1.05, length.out = length(all_missing$Code)))
# b.df <- data.frame(text = b_missing$Code,
# x = rep(x.max*0.7,length(b_missing$Code)),
# y = c(1.45,2.15, length.out = length(b_missing$Code)))
# f.df <- data.frame(text = f_missing$Code,
# x = rep(x.max*0.5,length(f_missing$Code)),
# y = seq(1.45,1.0, length.out = length(f_missing$Code)))
# Custom Color
custom_color<- c("#56B4E9", "#009E73", "#0072B2")
#Plotting code
ggplot(data = stock_status) +
geom_vline(xintercept = 1, linetype = "dotted", color = "grey60")+
geom_vline(xintercept = 0.5, linetype = "dashed", color = "grey60")+
geom_hline(yintercept = 1, linetype = "dashed", color = "grey60") +
geom_point(aes(x = B.Bmsy,
y = F.Fmsy,
color = stock_status$score)) +
geom_text_repel(aes(x = B.Bmsy, #geom_text_repel auto-jitters text around points
y = F.Fmsy,
label = Code,
color = stock_status$score), show.legend = FALSE,nudge_y = -0.01, nudge_x = 0.05) +
ylim(0,y.max) +
xlim(0,x.max*1.1) +
# geom_text(data = all.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
# geom_text(data = b.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
# geom_text(data = f.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
# scale_color_brewer(palette = "Dark2", #Change legend labels for clarity
# breaks = stock_status$score) +
# annotate("rect", xmin = 0.924*x.max,
# xmax = 1.08*x.max,
# ymin = 0.645*y.max,
# ymax = 0.98*y.max,
# alpha = 0.01) +
# annotate("text", x = 9, y = 1.5, label = "F and B missing", fontface =2, size = 3)+
# annotate("rect",
# xmin = 0.70*x.max,
# xmax = 0.85*x.max,
# ymin = 0.90*y.max,
# ymax = 1.8,
# alpha = 0.01) +
# annotate("text", x = 7, y = 1.5, label = "B missing", fontface =2, size = 3)+
# annotate("rect", xmin = 0.509*x.max,
# xmax = 0.681*x.max,
# ymin = 0.65*y.max,
# ymax = 0.98*y.max,
# alpha = 0.01) +
# annotate("text", x = 5, y = 1.5, label = "F missing", fontface =2, size = 3)+
xlab(expression(~B/B[msy])) +
ylab(expression(~F/F[msy])) +
guides(color = FALSE) +
theme_ts()
#Get data, spread for plotting, and filter
stock_status <- ecodata::stock_status %>%
dplyr::mutate(Code = dplyr::recode(Code, "Dogfish" = "Sp. Dogfish" )) %>%
tidyr::spread(.,Var,Value) %>%
dplyr::filter(Council %in% c("NEFMC","Both")) %>%
dplyr::group_by(Stock) %>%
dplyr::mutate(score = case_when(
(B.Bmsy <0.5) ~"a",
(F.Fmsy >1) ~ "a",
(F.Fmsy < 1 & B.Bmsy > 0.5 & B.Bmsy < 1) ~ "b",
(F.Fmsy < 1 & B.Bmsy > 1) ~ "c"))
#Plot constants
y.max <- 1.5
x.max <- 10
all_missing <- stock_status %>%
dplyr::filter(is.na(B.Bmsy),is.na(F.Fmsy)) %>%
dplyr::select(Code, Council)
b_missing <- stock_status %>%
dplyr::filter(is.na(B.Bmsy), !is.na(F.Fmsy)) %>%
dplyr::select(Code, Council)
f_missing <- stock_status %>%
dplyr::filter(is.na(F.Fmsy), !is.na(B.Bmsy)) %>%
dplyr::select(Code, Council)
#A dataframe that defines custom legend for stocks with unknown status
all.df <- data.frame(text = all_missing$Code,
x = rep(x.max*0.9,length(all_missing$Code)),
y = seq(1.45,0.7, length.out = 12))
b.df <- data.frame(text = b_missing$Code,
x = rep(x.max*0.7,length(b_missing$Code)),
y = seq(1.45,1.30, length.out = 1))
f.df <- data.frame(text = f_missing$Code,
x = rep(x.max*0.5,length(f_missing$Code)),
y = seq(1.45,1, length.out = 7))
#Plotting code
ggplot2::ggplot(data = stock_status) +
ggplot2::geom_vline(xintercept = 1, linetype = "dotted", color = "grey60")+
ggplot2::geom_vline(xintercept = 0.5, linetype = "dashed", color = "grey60")+
ggplot2::geom_hline(yintercept = 1, linetype = "dashed", color = "grey60") +
ggplot2::geom_point(aes(x = B.Bmsy,
y = F.Fmsy,
color = stock_status$score)) +
ggrepel::geom_text_repel(aes(x = B.Bmsy, #geom_text_repel auto-jitters text around points
y = F.Fmsy,
label = Code,
color = stock_status$score), show.legend = FALSE,nudge_y = -0.01, nudge_x = 0.05) +
ggplot2::ylim(0,y.max) +
ggplot2::xlim(0,x.max*1.1) +
ggplot2::geom_text(data = all.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
ggplot2::geom_text(data = b.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
ggplot2::geom_text(data = f.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
ggplot2::scale_color_brewer(palette = "Dark2", #Change legend labels for clarity
breaks = stock_status$score) +
ggplot2::annotate("rect", xmin = 0.924*x.max,
xmax = 1.08*x.max,
ymin = 0.645*y.max,
ymax = 0.98*y.max,
alpha = 0.01) +
ggplot2::annotate("text", x = 9, y = 1.5, label = "F and B missing", fontface =2, size = 3)+
ggplot2::annotate("rect",
xmin = 0.70*x.max,
xmax = 0.85*x.max,
ymin = 0.30*y.max,
ymax = 0.98*y.max,
alpha = 0.01) +
ggplot2::annotate("text", x = 7, y = 1.5, label = "B missing", fontface =2, size = 3)+
ggplot2::annotate("rect", xmin = 0.509*x.max,
xmax = 0.681*x.max,
ymin = 0.65*y.max,
ymax = 0.98*y.max,
alpha = 0.01) +
ggplot2::annotate("text", x = 5, y = 1.5, label = "F missing", fontface =2, size = 3)+
ggplot2::xlab(expression(~B/B[msy])) +
ggplot2::ylab(expression(~F/F[msy])) +
ggplot2::guides(color = FALSE) +
ecodata::theme_ts()
As of January 2023, stockSMART and stocksmart
have been
updated. We should be able to compare the above to what I did below for
the December 2022 deadline.
Used the form here: https://apps-nefsc.fisheries.noaa.gov/saw/sasi/sasi_report_options.php
Files should be up-to-date as of the day of my query, December 6 2022, according to the website.
Checked the boxes: Year–2022
Species with 2022 updates:
American plaice, Atlantic bluefish, Atlantic halibut, Atlantic herring, Atlantic wolffish, Butterfish, Haddock (2 stocks), Monkfish (2 stocks), Ocean Pout, Pollock, Shortfin squid, Spiny dogfish, White hake, Winter flounder (3 stocks), Witch flounder, and Yellowtail flounder (2 stocks)
As of 6 December 2022, none of these appear in StockSMART. Team StockSMART was contacted to see if they have the data and it is just not posted, or if it has not been submitted.
If I don’t hear back, I guess I have to do this by hand.
December 8 update: doing this by hand.
Current dataset (stocksmart only to 2021) species names and necessary columns:
assess <- read.csv(here("2021assess.csv"))
manualupdatenames <- assess %>%
dplyr::group_by(Entity.Name,) %>%
dplyr::filter(Assessment.Year == max(Assessment.Year)) %>%
dplyr::select(Entity.Name) %>%
dplyr::distinct()
print(manualupdatenames, n = 52)
## # A tibble: 52 × 1
## # Groups: Entity.Name [52]
## Entity.Name
## <chr>
## 1 Atlantic mackerel - Gulf of Maine / Cape Hatteras
## 2 Atlantic surfclam - Mid-Atlantic Coast
## 3 Black sea bass - Mid-Atlantic Coast
## 4 Bluefish - Atlantic Coast
## 5 Butterfish - Gulf of Maine / Cape Hatteras
## 6 Longfin inshore squid - Georges Bank / Cape Hatteras
## 7 Northern shortfin squid - Northwestern Atlantic Coast
## 8 Ocean quahog - Atlantic Coast
## 9 Scup - Atlantic Coast
## 10 Summer flounder - Mid-Atlantic Coast
## 11 Tilefish - Mid-Atlantic Coast
## 12 Acadian redfish - Gulf of Maine / Georges Bank
## 13 American plaice - Gulf of Maine / Georges Bank
## 14 Atlantic cod - Eastern Georges Bank
## 15 Atlantic cod - Georges Bank
## 16 Atlantic cod - Gulf of Maine
## 17 Atlantic halibut - Northwestern Atlantic Coast
## 18 Atlantic herring - Northwestern Atlantic Coast
## 19 Atlantic salmon - Gulf of Maine
## 20 Atlantic wolffish - Gulf of Maine / Georges Bank
## 21 Barndoor skate - Georges Bank / Southern New England
## 22 Clearnose skate - Southern New England / Mid-Atlantic
## 23 Haddock - Eastern Georges Bank
## 24 Haddock - Georges Bank
## 25 Haddock - Gulf of Maine
## 26 Little skate - Georges Bank / Southern New England
## 27 Ocean pout - Northwestern Atlantic Coast
## 28 Offshore hake - Northwestern Atlantic Coast
## 29 Pollock - Gulf of Maine / Georges Bank
## 30 Red deepsea crab - Northwestern Atlantic
## 31 Red hake - Gulf of Maine / Northern Georges Bank
## 32 Red hake - Southern Georges Bank / Mid-Atlantic
## 33 Rosette skate - Southern New England / Mid-Atlantic
## 34 Sea scallop - Northwestern Atlantic Coast
## 35 Silver hake - Gulf of Maine / Northern Georges Bank
## 36 Silver hake - Southern Georges Bank / Mid-Atlantic
## 37 Smooth skate - Gulf of Maine
## 38 Thorny skate - Gulf of Maine
## 39 White hake - Gulf of Maine / Georges Bank
## 40 Windowpane - Gulf of Maine / Georges Bank
## 41 Windowpane - Southern New England / Mid-Atlantic
## 42 Winter flounder - Georges Bank
## 43 Winter flounder - Gulf of Maine
## 44 Winter flounder - Southern New England / Mid-Atlantic
## 45 Winter skate - Georges Bank / Southern New England
## 46 Witch flounder - Northwestern Atlantic Coast
## 47 Yellowtail flounder - Cape Cod / Gulf of Maine
## 48 Yellowtail flounder - Georges Bank
## 49 Yellowtail flounder - Southern New England / Mid-Atlantic
## 50 Goosefish - Gulf of Maine / Northern Georges Bank
## 51 Goosefish - Southern Georges Bank / Mid-Atlantic
## 52 Spiny dogfish - Atlantic Coast
names(assess)
## [1] "X" "Entity.Name" "Jurisdiction" "FMP"
## [5] "Science.Center" "Stock.Area" "Assessment.Year" "Last.Data.Year"
## [9] "F.Year" "Estimated.F" "Flimit" "Fmsy"
## [13] "F.Flimit" "F.Fmsy" "Ftarget" "F.Ftarget"
## [17] "B.Year" "Estimated.B" "B.Unit" "Blimit"
## [21] "Bmsy" "B.Blimit" "B.Bmsy"
Add rows updating key columns for individual species in code instead of spreadsheet. Template:
“Entity.Name” “Assessment.Year” “Estimated F” “Fmsy” “F.Fmsy” “Estimated B” “Bmsy” “B.Bmsy”
(calculate F.Fmsy and B.Bmsy from inputs)
# American plaice, American_plaice_Update_2022_10_12_091606.pdf
Aplaice <- data.frame(Entity.Name = "American plaice - Gulf of Maine / Georges Bank",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.045,
Fmsy = 0.41,
`Estimated B` = 18809,
Bmsy = 19051)
#Atlantic bluefish, Bluefish_SAW_SARC_2022_FINAL.pdf
bluefish <- data.frame(Entity.Name = "Bluefish - Atlantic Coast",
Jurisdiction = "MAFMC",
Assessment.Year = 2022, #RT results
`Estimated F` = 0.166,
Fmsy = 0.248,
`Estimated B` = 55344,
Bmsy = 91987)
#Atlantic halibut, Atlantic_halibut_Update_2022_09_02_094235.pdf
Ahalibut <- data.frame(Entity.Name = "Atlantic halibut - Northwestern Atlantic Coast",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = NA,
Fmsy = NA,
`Estimated B` = NA,
Bmsy = NA)
#Atlantic herring, Atlantic_Herring_Unit_Report_23May2022.pdf
Aherring <- data.frame(Entity.Name = "Atlantic herring - Northwestern Atlantic Coast",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.153, #retro adjusted from text not table
Fmsy = 0.5,
`Estimated B` = 39091, #retro adjusted from text not table
Bmsy = 185750)
#Atlantic wolffish, 2022_CAT_UNIT_RPT.pdf
Awolf<- data.frame(Entity.Name = "Atlantic wolffish - Gulf of Maine / Georges Bank",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.004,
Fmsy = 0.192,
`Estimated B` = 690,
Bmsy = 1509)
#Butterfish, 2022_BUT_UNIT_RPT.pdf
butter <- data.frame(Entity.Name = "Butterfish - Gulf of Maine / Cape Hatteras",
Jurisdiction = "MAFMC",
Assessment.Year = 2022.5, # a workaround, stocksmart has RT not MT results
`Estimated F` = 0.191,
Fmsy = 5.60,
`Estimated B` = 66566,
Bmsy = 39436)
#Haddock (2 stocks),
# Haddock Georges_Bank_haddock_Update_2022_10_12_124337.pdf
haddock2 <- data.frame(Entity.Name = "Haddock - Georges Bank",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.137,
Fmsy = 0.25,
`Estimated B` = 79513,
Bmsy = 120580)
# Haddock Gulf_of_Maine_haddock_Update_2022_v3.pdf
haddock3 <- data.frame(Entity.Name = "Haddock - Gulf of Maine",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.375,
Fmsy = 0.338,
`Estimated B` = 16528,
Bmsy = 6123)
#Monkfish (2 stocks), DraftMonkfishReport15August2022b.pdf
monk1 <- data.frame(Entity.Name = "Goosefish - Gulf of Maine / Northern Georges Bank",
Jurisdiction = "NEFMC / MAFMC",
Assessment.Year = 2022,
`Estimated F` = NA,
Fmsy = NA,
`Estimated B` = NA,
Bmsy = NA)
monk2 <- data.frame(Entity.Name = "Goosefish - Southern Georges Bank / Mid-Atlantic",
Jurisdiction = "NEFMC / MAFMC",
Assessment.Year = 2022,
`Estimated F` = NA,
Fmsy = NA,
`Estimated B` = NA,
Bmsy = NA)
#Ocean Pout, 2022_OPT_UNIT_RPT.pdf
opout <- data.frame(Entity.Name = "Ocean pout - Northwestern Atlantic Coast",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.234,
Fmsy = 0.76,
`Estimated B` = 0.263,
Bmsy = 4.94)
#Pollock, 2022_POK_UNIT_RPT_Update_2022_10_11_163300.pdf
pollock <- data.frame(Entity.Name = "Pollock - Gulf of Maine / Georges Bank",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.052, #base model
Fmsy = 0.235, #base model
`Estimated B` = 175573, #base model
Bmsy = 92130) #base model
#Shortfin squid, northern_shortfin_squid_Update_2022_09_13_151413.pdf
illex <- data.frame(Entity.Name = "Northern shortfin squid - Northwestern Atlantic Coast",
Jurisdiction = "MAFMC",
Assessment.Year = 2022,
`Estimated F` = NA,
Fmsy = NA,
`Estimated B` = NA,
Bmsy = NA)
#Spiny dogfish, Spiny_Dogfish_SAW_SARC_2022_FINAL.pdf
dogfish <- data.frame(Entity.Name = "Spiny dogfish - Atlantic Coast",
Jurisdiction = "NEFMC / MAFMC",
Assessment.Year = 2022, #RT results
`Estimated F` = 0.032, #2019 table 4.4
Fmsy = 0.025, #SPR60%
`Estimated B` = 239877, #2019 table 4.4
Bmsy = 370799) #SPR60% thousand pups
#White hake, 2022_HKW_UNIT_REPORT_REV.pdf
whake <- data.frame(Entity.Name = "White hake - Gulf of Maine / Georges Bank",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.104, #retro adjusted from text not table
Fmsy = 0.1605,
`Estimated B` = 19497, #retro adjusted from text not table
Bmsy = 28191)
#Winter flounder (3 stocks),
# Winter flounder Georges_Bank_Winter_Flounder_Update_2022_09_20_revised.pdf
wflounder1 <- data.frame(Entity.Name = "Winter flounder - Georges Bank",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.076, #retro adjusted
Fmsy = 0.452,
`Estimated B` = 4503, #retro adjusted
Bmsy = 7503)
# Winter flounder 2022_FLW_GM_RPT_Report_2022_09_01_124900.pdf
wflounder2 <- data.frame(Entity.Name = "Winter flounder - Gulf of Maine",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.033,
Fmsy = 0.23,
`Estimated B` = 5093,
Bmsy = NA)
# Winter flounder 2022_FLW_SNEMA_RPT.pdf
wflounder3 <- data.frame(Entity.Name = "Winter flounder - Southern New England / Mid-Atlantic",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.061,
Fmsy = 0.265,
`Estimated B` = 3353.2,
Bmsy = 3314)
#Witch flounder, 2022_WIT_UNIT_RPT_10_12_145249.pdf
witch <- data.frame(Entity.Name = "Witch flounder - Northwestern Atlantic Coast",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.039,
Fmsy = NA,
`Estimated B` = 22419,
Bmsy = NA)
#Yellowtail flounder (2 stocks)
# Yell CCGOM 2022_YEL_CCGOM_RPT_Report_2022_11_02_134310.pdf
yelltail1 <- data.frame(Entity.Name = "Yellowtail flounder - Cape Cod / Gulf of Maine",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.1035, #retro adjusted
Fmsy = 0.3204,
`Estimated B` = 3058, #retro adjusted
Bmsy = 3068)
# Yell SNEMA 2022_YEL_SNEMA_RPT_Report_2022_09_11_152630.pdf
yelltail2 <- data.frame(Entity.Name = "Yellowtail flounder - Southern New England / Mid-Atlantic",
Jurisdiction = "NEFMC",
Assessment.Year = 2022,
`Estimated F` = 0.082, #retro adjusted
Fmsy = 0.349,
`Estimated B` = 70, #retro adjusted
Bmsy = 1715)
Bind rows, calculate F.Fmsy and B.Bmsy from inputs, add to assess
As of Dec 9 stocksmart has Atlantic herring, Shortfin squid, Butterfish, and SNEMA Winter flounder results for 2022. Herring, squid, and winter flounder match my entries below, but stockSMART source has the butterish research track results from 2021 rather than the updated management track results from 2022, so I’m subbing in the MT results here as they are used for spec setting.
Note that Spiny Dogfish and Bluefish results here for 2022 are based on the Research Track assessment results, reviewed December 5-9 2022. These are the most up to date stock status, but will not be used for management and will be replaced by management track assessment results in 2023 when those assessments are complete.
update <- dplyr::bind_rows(Ahalibut,
#Aherring,
Aplaice,
Awolf,
bluefish,
butter,
dogfish,
haddock2,
haddock3,
#illex,
monk1,
monk2,
opout,
pollock,
wflounder1,
wflounder2,
#wflounder3,
whake,
witch,
yelltail1,
yelltail2) %>%
dplyr::mutate(F.Fmsy = Estimated.F/Fmsy,
B.Bmsy = Estimated.B/Bmsy)
# assess <- assess %>%
# rename(Estimated.F = `Estimated F`,
# Estimated.B = `Estimated B`)
assessupdate <- dplyr::bind_rows(assess, update) %>%
dplyr::arrange(Jurisdiction, Entity.Name, Assessment.Year)
#write.csv(assessupdate, here("assess.csv"))
stock_status_update <-
assessupdate %>%
dplyr::group_by(Entity.Name) %>%
dplyr::filter(Assessment.Year == max(Assessment.Year)) %>%
#Find last year assessment occurred for each stock
dplyr::ungroup() %>%
dplyr::left_join(.,decode, by = "Entity.Name") %>% #Join in list of managed species
dplyr::select(Entity.Name, Assessment.Year, F.Fmsy, B.Bmsy, Council, Code) %>%
#select column variables to keep
dplyr::mutate(id = 1:length(Entity.Name)) %>%
tidyr::gather(.,Var, Value,-id,-Entity.Name,-Assessment.Year,-Council,-Code) %>%
#wide to long
dplyr::select(-id) %>%
dplyr::rename(`Last assessment` = Assessment.Year,
Stock = Entity.Name) %>% #rename variables for clarity
dplyr::mutate(Units = "unitless")
Try plotting again
stock_status <-
stock_status_update %>%
mutate(Code = recode(Code, "Dogfish" = "Sp. Dogfish" )) %>%
spread(.,Var,Value) %>%
filter(Council %in% c("MAFMC","Both")) %>%
group_by(Stock) %>%
mutate(score = case_when(
(B.Bmsy <0.5) ~"a",
(F.Fmsy >1) ~ "a",
(F.Fmsy < 1 & B.Bmsy > 0.5 & B.Bmsy < 1) ~ "b",
(F.Fmsy < 1 & B.Bmsy > 1) ~ "c"))
#Plot constants
y.max <- 2.1 #2.0 mackerel cut off F/Fmsy is 2.08
x.max <- 2.6
#A dataframe that defines custom legend for stocks with unknown status
# unknown <- data.frame(text = c("Unknown Status", "Longfin Squid",
# "Shortfin Squid", "N. Goosefish", "S. Goosefish"),
# x = rep(0.9*x.max,5), y = seq(0.93*y.max,1.5,-.1))
# Custom Color
custom_color<- c("#56B4E9", "#009E73", "#0072B2")
#Plotting code
ggplot(data = stock_status) +
geom_vline(xintercept = 1, linetype = "dotted")+
geom_vline(xintercept = 0.5, linetype = "dashed")+
geom_hline(yintercept = 1, linetype = "dashed") +
geom_point(aes(x = B.Bmsy,
y = F.Fmsy,
shape = Council,
color = score)) +
geom_text_repel(aes(x = B.Bmsy, #geom_text_repel auto-jitters text around points
y = F.Fmsy,
label = Code,
color = score),
show.legend = FALSE, nudge_y = -0.01, nudge_x = 0.05) +
scale_color_brewer(palette = "Dark2",
breaks = stock_status$score) +
ylim(0,y.max) +
xlim(0,x.max) +
# geom_text(data = unknown, aes(x = x, y = y, label = text), #Custom legend for unknown stock status
# size = c(4.75,rep(4,4))) +
# annotate("rect", xmin = 0.8*x.max,
# xmax = x.max,
# ymin = 0.65*y.max,
# ymax = 0.90*y.max,
# alpha = 0.1) +
xlab(expression(~B/B[msy])) +
ylab(expression(~F/F[msy])) +
guides(color = FALSE) +
theme_ts()
#Get data, spread for plotting, and filter
stock_status <- ecodata::stock_status %>%
dplyr::mutate(Code = recode(Code, "Dogfish" = "Sp. Dogfish" ),
Code = recode(Code, "Mackerel" = "At. Mackerel")) %>%
tidyr::spread(.,Var,Value) %>%
dplyr::filter(Council %in% c("MAFMC","Both")) %>%
dplyr::group_by(Stock) %>%
dplyr::mutate(score = case_when(
(B.Bmsy <0.5) ~"a",
(F.Fmsy >1) ~ "a",
(F.Fmsy < 1 & B.Bmsy > 0.5 & B.Bmsy < 1) ~ "b",
(F.Fmsy < 1 & B.Bmsy > 1) ~ "c"))
#Plot constants
y.max <- 2.1 #1.75 mackerel cut off F/Fmsy is 1.8
x.max <- 2.6
#A dataframe that defines custom legend for stocks with unknown status
unknown <- data.frame(text = c("Unknown Status", "Longfin Squid",
"Shortfin Squid", "N. Goosefish", "S. Goosefish", "Blueline Tilefish", "Chub Mackerel"),
x = rep(0.9*x.max,7), y = seq(0.88*y.max,1.2,-0.1))
# Custom Color
custom_color<- c("#56B4E9", "#009E73", "#0072B2")
#Plotting code
ggplot2::ggplot(data = stock_status) +
ggplot2::geom_vline(xintercept = 1, linetype = "dotted")+
ggplot2::geom_vline(xintercept = 0.5, linetype = "dashed")+
ggplot2::geom_hline(yintercept = 1, linetype = "dashed") +
ggplot2::geom_point(aes(x = B.Bmsy,
y = F.Fmsy,
shape = Council,
color = score)) +
ggrepel::geom_text_repel(aes(x = B.Bmsy, #geom_text_repel auto-jitters text around points
y = F.Fmsy,
label = Code,
color = score),
show.legend = FALSE, nudge_y = -0.01, nudge_x = 0.05) +
ggplot2::scale_color_brewer(palette = "Dark2",
breaks = stock_status$score) +
ggplot2::ylim(0,y.max) +
ggplot2::xlim(0,x.max) +
ggplot2::geom_text(data = unknown, aes(x = x-0.5, y = y+0.2, label = text), #Custom legend for unknown stock status
size = c(4.75,rep(4,6))) +
#ggplot2::annotate("rect", xmin = 0.8*x.max,
# xmax = x.max
# ymin = 0.65*y.max,
# ymax = 0.90*y.max,
# alpha = 0.1) +
ggplot2::xlab(expression(~B/B[msy])) +
ggplot2::ylab(expression(~F/F[msy])) +
ggplot2::guides(color = FALSE) +
ecodata::theme_ts()
stock_status <- stock_status_update %>%
mutate(Code = recode(Code, "Dogfish" = "Sp. Dogfish" )) %>%
spread(.,Var,Value) %>%
filter(Council %in% c("NEFMC","Both")) %>%
group_by(Stock) %>%
mutate(score = case_when(
(B.Bmsy <0.5) ~"a",
(F.Fmsy >1) ~ "a",
(F.Fmsy < 1 & B.Bmsy > 0.5 & B.Bmsy < 1) ~ "b",
(F.Fmsy < 1 & B.Bmsy > 1) ~ "c"))
#Plot constants
y.max <- 1.5
x.max <- 10
all_missing <- stock_status %>%
filter(is.na(B.Bmsy),is.na(F.Fmsy)) %>%
dplyr::select(Code, Council)
b_missing <- stock_status %>%
filter(is.na(B.Bmsy), !is.na(F.Fmsy)) %>%
dplyr::select(Code, Council)
f_missing <- stock_status %>%
filter(is.na(F.Fmsy), !is.na(B.Bmsy)) %>%
dplyr::select(Code, Council)
#A dataframe that defines custom legend for stocks with unknown status
# all.df <- data.frame(text = all_missing$Code,
# x = rep(x.max*0.9,length(all_missing$Code)),
# #y = seq(1.45,1.05, length.out = 7))
# y = seq(1.45,1.05, length.out = length(all_missing$Code)))
# b.df <- data.frame(text = b_missing$Code,
# x = rep(x.max*0.7,length(b_missing$Code)),
# y = c(1.45,2.15, length.out = length(b_missing$Code)))
# f.df <- data.frame(text = f_missing$Code,
# x = rep(x.max*0.5,length(f_missing$Code)),
# y = seq(1.45,1.0, length.out = length(f_missing$Code)))
# Custom Color
custom_color<- c("#56B4E9", "#009E73", "#0072B2")
#Plotting code
ggplot(data = stock_status) +
geom_vline(xintercept = 1, linetype = "dotted", color = "grey60")+
geom_vline(xintercept = 0.5, linetype = "dashed", color = "grey60")+
geom_hline(yintercept = 1, linetype = "dashed", color = "grey60") +
geom_point(aes(x = B.Bmsy,
y = F.Fmsy,
color = stock_status$score)) +
geom_text_repel(aes(x = B.Bmsy, #geom_text_repel auto-jitters text around points
y = F.Fmsy,
label = Code,
color = stock_status$score), show.legend = FALSE,nudge_y = -0.01, nudge_x = 0.05) +
ylim(0,y.max) +
xlim(0,x.max*1.1) +
# geom_text(data = all.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
# geom_text(data = b.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
# geom_text(data = f.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
# scale_color_brewer(palette = "Dark2", #Change legend labels for clarity
# breaks = stock_status$score) +
# annotate("rect", xmin = 0.924*x.max,
# xmax = 1.08*x.max,
# ymin = 0.645*y.max,
# ymax = 0.98*y.max,
# alpha = 0.01) +
# annotate("text", x = 9, y = 1.5, label = "F and B missing", fontface =2, size = 3)+
# annotate("rect",
# xmin = 0.70*x.max,
# xmax = 0.85*x.max,
# ymin = 0.90*y.max,
# ymax = 1.8,
# alpha = 0.01) +
# annotate("text", x = 7, y = 1.5, label = "B missing", fontface =2, size = 3)+
# annotate("rect", xmin = 0.509*x.max,
# xmax = 0.681*x.max,
# ymin = 0.65*y.max,
# ymax = 0.98*y.max,
# alpha = 0.01) +
# annotate("text", x = 5, y = 1.5, label = "F missing", fontface =2, size = 3)+
xlab(expression(~B/B[msy])) +
ylab(expression(~F/F[msy])) +
guides(color = FALSE) +
theme_ts()
#Get data, spread for plotting, and filter
stock_status <- ecodata::stock_status %>%
dplyr::mutate(Code = dplyr::recode(Code, "Dogfish" = "Sp. Dogfish" )) %>%
tidyr::spread(.,Var,Value) %>%
dplyr::filter(Council %in% c("NEFMC","Both")) %>%
dplyr::group_by(Stock) %>%
dplyr::mutate(score = case_when(
(B.Bmsy <0.5) ~"a",
(F.Fmsy >1) ~ "a",
(F.Fmsy < 1 & B.Bmsy > 0.5 & B.Bmsy < 1) ~ "b",
(F.Fmsy < 1 & B.Bmsy > 1) ~ "c"))
#Plot constants
y.max <- 1.5
x.max <- 10
all_missing <- stock_status %>%
dplyr::filter(is.na(B.Bmsy),is.na(F.Fmsy)) %>%
dplyr::select(Code, Council)
b_missing <- stock_status %>%
dplyr::filter(is.na(B.Bmsy), !is.na(F.Fmsy)) %>%
dplyr::select(Code, Council)
f_missing <- stock_status %>%
dplyr::filter(is.na(F.Fmsy), !is.na(B.Bmsy)) %>%
dplyr::select(Code, Council)
#A dataframe that defines custom legend for stocks with unknown status
all.df <- data.frame(text = all_missing$Code,
x = rep(x.max*0.9,length(all_missing$Code)),
y = seq(1.45,0.7, length.out = 12))
b.df <- data.frame(text = b_missing$Code,
x = rep(x.max*0.7,length(b_missing$Code)),
y = seq(1.45,1.30, length.out = 1))
f.df <- data.frame(text = f_missing$Code,
x = rep(x.max*0.5,length(f_missing$Code)),
y = seq(1.45,1, length.out = 7))
#Plotting code
ggplot2::ggplot(data = stock_status) +
ggplot2::geom_vline(xintercept = 1, linetype = "dotted", color = "grey60")+
ggplot2::geom_vline(xintercept = 0.5, linetype = "dashed", color = "grey60")+
ggplot2::geom_hline(yintercept = 1, linetype = "dashed", color = "grey60") +
ggplot2::geom_point(aes(x = B.Bmsy,
y = F.Fmsy,
color = stock_status$score)) +
ggrepel::geom_text_repel(aes(x = B.Bmsy, #geom_text_repel auto-jitters text around points
y = F.Fmsy,
label = Code,
color = stock_status$score), show.legend = FALSE,nudge_y = -0.01, nudge_x = 0.05) +
ggplot2::ylim(0,y.max) +
ggplot2::xlim(0,x.max*1.1) +
ggplot2::geom_text(data = all.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
ggplot2::geom_text(data = b.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
ggplot2::geom_text(data = f.df, aes(x = x, y = y, label = text),show.legend = FALSE, size = 3)+
ggplot2::scale_color_brewer(palette = "Dark2", #Change legend labels for clarity
breaks = stock_status$score) +
ggplot2::annotate("rect", xmin = 0.924*x.max,
xmax = 1.08*x.max,
ymin = 0.645*y.max,
ymax = 0.98*y.max,
alpha = 0.01) +
ggplot2::annotate("text", x = 9, y = 1.5, label = "F and B missing", fontface =2, size = 3)+
ggplot2::annotate("rect",
xmin = 0.70*x.max,
xmax = 0.85*x.max,
ymin = 0.30*y.max,
ymax = 0.98*y.max,
alpha = 0.01) +
ggplot2::annotate("text", x = 7, y = 1.5, label = "B missing", fontface =2, size = 3)+
ggplot2::annotate("rect", xmin = 0.509*x.max,
xmax = 0.681*x.max,
ymin = 0.65*y.max,
ymax = 0.98*y.max,
alpha = 0.01) +
ggplot2::annotate("text", x = 5, y = 1.5, label = "F missing", fontface =2, size = 3)+
ggplot2::xlab(expression(~B/B[msy])) +
ggplot2::ylab(expression(~F/F[msy])) +
ggplot2::guides(color = FALSE) +
ecodata::theme_ts()