From 57cdbbca1f684635cac5a41c54c6ceeb7085fe93 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Fri, 20 Mar 2026 15:03:28 -0400 Subject: [PATCH 01/28] add area for condition when r4ss output object is input --- R/convert_output.R | 2062 ++++++++++++++++++++++---------------------- 1 file changed, 1035 insertions(+), 1027 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index ba3d1283..ae201bf8 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -162,1099 +162,1107 @@ convert_output <- function( #### SS3 #### # Convert SS3 output Report.sso file if (tolower(model) == "ss3") { - # read SS3 report file - dat <- utils::read.table( - file = file, - col.names = 1:get_ncol(file), - fill = TRUE, - quote = "", - colClasses = "character", # reads all data as characters - nrows = -1, - comment.char = "", - blank.lines.skip = FALSE - ) - # Check SS3 model version - vers <- stringr::str_extract(dat[1, 1], "[0-9].[0-9][0-9].[0-9][0-9]") # .[0-9] - if (vers < 3.3) { - cli::cli_abort("This function in its current state can not process the data.") - } - - # Extract fleet names - if (is.null(fleet_names)) { - fleet_names <- SS3_extract_fleet(dat, vers) - } - # Output fleet names in console - cli::cli_alert_info("Identified fleet names:") - cli::cli_alert_info("{fleet_names}") - - # Extract units - - - # Estimated and focal parameters to put into reformatted output df - naming conventions from SS3 - # Extract keywords from ss3 file - # Find row where keywords start - keywords_start_row <- which(apply(dat, 1, function(row) any(grepl("#_KeyWords_of_tables_available_in_report_sso", row)))) - # Extract this first chunk of keywords to identify the first reported df - most likely DEFINITIONS - first_blank_after <- which(apply(dat, 1, function(row) all(is.na(row) | row == "")) & (seq_len(nrow(dat)) > keywords_start_row))[1] - rows <- c(keywords_start_row, first_blank_after) - # Extract the metric using the rows from above as a guide and clean up empty columns - keyword_1 <- dat[rows[1]:(rows[2] - 1), ] |> - naniar::replace_with_na_all(condition = ~ .x == "") - keyword_1 <- Filter(function(x) !all(is.na(x)), keyword_1)[-c(1:3), ] - colnames(keyword_1) <- c("output", "keyword", "output_order") - keyword_1 <- keyword_1 |> - dplyr::mutate(output_order = as.numeric(stringr::str_extract(output_order, "\\d+$"))) |> - dplyr::filter(output_order == 1) |> - dplyr::pull(keyword) - # identify first reported keyword - keywords_end_row <- which(apply(dat, 1, function(row) any(grepl(keyword_1, row))))[2] - 12 # 12 rows behind is the last entry for keywords - # always extract the second entry bc the first is just in the list of keywords - - keywords <- dat[keywords_start_row:keywords_end_row, ][-c(1:3), c(1:3)] |> - naniar::replace_with_na_all(condition = ~ .x == "") - keywords <- Filter(function(x) !all(is.na(x)), keywords) - colnames(keywords) <- c("output", "keyword", "output_order") - param_names <- keywords |> - dplyr::mutate(output_order = as.numeric(stringr::str_extract(output_order, "\\d+$"))) |> - dplyr::filter(output == "Y") |> - dplyr::pull(keyword) - - # Group parameters base on table pattern - std <- c( - "DERIVED_QUANTITIES", - "MGparm_By_Year_after_adjustments", - "CATCH", - "SPAWN_RECRUIT", - "TIME_SERIES", - "DISCARD_OUTPUT", - "INDEX_2", - "FIT_LEN_COMPS", - "FIT_AGE_COMPS", - "FIT_SIZE_COMPS", - "SELEX_database", - "Growth_Parameters", - "Kobe_Plot" - ) - std2 <- c("OVERALL_COMPS") - cha <- c("Dynamic_Bzero") - rand <- c( - "Input_Variance_Adjustment", - "SPR_SERIES", - "selparm(Size)_By_Year_after_adjustments", - "selparm(Age)_By_Year_after_adjustments", - "BIOLOGY", - "SPR/YPR_Profile", - "Biology_at_age_in_endyr", - "SPAWN_RECR_CURVE", - "PARAMETERS" - ) - info <- c( - "LIKELIHOOD", - "DEFINITIONS" - ) - aa.al <- c( - "BIOMASS_AT_AGE", - "BIOMASS_AT_LENGTH", - "DISCARD_AT_AGE", - "CATCH_AT_AGE", - "F_AT_AGE", - "MEAN_SIZE_TIMESERIES", - "NUMBERS_AT_AGE", - "NUMBERS_AT_LENGTH", - "AGE_SELEX", - "LEN_SELEX", - "MEAN_BODY_WT(Begin)", - "Natural_Mortality" - ) - nn <- c( - "MORPH_INDEXING", - "EXPLOITATION", - "DISCARD_SPECIFICATION", - "INDEX_1", - "MEAN_BODY_WT_OUTPUT" - ) - - # Loop for all identified parameters to extract for plotting and use - # Create list of parameters that were not found in the output file - # 1,4,10,17,19,20,22,32,37 - factors <- c( - "era", "year", "fleet", - "fleet_name", "age", "sex", - "area", "seas", "season", - "time", "era", "subseas", - "subseason", "platoon", "platoo", - "growth_pattern", "gp", "month", - "like", "morph", "bio_pattern", - "settlement", "birthseas", "count", - "kind" - ) - - errors <- c( - "StdDev", "sd", "std", "stddev", - "se", "SE", - "cv", "CV" - ) - - miss_parms <- c() - out_list <- list() - #### SS3 loop #### - for (i in seq_along(param_names)) { - # Processing data frame - parm_sel <- param_names[i] - if (parm_sel %in% c(std, std2, cha, rand, aa.al)) { - cli::cli_alert(glue::glue("Processing {parm_sel}")) - extract <- SS3_extract_df(dat, parm_sel) - if (!is.data.frame(extract)) { - miss_parms <- c(miss_parms, parm_sel) - cli::cli_alert(glue::glue("Skipped {parm_sel}")) - next - } else { - ##### STD #### - # 1,4,10,17,19,36 - if (parm_sel %in% std) { - # remove first row - naming - df1 <- extract[-1, ] - # Find first row without NAs = headers - # temp fix for catch df - I have only seen this issue for Hake example - if (any(is.na(df1[1, ])) & parm_sel == "CATCH") { - df1 <- df1[-1, ] - cols_to_keep <- which(sapply(df1, function(x) !all(is.na(x)))) - df1 <- df1 |> dplyr::select(dplyr::all_of(c(names(cols_to_keep)))) - df2 <- df1 - } else { - df2 <- df1[stats::complete.cases(df1), ] - } - if (any(c("#") %in% df2[, 1])) { - full_row <- which(apply(df1, 1, function(row) is.na(row) | row == " " | row == "-" | row == "#"))[1] - df1 <- df1[-full_row[1], ] - df1 <- Filter(function(x) !all(is.na(x)), df1) - df2 <- df1[stats::complete.cases(df1), ] - } - # identify first row - row <- df2[1, ] - # find row number that matches 'row' - rownum <- prodlim::row.match(as.vector(row), df1) - # make row the header names for first df - colnames(df1) <- row - # Subset data frame - df3 <- df1[-c(1:rownum), ] - colnames(df3) <- tolower(row) - # Remove any leftover NA columns if still present - NA_cols <- which(sapply(df3, function(x) all(is.na(x)))) - if (length(NA_cols) > 0) df3 <- df3[, -NA_cols] - # Remove suprper + use from df - if (any(grepl("suprper|use", colnames(df3)))) { - df3 <- df3 |> - dplyr::select(-tidyselect::any_of(c("suprper", "use"))) - } - # Reformat data frame - if (any(colnames(df3) %in% c("Yr", "yr"))) { - df3 <- df3 |> - dplyr::rename(year = yr) - } - if ("label" %in% colnames(df3)) { - if (any(grepl("_[0-9]+$", df3$label))) { - df4 <- df3 |> - dplyr::mutate( - year = stringr::str_extract(label, "[0-9]+$"), - label = stringr::str_remove(label, "_[0-9]+$"), - # Add factors consistent with other else - area = NA, - sex = NA, - growth_pattern = NA, - fleet = NA - ) # need to remove the multiple error one + if (is.character(file)) { + # report.sso file + # read SS3 report file + dat <- utils::read.table( + file = file, + col.names = 1:get_ncol(file), + fill = TRUE, + quote = "", + colClasses = "character", # reads all data as characters + nrows = -1, + comment.char = "", + blank.lines.skip = FALSE + ) + # Check SS3 model version + vers <- stringr::str_extract(dat[1, 1], "[0-9].[0-9][0-9].[0-9][0-9]") # .[0-9] + if (vers < 3.3) { + cli::cli_abort("This function in its current state can not process the data.") + } + + # Extract fleet names + if (is.null(fleet_names)) { + fleet_names <- SS3_extract_fleet(dat, vers) + } + # Output fleet names in console + cli::cli_alert_info("Identified fleet names:") + cli::cli_alert_info("{fleet_names}") + + # Extract units + + + # Estimated and focal parameters to put into reformatted output df - naming conventions from SS3 + # Extract keywords from ss3 file + # Find row where keywords start + keywords_start_row <- which(apply(dat, 1, function(row) any(grepl("#_KeyWords_of_tables_available_in_report_sso", row)))) + # Extract this first chunk of keywords to identify the first reported df - most likely DEFINITIONS + first_blank_after <- which(apply(dat, 1, function(row) all(is.na(row) | row == "")) & (seq_len(nrow(dat)) > keywords_start_row))[1] + rows <- c(keywords_start_row, first_blank_after) + # Extract the metric using the rows from above as a guide and clean up empty columns + keyword_1 <- dat[rows[1]:(rows[2] - 1), ] |> + naniar::replace_with_na_all(condition = ~ .x == "") + keyword_1 <- Filter(function(x) !all(is.na(x)), keyword_1)[-c(1:3), ] + colnames(keyword_1) <- c("output", "keyword", "output_order") + keyword_1 <- keyword_1 |> + dplyr::mutate(output_order = as.numeric(stringr::str_extract(output_order, "\\d+$"))) |> + dplyr::filter(output_order == 1) |> + dplyr::pull(keyword) + # identify first reported keyword + keywords_end_row <- which(apply(dat, 1, function(row) any(grepl(keyword_1, row))))[2] - 12 # 12 rows behind is the last entry for keywords + # always extract the second entry bc the first is just in the list of keywords + + keywords <- dat[keywords_start_row:keywords_end_row, ][-c(1:3), c(1:3)] |> + naniar::replace_with_na_all(condition = ~ .x == "") + keywords <- Filter(function(x) !all(is.na(x)), keywords) + colnames(keywords) <- c("output", "keyword", "output_order") + param_names <- keywords |> + dplyr::mutate(output_order = as.numeric(stringr::str_extract(output_order, "\\d+$"))) |> + dplyr::filter(output == "Y") |> + dplyr::pull(keyword) + + # Group parameters base on table pattern + std <- c( + "DERIVED_QUANTITIES", + "MGparm_By_Year_after_adjustments", + "CATCH", + "SPAWN_RECRUIT", + "TIME_SERIES", + "DISCARD_OUTPUT", + "INDEX_2", + "FIT_LEN_COMPS", + "FIT_AGE_COMPS", + "FIT_SIZE_COMPS", + "SELEX_database", + "Growth_Parameters", + "Kobe_Plot" + ) + std2 <- c("OVERALL_COMPS") + cha <- c("Dynamic_Bzero") + rand <- c( + "Input_Variance_Adjustment", + "SPR_SERIES", + "selparm(Size)_By_Year_after_adjustments", + "selparm(Age)_By_Year_after_adjustments", + "BIOLOGY", + "SPR/YPR_Profile", + "Biology_at_age_in_endyr", + "SPAWN_RECR_CURVE", + "PARAMETERS" + ) + info <- c( + "LIKELIHOOD", + "DEFINITIONS" + ) + aa.al <- c( + "BIOMASS_AT_AGE", + "BIOMASS_AT_LENGTH", + "DISCARD_AT_AGE", + "CATCH_AT_AGE", + "F_AT_AGE", + "MEAN_SIZE_TIMESERIES", + "NUMBERS_AT_AGE", + "NUMBERS_AT_LENGTH", + "AGE_SELEX", + "LEN_SELEX", + "MEAN_BODY_WT(Begin)", + "Natural_Mortality" + ) + nn <- c( + "MORPH_INDEXING", + "EXPLOITATION", + "DISCARD_SPECIFICATION", + "INDEX_1", + "MEAN_BODY_WT_OUTPUT" + ) + + # Loop for all identified parameters to extract for plotting and use + # Create list of parameters that were not found in the output file + # 1,4,10,17,19,20,22,32,37 + factors <- c( + "era", "year", "fleet", + "fleet_name", "age", "sex", + "area", "seas", "season", + "time", "era", "subseas", + "subseason", "platoon", "platoo", + "growth_pattern", "gp", "month", + "like", "morph", "bio_pattern", + "settlement", "birthseas", "count", + "kind" + ) + + errors <- c( + "StdDev", "sd", "std", "stddev", + "se", "SE", + "cv", "CV" + ) + + miss_parms <- c() + out_list <- list() + #### SS3 loop #### + for (i in seq_along(param_names)) { + # Processing data frame + parm_sel <- param_names[i] + if (parm_sel %in% c(std, std2, cha, rand, aa.al)) { + cli::cli_alert(glue::glue("Processing {parm_sel}")) + extract <- SS3_extract_df(dat, parm_sel) + if (!is.data.frame(extract)) { + miss_parms <- c(miss_parms, parm_sel) + cli::cli_alert(glue::glue("Skipped {parm_sel}")) + next + } else { + ##### STD #### + # 1,4,10,17,19,36 + if (parm_sel %in% std) { + # remove first row - naming + df1 <- extract[-1, ] + # Find first row without NAs = headers + # temp fix for catch df - I have only seen this issue for Hake example + if (any(is.na(df1[1, ])) & parm_sel == "CATCH") { + df1 <- df1[-1, ] + cols_to_keep <- which(sapply(df1, function(x) !all(is.na(x)))) + df1 <- df1 |> dplyr::select(dplyr::all_of(c(names(cols_to_keep)))) + df2 <- df1 + } else { + df2 <- df1[stats::complete.cases(df1), ] } - } else if (any(colnames(df3) %in% c(factors, errors))) { - # Keeping check here if case arises that there is a similar situation to the error - # aka there are multiple columns containing the string and they are not selected properly - - if ("sexes" %in% colnames(df3)) { + if (any(c("#") %in% df2[, 1])) { + full_row <- which(apply(df1, 1, function(row) is.na(row) | row == " " | row == "-" | row == "#"))[1] + df1 <- df1[-full_row[1], ] + df1 <- Filter(function(x) !all(is.na(x)), df1) + df2 <- df1[stats::complete.cases(df1), ] + } + # identify first row + row <- df2[1, ] + # find row number that matches 'row' + rownum <- prodlim::row.match(as.vector(row), df1) + # make row the header names for first df + colnames(df1) <- row + # Subset data frame + df3 <- df1[-c(1:rownum), ] + colnames(df3) <- tolower(row) + # Remove any leftover NA columns if still present + NA_cols <- which(sapply(df3, function(x) all(is.na(x)))) + if (length(NA_cols) > 0) df3 <- df3[, -NA_cols] + # Remove suprper + use from df + if (any(grepl("suprper|use", colnames(df3)))) { df3 <- df3 |> - # add in case if sexes is present and add sex as na if so - dplyr::mutate( - sex = dplyr::case_when( - any(grepl("^sexes$", colnames(df3))) ~ sexes, - TRUE ~ NA - ) - ) |> - dplyr::select(-sexes) - } else { - df3 <- dplyr::mutate(df3, sex = NA) + dplyr::select(-tidyselect::any_of(c("suprper", "use"))) } - - df4 <- df3 |> - tidyr::pivot_longer( - !tidyselect::any_of(c(factors, errors)), - names_to = "label", - values_to = "estimate" - ) |> # , colnames(dplyr::select(df3, tidyselect::matches(errors))) - dplyr::mutate( - fleet = if ("fleet" %notin% colnames(df3)) { - dplyr::case_when( - # "fleet" %in% colnames(.data) ~ fleet, - grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), - TRUE ~ NA - ) - } else if ("fleet_name" %in% colnames(df3)) { - fleet_name - } else { - fleet - }, - area = if ("area" %notin% colnames(df3)) { - dplyr::case_when( - grepl("?_area_[0-9]_?", label) ~ stringr::str_extract(label, "(?<=area_)[0-9]+"), - grepl("_[0-9]_", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), - TRUE ~ NA - ) - } else { - area - }, - sex = if ("sex" %notin% colnames(df3)) { - dplyr::case_when( - grepl("_fem_", label) ~ "female", - grepl("_mal_", label) ~ "male", - grepl("_sx:1$", label) ~ "female", - grepl("_sx:2$", label) ~ "male", - grepl("_sx:1_", label) ~ "female", - grepl("_sx:2_", label) ~ "male", - TRUE ~ NA - ) - } else { - dplyr::case_when( - sex == 1 ~ "female", - sex == 2 ~ "male", - sex == 3 ~ "both", - TRUE ~ sex - ) - }, - growth_pattern = dplyr::case_when( - grepl("_gp_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - grepl("_gp:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), - grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), - TRUE ~ NA - ), - month = dplyr::case_when( - grepl("_month_[0-9]+$", label) ~ stringr::str_extract(label, "(?<=month_)[0-9]+$"), - TRUE ~ ifelse(any(grepl("^month$", colnames(df3))), month, NA) # this might remove month - ) - ) - - # if ("fleet" %in% colnames(df3)) { - # df4 <- df4 |> - # dplyr::mutate( - # fleet = dplyr::case_when( - # "fleet" %in% colnames(df3) ~ fleet, - # # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - # # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), - # TRUE ~ NA - # ), - # label = stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") - # ) - # } else { - df4 <- df4 |> - dplyr::mutate( - # fleet = dplyr::case_when( - # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), - # TRUE ~ NA - # ), - label = dplyr::case_when( - grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), - grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), - TRUE ~ stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") - ) - ) - # } - } else { - cli::cli_alert_warning(glue::glue("Data frame not compatible in {parm_sel}.")) - } - if (any(colnames(df4) %in% c("value"))) df4 <- dplyr::rename(df4, estimate = value) - - # Check if error values are in the labels column and extract out - if (any(sapply(paste0("(^|[_.])", errors, "($|[_.])"), function(x) grepl(x, unique(df4$label))))) { - err_names <- unique(df4$label)[grepl(paste(paste0("(^|[_.])", errors, "($|[_.])"), collapse = "|"), unique(df4$label)) & !unique(df4$label) %in% errors] - if (any(grepl("sel", err_names))) { - df4 <- df4 - } else if (length(intersect(errors, colnames(df4))) == 1) { - df4 <- df4[-grep(paste(errors, "_", collapse = "|", sep = ""), df4$label), ] - } else if (parm_sel == "MGparm_By_Year_after_adjustments") { # this is too specific - df4 <- df4 - cli::cli_alert_info("Error values are present, but are unique to the data frame and not to a selected parameter.") - } else { - df4 <- df4 |> - tidyr::pivot_wider( - names_from = label, - values_from = estimate, - id_cols = c(intersect(colnames(df4), factors)), - values_fill = NA - ) |> + # Reformat data frame + if (any(colnames(df3) %in% c("Yr", "yr"))) { + df3 <- df3 |> + dplyr::rename(year = yr) + } + if ("label" %in% colnames(df3)) { + if (any(grepl("_[0-9]+$", df3$label))) { + df4 <- df3 |> + dplyr::mutate( + year = stringr::str_extract(label, "[0-9]+$"), + label = stringr::str_remove(label, "_[0-9]+$"), + # Add factors consistent with other else + area = NA, + sex = NA, + growth_pattern = NA, + fleet = NA + ) # need to remove the multiple error one + } + } else if (any(colnames(df3) %in% c(factors, errors))) { + # Keeping check here if case arises that there is a similar situation to the error + # aka there are multiple columns containing the string and they are not selected properly + + if ("sexes" %in% colnames(df3)) { + df3 <- df3 |> + # add in case if sexes is present and add sex as na if so + dplyr::mutate( + sex = dplyr::case_when( + any(grepl("^sexes$", colnames(df3))) ~ sexes, + TRUE ~ NA + ) + ) |> + dplyr::select(-sexes) + } else { + df3 <- dplyr::mutate(df3, sex = NA) + } + + df4 <- df3 |> tidyr::pivot_longer( - cols = -c(intersect(colnames(df4), factors), err_names), + !tidyselect::any_of(c(factors, errors)), names_to = "label", values_to = "estimate" - ) |> - dplyr::select(tidyselect::any_of(c("label", "estimate", factors, errors, err_names))) - if (length(err_names) > 1) { - # warning("There are multiple reported error metrics.") - if (any(grepl(paste(err_names, collapse = "|"), colnames(df4)))) { - df4 <- df4 |> - dplyr::select(-tidyselect::all_of(err_names[2:length(err_names)])) - cli::cli_alert_info( - glue::glue("Multiple error metrics reported in {parm_sel}.") + ) |> # , colnames(dplyr::select(df3, tidyselect::matches(errors))) + dplyr::mutate( + fleet = if ("fleet" %notin% colnames(df3)) { + dplyr::case_when( + # "fleet" %in% colnames(.data) ~ fleet, + grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), + TRUE ~ NA + ) + } else if ("fleet_name" %in% colnames(df3)) { + fleet_name + } else { + fleet + }, + area = if ("area" %notin% colnames(df3)) { + dplyr::case_when( + grepl("?_area_[0-9]_?", label) ~ stringr::str_extract(label, "(?<=area_)[0-9]+"), + grepl("_[0-9]_", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), + TRUE ~ NA + ) + } else { + area + }, + sex = if ("sex" %notin% colnames(df3)) { + dplyr::case_when( + grepl("_fem_", label) ~ "female", + grepl("_mal_", label) ~ "male", + grepl("_sx:1$", label) ~ "female", + grepl("_sx:2$", label) ~ "male", + grepl("_sx:1_", label) ~ "female", + grepl("_sx:2_", label) ~ "male", + TRUE ~ NA + ) + } else { + dplyr::case_when( + sex == 1 ~ "female", + sex == 2 ~ "male", + sex == 3 ~ "both", + TRUE ~ sex + ) + }, + growth_pattern = dplyr::case_when( + grepl("_gp_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + grepl("_gp:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), + grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), + TRUE ~ NA + ), + month = dplyr::case_when( + grepl("_month_[0-9]+$", label) ~ stringr::str_extract(label, "(?<=month_)[0-9]+$"), + TRUE ~ ifelse(any(grepl("^month$", colnames(df3))), month, NA) # this might remove month ) - cli::cli_alert_info( - glue::glue("Error label(s) removed: \n {paste(err_names[-1], sep = '\n')}") + ) + + # if ("fleet" %in% colnames(df3)) { + # df4 <- df4 |> + # dplyr::mutate( + # fleet = dplyr::case_when( + # "fleet" %in% colnames(df3) ~ fleet, + # # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + # # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), + # TRUE ~ NA + # ), + # label = stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") + # ) + # } else { + df4 <- df4 |> + dplyr::mutate( + # fleet = dplyr::case_when( + # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), + # TRUE ~ NA + # ), + label = dplyr::case_when( + grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), + grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), + TRUE ~ stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") ) - } else { - df4 <- df4 |> - dplyr::filter(!(label %in% err_names[2:length(err_names)])) - } - # Find overlapping error values if still present - find_error_value <- function(column_names, to_match_vector) { - vals <- vapply(column_names, function(col_name) { - match <- vapply(to_match_vector, function(err) { - pattern <- paste0("(^|[_.])", err, "($|[_.])") - if (grepl(pattern, col_name)) err else NA_character_ + ) + # } + } else { + cli::cli_alert_warning(glue::glue("Data frame not compatible in {parm_sel}.")) + } + if (any(colnames(df4) %in% c("value"))) df4 <- dplyr::rename(df4, estimate = value) + + # Check if error values are in the labels column and extract out + if (any(sapply(paste0("(^|[_.])", errors, "($|[_.])"), function(x) grepl(x, unique(df4$label))))) { + err_names <- unique(df4$label)[grepl(paste(paste0("(^|[_.])", errors, "($|[_.])"), collapse = "|"), unique(df4$label)) & !unique(df4$label) %in% errors] + if (any(grepl("sel", err_names))) { + df4 <- df4 + } else if (length(intersect(errors, colnames(df4))) == 1) { + df4 <- df4[-grep(paste(errors, "_", collapse = "|", sep = ""), df4$label), ] + } else if (parm_sel == "MGparm_By_Year_after_adjustments") { # this is too specific + df4 <- df4 + cli::cli_alert_info("Error values are present, but are unique to the data frame and not to a selected parameter.") + } else { + df4 <- df4 |> + tidyr::pivot_wider( + names_from = label, + values_from = estimate, + id_cols = c(intersect(colnames(df4), factors)), + values_fill = NA + ) |> + tidyr::pivot_longer( + cols = -c(intersect(colnames(df4), factors), err_names), + names_to = "label", + values_to = "estimate" + ) |> + dplyr::select(tidyselect::any_of(c("label", "estimate", factors, errors, err_names))) + if (length(err_names) > 1) { + # warning("There are multiple reported error metrics.") + if (any(grepl(paste(err_names, collapse = "|"), colnames(df4)))) { + df4 <- df4 |> + dplyr::select(-tidyselect::all_of(err_names[2:length(err_names)])) + cli::cli_alert_info( + glue::glue("Multiple error metrics reported in {parm_sel}.") + ) + cli::cli_alert_info( + glue::glue("Error label(s) removed: \n {paste(err_names[-1], sep = '\n')}") + ) + } else { + df4 <- df4 |> + dplyr::filter(!(label %in% err_names[2:length(err_names)])) + } + # Find overlapping error values if still present + find_error_value <- function(column_names, to_match_vector) { + vals <- vapply(column_names, function(col_name) { + match <- vapply(to_match_vector, function(err) { + pattern <- paste0("(^|[_.])", err, "($|[_.])") + if (grepl(pattern, col_name)) err else NA_character_ + }, FUN.VALUE = character(1)) + stats::na.omit(match)[1] }, FUN.VALUE = character(1)) - stats::na.omit(match)[1] - }, FUN.VALUE = character(1)) - # } - # only unique values and those that intersect with values vector - intersect(unique(vals), to_match_vector) - } - # SS: I am not entirely sure what this step is doing, but is a good check - if (any(grepl(paste(err_names, collapse = "|"), colnames(df4)))) { - err_name <- find_error_value(names(df4), errors) - if (length(err_name) > 1) { - err_name <- stringr::str_extract(err_names[1], paste(errors, collapse = "|")) - # cli::cli_alert_info( - # glue::glue("Multiple error metrics reported in {parm_sel}. Error label(s) removed: {err_names[-1]}" - # ) - # ) + # } + # only unique values and those that intersect with values vector + intersect(unique(vals), to_match_vector) + } + # SS: I am not entirely sure what this step is doing, but is a good check + if (any(grepl(paste(err_names, collapse = "|"), colnames(df4)))) { + err_name <- find_error_value(names(df4), errors) + if (length(err_name) > 1) { + err_name <- stringr::str_extract(err_names[1], paste(errors, collapse = "|")) + # cli::cli_alert_info( + # glue::glue("Multiple error metrics reported in {parm_sel}. Error label(s) removed: {err_names[-1]}" + # ) + # ) + } + colnames(df4)[grepl(err_name, colnames(df4))] <- err_name + } else { + err_name <- find_error_value(unique(df4$label), errors) + colnames(df4)[grepl(paste(errors, collapse = "|"), colnames(df4))] <- err_name } - colnames(df4)[grepl(err_name, colnames(df4))] <- err_name - } else { - err_name <- find_error_value(unique(df4$label), errors) - colnames(df4)[grepl(paste(errors, collapse = "|"), colnames(df4))] <- err_name } } } - } - - df5 <- df4 |> - dplyr::select(tidyselect::any_of(c("label", "estimate", "year", factors, errors))) |> - dplyr::mutate( - module_name = parm_sel, - label = dplyr::case_when( - label == "f" ~ "fishing_mortality", - TRUE ~ label - ), - estimate = dplyr::if_else( - grepl("-|_", estimate), - NA, - estimate - ) - ) - - if (any(colnames(df5) %in% errors)) { - df5 <- df5 |> - dplyr::mutate(uncertainty_label = intersect(names(df5), errors)) |> - dplyr::rename(uncertainty = intersect(colnames(df5), errors)) - colnames(df5) <- tolower(names(df5)) - } else { - df5 <- df5 |> + + df5 <- df4 |> + dplyr::select(tidyselect::any_of(c("label", "estimate", "year", factors, errors))) |> dplyr::mutate( - uncertainty_label = NA, - uncertainty = NA + module_name = parm_sel, + label = dplyr::case_when( + label == "f" ~ "fishing_mortality", + TRUE ~ label + ) ) - colnames(df5) <- tolower(names(df5)) - } - - if ("seas" %in% colnames(df5)) df5 <- dplyr::rename(df5, season = seas) - - if ("subseas" %in% colnames(df5)) df5 <- dplyr::rename(df5, subseason = subseas) - - if ("like" %in% colnames(df5)) df5 <- dplyr::rename(df5, likelihood = like) - - df5[setdiff(tolower(names(out_new)), tolower(names(df5)))] <- NA - if (ncol(out_new) < ncol(df5)) { - diff <- setdiff(names(df5), names(out_new)) - cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) - # warning(parm_sel, " has more columns than the output data frame. The column(s) ", paste(diff, collapse = ", ")," are not found in the standard file. It was excluded from the resulting output. Please open an issue for developer fix.") - df5 <- dplyr::select(df5, -tidyselect::all_of(c(diff))) - out_list[[parm_sel]] <- df5 - } else { - out_list[[parm_sel]] <- df5 - } - ##### STD2 #### - } else if (parm_sel %in% std2) { - # 4, 8 - # remove first row - naming - df1 <- extract[-1, ] - # check for age and length comps - rows <- df1 |> dplyr::filter_all(dplyr::any_vars(. %in% c("age_bins", "len_bins"))) - if (length(rows) > 1) { - matchr <- prodlim::row.match(rows, df1) - df1a <- df1[matchr[1]:matchr[2] - 1, ] - df1a <- Filter(function(x) !all(is.na(x)), df1a) - df1b <- df1[matchr[2]:nrow(df1), ] - df1b <- Filter(function(x) !all(is.na(x)), df1b) - df_list <- list(df1a, df1b) - } else { - # Find first row without NAs = headers - df_sel <- df1[stats::complete.cases(df1), ] - df_list <- list(df_sel) - } - comps_list <- list() - for (i in seq_along(df_list)) { - df2 <- df_list[[i]] - # identify first row - row <- tolower(df2[1, ]) - # make row the header names for first df - colnames(df2) <- row - df2 <- df2[-1, ] - # Defining columns for the grouping - if (any(grepl("len_bins", colnames(df2)))) { - std2_id <- "len_bins" - } else if (any(grepl("age_bins", colnames(df2)))) { - std2_id <- "age_bins" + + if (any(colnames(df5) %in% errors)) { + df5 <- df5 |> + dplyr::mutate(uncertainty_label = intersect(names(df5), errors)) |> + dplyr::rename(uncertainty = intersect(colnames(df5), errors)) + colnames(df5) <- tolower(names(df5)) } else { - std2_id <- "fleet" - } - # pivot data - if (any(grepl(":", df2[max(nrow(df2)), ]))) { - df2 <- df2[-max(nrow(df2)), ] - } else { - df2 <- df2 + df5 <- df5 |> + dplyr::mutate( + uncertainty_label = NA, + uncertainty = NA + ) + colnames(df5) <- tolower(names(df5)) } - df3 <- df2 |> - tidyr::pivot_longer( - cols = -intersect(c(factors, errors, std2_id, "n_obs"), colnames(df2)), - names_to = "label", - values_to = "estimate" - ) |> - tidyr::pivot_wider( - names_from = tidyselect::all_of(std2_id), - values_from = estimate - ) - # if(!std2_id %in% factors){ - colnames(df3) <- stringr::str_replace(colnames(df3), "label", std2_id) + # param_df <- df5 + # if (ncol(out_new) < ncol(df5)){ + # warning(paste0("Transformed data frame for ", parm_sel, " has more columns than default.")) + # } else if (ncol(out_new) > ncol(df5)){ + # warning(paste0("Transformed data frame for ", parm_sel, " has less columns than default.")) # } - if (any(duplicated(tolower(names(df3))))) { - repd_name <- names(which(table(tolower(names(df3))) > 1)) - df3 <- df3 |> - dplyr::select(-tidyselect::all_of(repd_name)) - colnames(df3) <- tolower(names(df3)) - } - if ("age_bins" %in% colnames(df3)) df3 <- dplyr::rename(df3, age = age_bins) - if (nrow(df3) > 0) { - df4 <- df3 |> - tidyr::pivot_longer( - cols = -intersect(c(factors, errors, std2_id, "n_obs"), colnames(df3)), - names_to = "label", - values_to = "estimate" - ) |> - dplyr::mutate(module_name = parm_sel) - } else { - df4 <- df3 - } - if ("seas" %in% colnames(df4)) { - df4 <- df4 |> - dplyr::rename(season = seas) - } - df4 <- dplyr::mutate(df4, module_name = parm_sel) - df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA - if (ncol(out_new) < ncol(df4)) { - diff <- setdiff(names(df4), names(out_new)) + if ("seas" %in% colnames(df5)) df5 <- dplyr::rename(df5, season = seas) + + if ("subseas" %in% colnames(df5)) df5 <- dplyr::rename(df5, subseason = subseas) + + if ("like" %in% colnames(df5)) df5 <- dplyr::rename(df5, likelihood = like) + + df5[setdiff(tolower(names(out_new)), tolower(names(df5)))] <- NA + if (ncol(out_new) < ncol(df5)) { + diff <- setdiff(names(df5), names(out_new)) cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) # warning(parm_sel, " has more columns than the output data frame. The column(s) ", paste(diff, collapse = ", ")," are not found in the standard file. It was excluded from the resulting output. Please open an issue for developer fix.") - df4 <- dplyr::select(df4, -tidyselect::all_of(diff)) + df5 <- dplyr::select(df5, -tidyselect::all_of(c(diff))) + out_list[[parm_sel]] <- df5 + } else { + out_list[[parm_sel]] <- df5 } - comps_list[[i]] <- df4 - } - # Add to new dataframe - df5 <- Reduce(rbind, comps_list) - out_list[[parm_sel]] <- df5 - - ##### cha #### - } else if (parm_sel %in% cha) { - # Only one keyword characterized as this - area_row <- which(apply(extract, 1, function(row) any(row == "Area:"))) - area_val <- c(t(extract[area_row, 3:ncol(extract)])) - gp_row <- which(apply(extract, 1, function(row) any(row == "GP:"))) - gp_val <- c(t(extract[gp_row, 3:ncol(extract)])) - df1 <- extract[-c(1:4), ] - col_name_repl <- paste(parm_sel, "_", area_val, "_", gp_val, sep = "") - colnames(df1) <- c("year", "era", col_name_repl) - df2 <- df1 |> - tidyr::pivot_longer( - cols = -intersect(colnames(df1), c(factors, errors)), - names_to = "label", - values_to = "estimate" - ) |> - dplyr::mutate( - area = stringr::str_extract(label, "(?<=_)[0-9]+"), - growth_pattern = stringr::str_extract(label, "(?<=_)[0-9]+$"), - label = stringr::str_extract(label, "^.*?(?=_[0-9]+)"), - module_name = parm_sel - ) - df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA - if (ncol(out_new) < ncol(df2)) { - diff <- setdiff(names(df2), names(out_new)) - cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) - df2 <- dplyr::select(df2, -tidyselect::all_of(diff)) - out_list[[parm_sel]] <- df2 - } else { - out_list[[parm_sel]] <- df2 - } - ##### rand #### - } else if (parm_sel %in% rand) { - # KEYWORDS in RAND - # "Input_Variance_Adjustment" - # "SPR_SERIES" - # "selparm(Size)_By_Year_after_adjustments" - # "selparm(Age)_By_Year_after_adjustments" - # "BIOLOGY" - # "SPR/YPR_Profile" - # "SPAWN_RECR_CURVE" - # "Biology_at_age_in_endyr" - # "PARAMETERS" - - if (parm_sel == "SPAWN_RECR_CURVE") { - # 32 - # TODO: add this to converter - # set labels to "fitted_line_x" - # remove first row - naming - # df1 <- extract[-1, ] - # # Find first row without NAs = headers - # df2 <- df1[stats::complete.cases(df1), ] - # # identify first row - # row <- df2[1, ] - # # make row the header names for first df - # colnames(df1) <- row - # # find row number that matches 'row' - # rownum <- prodlim::row.match(row, df1) - # # Subset data frame - # df3 <- df1[-c(1:rownum), ] - # colnames(df3) <- tolower(row) - # # add year and manipulate df - # # Extract first year of recruitment - # fyr_row <- which(apply(dat, 1, function(row) any(row == "Start_year:"))) - # first_year <- dat[fyr_row,2] - # # Extract last year - # endyr_row <- which(apply(dat, 1, function(row) any(row == "End_year:"))) - # end_year <- dat[endyr_row,2] - # df4 <- df3 |> - # dplyr::mutate( - # year = seq(first_year, end_year, by = 1), - # ) - # skipping for now cuz not needed - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "SPR_SERIES") { - # split into the 3 dfs then stack - make sure all factors are present + ##### STD2 #### + } else if (parm_sel %in% std2) { + # 4, 8 # remove first row - naming df1 <- extract[-1, ] - # Find first row without NAs = headers - df2 <- df1[stats::complete.cases(df1), ] - # identify first row - row <- df2[1, ] - # make row the header names for first df - colnames(df1) <- row - # find row number that matches 'row' - rownum <- prodlim::row.match(row, df1) - # Subset data frame - df3 <- df1[-(1:rownum), ] - colnames(df3) <- tolower(row) - # check if there are estimate and acual values within the df - if (any(grepl("actual", colnames(df3)) | grepl("more_f", colnames(df3)))) { - actual_col <- grep("actual", colnames(df3)) - moref_col <- grep("more_f", colnames(df3)) - # Separate out parts of the dataframe - sub_df1 <- df3[, 1:(actual_col - 1)] |> + # check for age and length comps + rows <- df1 |> dplyr::filter_all(dplyr::any_vars(. %in% c("age_bins", "len_bins"))) + if (length(rows) > 1) { + matchr <- prodlim::row.match(rows, df1) + df1a <- df1[matchr[1]:matchr[2] - 1, ] + df1a <- Filter(function(x) !all(is.na(x)), df1a) + df1b <- df1[matchr[2]:nrow(df1), ] + df1b <- Filter(function(x) !all(is.na(x)), df1b) + df_list <- list(df1a, df1b) + } else { + # Find first row without NAs = headers + df_sel <- df1[stats::complete.cases(df1), ] + df_list <- list(df_sel) + } + comps_list <- list() + for (i in seq_along(df_list)) { + df2 <- df_list[[i]] + # identify first row + row <- tolower(df2[1, ]) + # make row the header names for first df + colnames(df2) <- row + df2 <- df2[-1, ] + # Defining columns for the grouping + if (any(grepl("len_bins", colnames(df2)))) { + std2_id <- "len_bins" + } else if (any(grepl("age_bins", colnames(df2)))) { + std2_id <- "age_bins" + } else { + std2_id <- "fleet" + } + # pivot data + if (any(grepl(":", df2[max(nrow(df2)), ]))) { + df2 <- df2[-max(nrow(df2)), ] + } else { + df2 <- df2 + } + df3 <- df2 |> tidyr::pivot_longer( - cols = -c(yr, era), + cols = -intersect(c(factors, errors, std2_id, "n_obs"), colnames(df2)), names_to = "label", values_to = "estimate" ) |> - dplyr::rename(year = yr) |> - dplyr::mutate( - label = dplyr::case_when( - label == "bio_all" ~ "biomass", - label == "bio_smry" ~ "biomass_midyear", - label == "ssbzero" ~ "spawning_biomass_zero", - # label == "ssbfished" ~ "spawning_biomass", - label == "ssbfished/r" ~ "ssbfished_r", - TRUE ~ label - ), - # label = paste("estimate_", label, sep = ""), - morph = NA - ) - - sub_df2 <- df3[, c(1:2, (actual_col + 1):(moref_col - 1))] |> - tidyr::pivot_longer( - cols = -c(yr, era), - names_to = "label", - values_to = "initial" - ) |> - dplyr::rename(year = yr) |> - dplyr::mutate( - label = dplyr::case_when( - label == "bio_all" ~ "biomass", - label == "bio_smry" ~ "biomass_midyear", - label == "num_smry" ~ "abundance_midyear", - label == "dead_catch" ~ "total_catch", # dead + retained - label == "retain_catch" ~ "landings", - label == "ssb" ~ "spawning_biomass", - label == "recruits" ~ "recruitment", - TRUE ~ label - ), - # change so that the values are placed in the column "initial" then combine w/ estimates - # label = paste("actual_", label, sep = ""), - morph = NA + tidyr::pivot_wider( + names_from = tidyselect::all_of(std2_id), + values_from = estimate ) - # combine above 2 since they show the estimate and actual values - matching - sub_df12 <- dplyr::full_join( - sub_df1, - sub_df2, - by = c("year", "era", "label", "morph") + # if(!std2_id %in% factors){ + colnames(df3) <- stringr::str_replace(colnames(df3), "label", std2_id) + # } + if (any(duplicated(tolower(names(df3))))) { + repd_name <- names(which(table(tolower(names(df3))) > 1)) + df3 <- df3 |> + dplyr::select(-tidyselect::all_of(repd_name)) + colnames(df3) <- tolower(names(df3)) + } + if ("age_bins" %in% colnames(df3)) df3 <- dplyr::rename(df3, age = age_bins) + if (nrow(df3) > 0) { + df4 <- df3 |> + tidyr::pivot_longer( + cols = -intersect(c(factors, errors, std2_id, "n_obs"), colnames(df3)), + names_to = "label", + values_to = "estimate" + ) |> + dplyr::mutate(module_name = parm_sel) + } else { + df4 <- df3 + } + if ("seas" %in% colnames(df4)) { + df4 <- df4 |> + dplyr::rename(season = seas) + } + df4 <- dplyr::mutate(df4, module_name = parm_sel) + df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA + if (ncol(out_new) < ncol(df4)) { + diff <- setdiff(names(df4), names(out_new)) + cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) + # warning(parm_sel, " has more columns than the output data frame. The column(s) ", paste(diff, collapse = ", ")," are not found in the standard file. It was excluded from the resulting output. Please open an issue for developer fix.") + df4 <- dplyr::select(df4, -tidyselect::all_of(diff)) + } + comps_list[[i]] <- df4 + } + # Add to new dataframe + df5 <- Reduce(rbind, comps_list) + out_list[[parm_sel]] <- df5 + + ##### cha #### + } else if (parm_sel %in% cha) { + # Only one keyword characterized as this + area_row <- which(apply(extract, 1, function(row) any(row == "Area:"))) + area_val <- c(t(extract[area_row, 3:ncol(extract)])) + gp_row <- which(apply(extract, 1, function(row) any(row == "GP:"))) + gp_val <- c(t(extract[gp_row, 3:ncol(extract)])) + df1 <- extract[-c(1:4), ] + col_name_repl <- paste(parm_sel, "_", area_val, "_", gp_val, sep = "") + colnames(df1) <- c("year", "era", col_name_repl) + df2 <- df1 |> + tidyr::pivot_longer( + cols = -intersect(colnames(df1), c(factors, errors)), + names_to = "label", + values_to = "estimate" + ) |> + dplyr::mutate( + area = stringr::str_extract(label, "(?<=_)[0-9]+"), + growth_pattern = stringr::str_extract(label, "(?<=_)[0-9]+$"), + label = stringr::str_extract(label, "^.*?(?=_[0-9]+)"), + module_name = parm_sel ) - # extract last part of df - sub_df3 <- df3[, c(1:2, (moref_col + 1):ncol(df3))] |> - tidyr::pivot_longer( - cols = -c(yr, era), - names_to = "label", - values_to = "estimate" + df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA + if (ncol(out_new) < ncol(df2)) { + diff <- setdiff(names(df2), names(out_new)) + cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) + df2 <- dplyr::select(df2, -tidyselect::all_of(diff)) + out_list[[parm_sel]] <- df2 + } else { + out_list[[parm_sel]] <- df2 + } + ##### rand #### + } else if (parm_sel %in% rand) { + # KEYWORDS in RAND + # "Input_Variance_Adjustment" + # "SPR_SERIES" + # "selparm(Size)_By_Year_after_adjustments" + # "selparm(Age)_By_Year_after_adjustments" + # "BIOLOGY" + # "SPR/YPR_Profile" + # "SPAWN_RECR_CURVE" + # "Biology_at_age_in_endyr" + # "PARAMETERS" + + if (parm_sel == "SPAWN_RECR_CURVE") { + # 32 + # TODO: add this to converter + # set labels to "fitted_line_x" + # remove first row - naming + # df1 <- extract[-1, ] + # # Find first row without NAs = headers + # df2 <- df1[stats::complete.cases(df1), ] + # # identify first row + # row <- df2[1, ] + # # make row the header names for first df + # colnames(df1) <- row + # # find row number that matches 'row' + # rownum <- prodlim::row.match(row, df1) + # # Subset data frame + # df3 <- df1[-c(1:rownum), ] + # colnames(df3) <- tolower(row) + # # add year and manipulate df + # # Extract first year of recruitment + # fyr_row <- which(apply(dat, 1, function(row) any(row == "Start_year:"))) + # first_year <- dat[fyr_row,2] + # # Extract last year + # endyr_row <- which(apply(dat, 1, function(row) any(row == "End_year:"))) + # end_year <- dat[endyr_row,2] + # df4 <- df3 |> + # dplyr::mutate( + # year = seq(first_year, end_year, by = 1), + # ) + # skipping for now cuz not needed + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "SPR_SERIES") { + # split into the 3 dfs then stack - make sure all factors are present + # remove first row - naming + df1 <- extract[-1, ] + # Find first row without NAs = headers + df2 <- df1[stats::complete.cases(df1), ] + # identify first row + row <- df2[1, ] + # make row the header names for first df + colnames(df1) <- row + # find row number that matches 'row' + rownum <- prodlim::row.match(row, df1) + # Subset data frame + df3 <- df1[-(1:rownum), ] + colnames(df3) <- tolower(row) + # check if there are estimate and acual values within the df + if (any(grepl("actual", colnames(df3)) | grepl("more_f", colnames(df3)))) { + actual_col <- grep("actual", colnames(df3)) + moref_col <- grep("more_f", colnames(df3)) + # Separate out parts of the dataframe + sub_df1 <- df3[, 1:(actual_col - 1)] |> + tidyr::pivot_longer( + cols = -c(yr, era), + names_to = "label", + values_to = "estimate" + ) |> + dplyr::rename(year = yr) |> + dplyr::mutate( + label = dplyr::case_when( + label == "bio_all" ~ "biomass", + label == "bio_smry" ~ "biomass_midyear", + label == "ssbzero" ~ "spawning_biomass_zero", + # label == "ssbfished" ~ "spawning_biomass", + label == "ssbfished/r" ~ "ssbfished_r", + TRUE ~ label + ), + # label = paste("estimate_", label, sep = ""), + morph = NA + ) + + sub_df2 <- df3[, c(1:2, (actual_col + 1):(moref_col - 1))] |> + tidyr::pivot_longer( + cols = -c(yr, era), + names_to = "label", + values_to = "initial" + ) |> + dplyr::rename(year = yr) |> + dplyr::mutate( + label = dplyr::case_when( + label == "bio_all" ~ "biomass", + label == "bio_smry" ~ "biomass_midyear", + label == "num_smry" ~ "abundance_midyear", + label == "dead_catch" ~ "total_catch", # dead + retained + label == "retain_catch" ~ "landings", + label == "ssb" ~ "spawning_biomass", + label == "recruits" ~ "recruitment", + TRUE ~ label + ), + # change so that the values are placed in the column "initial" then combine w/ estimates + # label = paste("actual_", label, sep = ""), + morph = NA + ) + # combine above 2 since they show the estimate and actual values - matching + sub_df12 <- dplyr::full_join( + sub_df1, + sub_df2, + by = c("year", "era", "label", "morph") + ) + # extract last part of df + sub_df3 <- df3[, c(1:2, (moref_col + 1):ncol(df3))] |> + tidyr::pivot_longer( + cols = -c(yr, era), + names_to = "label", + values_to = "estimate" + ) |> + dplyr::rename(year = yr) |> + dplyr::mutate( + morph = dplyr::case_when( + grepl("avef_|maxf_", label) ~ stringr::str_extract(label, "[0-9]+$"), + TRUE ~ NA_character_ + ), + label = dplyr::case_when( + grepl("avef_", label) ~ stringr::str_remove(label, "_[0-9]+"), + grepl("maxf_", label) ~ stringr::str_remove(label, "_[0-9]+"), + label == "f=z-m" ~ "fishing_mortality", + TRUE ~ label + ), + initial = NA + ) + # combine all subdataframes + df4 <- rbind(sub_df12, sub_df3) |> + dplyr::mutate(module_name = parm_sel) + } else { + df4 <- df3 |> + tidyr::pivot_longer( + cols = -c(intersect(colnames(df3), c("Yr", "yr", "era"))), + names_to = "label", + values_to = "estimate" + ) |> + dplyr::rename(year = intersect(colnames(df3), c("Yr", "yr", "Year"))) |> + dplyr::mutate( + label = dplyr::case_when( + grepl("bio_all", label) ~ "biomass", + grepl("bio_smry", label) ~ "biomass_midyear", + label == "ssbzero" ~ "spawning_biomass_zero", + # label == "ssbfished" ~ "spawning_biomass", + grepl("SSB_unfished", label) ~ "SSB_unfished", + grepl("SSBfished_eq", label) ~ "SSB_fished", + label == "ssbfished/r" ~ "ssbfished_r", + TRUE ~ label + ), + # label = paste("estimate_", label, sep = ""), + morph = NA, + module_name = parm_sel + ) + } + # match to out_new + df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA + # Add to out list + out_list[[parm_sel]] <- df4 + } else if (parm_sel == "selparm(Size)_By_Year_after_adjustments") { + # TODO: revisit one day in group work + # skipping this one because there are no headers + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "selparm(Age)_By_Year_after_adjustments") { + # also skipping + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "BIOLOGY") { + # not sure how this output is helpful + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "SPR/YPR_Profile") { + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "Biology_at_age_in_endyr") { + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "PARAMETERS") { + df1 <- extract[-1, ] + # Find first row without NAs = headers + # temp fix for catch df + df2 <- df1[stats::complete.cases(df1), ] + if (any(c("#") %in% df2[, 1])) { + full_row <- which(apply(df1, 1, function(row) is.na(row) | row == " " | row == "-" | row == "#"))[1] + df1 <- df1[-full_row[1], ] + df1 <- Filter(function(x) !all(is.na(x)), df1) + df2 <- df1[stats::complete.cases(df1), ] + } + # identify first row + row <- df2[1, ] + # make row the header names for first df + colnames(df1) <- row + # find row number that matches 'row' + rownum <- prodlim::row.match(row, df1) + # Subset data frame + df3 <- df1[-c(1:rownum), ] + colnames(df3) <- tolower(row) + # Pull out indexing variables and remove from labels + df4 <- df3 |> + dplyr::select(intersect(colnames(df3), c("label", "value", "init", "parm_stdev"))) |> + dplyr::rename( + estimate = value, + initial = init, + uncertainty = parm_stdev ) |> - dplyr::rename(year = yr) |> dplyr::mutate( - morph = dplyr::case_when( - grepl("avef_|maxf_", label) ~ stringr::str_extract(label, "[0-9]+$"), - TRUE ~ NA_character_ + uncertainty = dplyr::case_when( + uncertainty == "_" ~ NA, + TRUE ~ uncertainty + ), + uncertainty_label = dplyr::case_when( + is.na(uncertainty) ~ NA, + TRUE ~ "sd" + ), + area = dplyr::case_when( + grepl("?_area_[0-9]_?", label) ~ stringr::str_extract(label, "(?<=area_)[0-9]+"), + grepl("_[0-9]_", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), + TRUE ~ NA ), + sex = dplyr::case_when( + grepl("_fem_", label) ~ "female", + grepl("_mal_", label) ~ "male", + grepl("_sx:1$", label) ~ "female", + grepl("_sx:2$", label) ~ "male", + grepl("_sx:1_", label) ~ "female", + grepl("_sx:2_", label) ~ "male", + grepl("Male", label) ~ "male", + grepl("Female", label) ~ "female", + TRUE ~ NA + ), + growth_pattern = dplyr::case_when( + grepl("_gp_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + grepl("_gp:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), + grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), + grepl("_GP_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + grepl("_GP:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), + grepl("_GP:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), + TRUE ~ NA + ), + month = dplyr::case_when( + grepl("_month_[0-9]+$", label) ~ stringr::str_extract(label, "(?<=month_)[0-9]+$"), + TRUE ~ ifelse(any(grepl("^month$", colnames(df3))), month, NA) + ), + age = dplyr::case_when( + grepl("InitAge", label) ~ stringr::str_extract(label, "(?<=InitAge_)[0-9]+"), + TRUE ~ NA + ), + year = dplyr::case_when( + grepl("RecrDev", label) ~ stringr::str_extract(label, "(?<=RecrDev_)[0-9]+$"), + grepl("_[0-9]{4}$", label) ~ stringr::str_extract(label, "[0-9]{4}$"), + TRUE ~ NA + ), + era = dplyr::case_when( + grepl("InitAge", label) ~ stringr::str_extract(label, "^.*?(?=_InitAge_[0-9]+$)"), + grepl("RecrDev", label) ~ stringr::str_extract(label, "^.*?(?=_RecrDev)"), + TRUE ~ NA + ), + fleet = dplyr::case_when( + grepl( + paste( + fleet_names, + collapse = "|" + ), + label + ) ~ stringr::str_extract(label, paste0("(^.*?_)?<=|", paste(fleet_names, collapse = "|"))), + TRUE ~ NA + ), + block = dplyr::case_when( + grepl("_BLK[0-9]repl_[0-9]{4}$", label) ~ stringr::str_extract(label, "(?<=_BLK)[0-9](?=repl_[0-9]{4}$)"), + TRUE ~ NA + ), + # Must be last step in mutate bc all info comes from the label = dplyr::case_when( - grepl("avef_", label) ~ stringr::str_remove(label, "_[0-9]+"), - grepl("maxf_", label) ~ stringr::str_remove(label, "_[0-9]+"), - label == "f=z-m" ~ "fishing_mortality", - TRUE ~ label + grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), + grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), + grepl("InitAge", label) ~ "initial_age", + grepl("RecrDev", label) ~ "recruitment_deviations", + grepl( + paste0( + paste0( + "_", + fleet_names, + collapse = "|" + ), + "\\([0-9]+\\)_BLK[0-9]repl_[0-9]{4}$" + ), + label + ) ~ stringr::str_remove_all(label, "(Male_|Female_)|(_[[:alnum:]]+\\([0-9]+\\))|(_BLK[0-9]repl_[0-9]{4})"), + grepl("Male_|Female_", label) & grepl(paste0(paste0("_", fleet_names, collapse = "|"), "\\([0-9]+\\)"), label) ~ stringr::str_remove_all(label, "(Male_|Female_)|(_[[:alnum:]]+\\([0-9]+\\))"), + grepl(paste0(paste0("_", fleet_names, collapse = "|"), "\\([0-9]+\\)"), label) ~ stringr::str_remove(label, paste0(paste0("_", fleet_names, "\\([0-9]+\\)", collapse = "|"))), # , paste0("_", fleet_names, collapse = "|") + TRUE ~ stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") ), - initial = NA + # fix remaining labels + label = ifelse(grepl("_GP$", label), stringr::str_remove(label, "_GP$"), label), + label = ifelse(grepl("_Fem|_Mal", label), stringr::str_remove(label, "_Fem$|_Mal$"), label), + module_name = parm_sel ) - # combine all subdataframes - df4 <- rbind(sub_df12, sub_df3) |> - dplyr::mutate(module_name = parm_sel) + # match to out_new + df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA + # Add to out list + out_list[[parm_sel]] <- df4 } else { - df4 <- df3 |> + miss_parms <- c(miss_parms, parm_sel) + next + } + # miss_parms <- c(miss_parms, parm_sel) + # next + #### info #### + } else if (parm_sel %in% info) { + if (parm_sel == "LIKELIHOOD") { + df1 <- extract[-1, ] + # make row the header names for first df + colnames(df1) <- df1[1, ] + # Remove first row containing column names + df2 <- df1[-1, ] |> + dplyr::rename(label = Component) |> tidyr::pivot_longer( - cols = -c(intersect(colnames(df3), c("Yr", "yr", "era"))), - names_to = "label", - values_to = "estimate" - ) |> - dplyr::rename(year = intersect(colnames(df3), c("Yr", "yr", "Year"))) |> + cols = -label, + names_to = "type", + values_to = "likelihood" + ) + # match to out_new + df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA + # Add to out list + out_list[[parm_sel]] <- df2 + } else if (parm_sel == "DEFINITIONS") { + # Pull out only the first two columns and remove first row keyword + df1 <- extract[-1, 1:2] + colnames(df1) <- c("label", "estimate") + # find where rescale is located + col_rescale <- grep("rescaled_to_sum_to:", extract) + rescaled_months <- extract[4, col_rescale + 1] |> dplyr::pull() + # remove : from all labels and tolower and add in rescaled months + df2 <- df1 |> + rbind(data.frame( + label = "rescaled_months", + estimate = rescaled_months + )) |> dplyr::mutate( - label = dplyr::case_when( - grepl("bio_all", label) ~ "biomass", - grepl("bio_smry", label) ~ "biomass_midyear", - label == "ssbzero" ~ "spawning_biomass_zero", - # label == "ssbfished" ~ "spawning_biomass", - grepl("SSB_unfished", label) ~ "SSB_unfished", - grepl("SSBfished_eq", label) ~ "SSB_fished", - label == "ssbfished/r" ~ "ssbfished_r", - TRUE ~ label - ), - # label = paste("estimate_", label, sep = ""), - morph = NA, + label = tolower(stringr::str_remove_all(label, ":")), module_name = parm_sel ) + # match to out_new + df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA + # Add to out list + out_list[[parm_sel]] <- df2 + } else { + miss_parms <- c(miss_parms, parm_sel) + next } - # match to out_new - df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA - # Add to out list - out_list[[parm_sel]] <- df4 - } else if (parm_sel == "selparm(Size)_By_Year_after_adjustments") { - # TODO: revisit one day in group work - # skipping this one because there are no headers - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "selparm(Age)_By_Year_after_adjustments") { - # also skipping - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "BIOLOGY") { - # not sure how this output is helpful - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "SPR/YPR_Profile") { - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "Biology_at_age_in_endyr") { - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "PARAMETERS") { + #### aa.al #### + } else if (parm_sel %in% aa.al) { + # 8,9,11,12,13,14,15,16,28,29 + # remove first row - naming df1 <- extract[-1, ] # Find first row without NAs = headers - # temp fix for catch df df2 <- df1[stats::complete.cases(df1), ] - if (any(c("#") %in% df2[, 1])) { - full_row <- which(apply(df1, 1, function(row) is.na(row) | row == " " | row == "-" | row == "#"))[1] - df1 <- df1[-full_row[1], ] - df1 <- Filter(function(x) !all(is.na(x)), df1) - df2 <- df1[stats::complete.cases(df1), ] - } # identify first row row <- df2[1, ] + if (any(row %in% "XX")) { + loc_xx <- grep("XX", row) + row <- row[row != "XX"] + df1 <- df1[, -loc_xx] + } + + # TODO: apply this next if statement to a general process so it's part of the standard cleaning + # check if the headers make sense + # this is a temporary fix to a specific bug + # I have seen this issue in the past and I am not sure how to recognize this generally + if (any(parm_sel == "AGE_SELEX" & c("1", "2", "3") %notin% row)) { + rownum <- prodlim::row.match(row, df1) + # Subset data frame + df1 <- df1[-c(1:rownum), ] + cols_to_keep <- which(sapply(df1, function(x) !all(is.na(x)))) + df1 <- df1 |> dplyr::select(dplyr::all_of(c(names(cols_to_keep)))) + df2 <- df1[stats::complete.cases(df1), ] + row <- df2[1, ] + } + # make row the header names for first df colnames(df1) <- row + # find row number that matches 'row' rownum <- prodlim::row.match(row, df1) # Subset data frame df3 <- df1[-c(1:rownum), ] colnames(df3) <- tolower(row) - # Pull out indexing variables and remove from labels - df4 <- df3 |> - dplyr::select(intersect(colnames(df3), c("label", "value", "init", "parm_stdev"))) |> - dplyr::rename( - estimate = value, - initial = init, - uncertainty = parm_stdev - ) |> - dplyr::mutate( - uncertainty = dplyr::case_when( - uncertainty == "_" ~ NA, - TRUE ~ uncertainty - ), - uncertainty_label = dplyr::case_when( - is.na(uncertainty) ~ NA, - TRUE ~ "sd" - ), - area = dplyr::case_when( - grepl("?_area_[0-9]_?", label) ~ stringr::str_extract(label, "(?<=area_)[0-9]+"), - grepl("_[0-9]_", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), - TRUE ~ NA - ), - sex = dplyr::case_when( - grepl("_fem_", label) ~ "female", - grepl("_mal_", label) ~ "male", - grepl("_sx:1$", label) ~ "female", - grepl("_sx:2$", label) ~ "male", - grepl("_sx:1_", label) ~ "female", - grepl("_sx:2_", label) ~ "male", - grepl("Male", label) ~ "male", - grepl("Female", label) ~ "female", - TRUE ~ NA - ), - growth_pattern = dplyr::case_when( - grepl("_gp_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - grepl("_gp:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), - grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), - grepl("_GP_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - grepl("_GP:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), - grepl("_GP:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), - TRUE ~ NA - ), - month = dplyr::case_when( - grepl("_month_[0-9]+$", label) ~ stringr::str_extract(label, "(?<=month_)[0-9]+$"), - TRUE ~ ifelse(any(grepl("^month$", colnames(df3))), month, NA) - ), - age = dplyr::case_when( - grepl("InitAge", label) ~ stringr::str_extract(label, "(?<=InitAge_)[0-9]+"), - TRUE ~ NA - ), - year = dplyr::case_when( - grepl("RecrDev", label) ~ stringr::str_extract(label, "(?<=RecrDev_)[0-9]+$"), - grepl("_[0-9]{4}$", label) ~ stringr::str_extract(label, "[0-9]{4}$"), - TRUE ~ NA - ), - era = dplyr::case_when( - grepl("InitAge", label) ~ stringr::str_extract(label, "^.*?(?=_InitAge_[0-9]+$)"), - grepl("RecrDev", label) ~ stringr::str_extract(label, "^.*?(?=_RecrDev)"), - TRUE ~ NA - ), - fleet = dplyr::case_when( - grepl( - paste( - fleet_names, - collapse = "|" - ), - label - ) ~ stringr::str_extract(label, paste0("(^.*?_)?<=|", paste(fleet_names, collapse = "|"))), - TRUE ~ NA - ), - block = dplyr::case_when( - grepl("_BLK[0-9]repl_[0-9]{4}$", label) ~ stringr::str_extract(label, "(?<=_BLK)[0-9](?=repl_[0-9]{4}$)"), - TRUE ~ NA - ), - # Must be last step in mutate bc all info comes from the - label = dplyr::case_when( - grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), - grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), - grepl("InitAge", label) ~ "initial_age", - grepl("RecrDev", label) ~ "recruitment_deviations", - grepl( - paste0( - paste0( - "_", - fleet_names, - collapse = "|" - ), - "\\([0-9]+\\)_BLK[0-9]repl_[0-9]{4}$" - ), - label - ) ~ stringr::str_remove_all(label, "(Male_|Female_)|(_[[:alnum:]]+\\([0-9]+\\))|(_BLK[0-9]repl_[0-9]{4})"), - grepl("Male_|Female_", label) & grepl(paste0(paste0("_", fleet_names, collapse = "|"), "\\([0-9]+\\)"), label) ~ stringr::str_remove_all(label, "(Male_|Female_)|(_[[:alnum:]]+\\([0-9]+\\))"), - grepl(paste0(paste0("_", fleet_names, collapse = "|"), "\\([0-9]+\\)"), label) ~ stringr::str_remove(label, paste0(paste0("_", fleet_names, "\\([0-9]+\\)", collapse = "|"))), # , paste0("_", fleet_names, collapse = "|") - TRUE ~ stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") - ), - # fix remaining labels - label = ifelse(grepl("_GP$", label), stringr::str_remove(label, "_GP$"), label), - label = ifelse(grepl("_Fem|_Mal", label), stringr::str_remove(label, "_Fem$|_Mal$"), label), - module_name = parm_sel - ) - # match to out_new - df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA - # Add to out list - out_list[[parm_sel]] <- df4 - } else { - miss_parms <- c(miss_parms, parm_sel) - next - } - # miss_parms <- c(miss_parms, parm_sel) - # next - #### info #### - } else if (parm_sel %in% info) { - if (parm_sel == "LIKELIHOOD") { - df1 <- extract[-1, ] - # make row the header names for first df - colnames(df1) <- df1[1, ] - # Remove first row containing column names - df2 <- df1[-1, ] |> - dplyr::rename(label = Component) |> - tidyr::pivot_longer( - cols = -label, - names_to = "type", - values_to = "likelihood" - ) - # match to out_new - df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA - # Add to out list - out_list[[parm_sel]] <- df2 - } else if (parm_sel == "DEFINITIONS") { - # Pull out only the first two columns and remove first row keyword - df1 <- extract[-1, 1:2] - colnames(df1) <- c("label", "estimate") - # find where rescale is located - col_rescale <- grep("rescaled_to_sum_to:", extract) - rescaled_months <- extract[4, col_rescale + 1] |> dplyr::pull() - # remove : from all labels and tolower and add in rescaled months - df2 <- df1 |> - rbind(data.frame( - label = "rescaled_months", - estimate = rescaled_months - )) |> - dplyr::mutate( - label = tolower(stringr::str_remove_all(label, ":")), - module_name = parm_sel - ) - # match to out_new - df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA - # Add to out list - out_list[[parm_sel]] <- df2 - } else { - miss_parms <- c(miss_parms, parm_sel) - next - } - #### aa.al #### - } else if (parm_sel %in% aa.al) { - # 8,9,11,12,13,14,15,16,28,29 - # remove first row - naming - df1 <- extract[-1, ] - # Find first row without NAs = headers - df2 <- df1[stats::complete.cases(df1), ] - # identify first row - row <- df2[1, ] - if (any(row %in% "XX")) { - loc_xx <- grep("XX", row) - row <- row[row != "XX"] - df1 <- df1[, -loc_xx] - } - - # TODO: apply this next if statement to a general process so it's part of the standard cleaning - # check if the headers make sense - # this is a temporary fix to a specific bug - # I have seen this issue in the past and I am not sure how to recognize this generally - if (any(parm_sel == "AGE_SELEX" & c("1", "2", "3") %notin% row)) { - rownum <- prodlim::row.match(row, df1) - # Subset data frame - df1 <- df1[-c(1:rownum), ] - cols_to_keep <- which(sapply(df1, function(x) !all(is.na(x)))) - df1 <- df1 |> dplyr::select(dplyr::all_of(c(names(cols_to_keep)))) - df2 <- df1[stats::complete.cases(df1), ] - row <- df2[1, ] - } - - # make row the header names for first df - colnames(df1) <- row - - # find row number that matches 'row' - rownum <- prodlim::row.match(row, df1) - # Subset data frame - df3 <- df1[-c(1:rownum), ] - colnames(df3) <- tolower(row) - - # aa.al names - naming <- c( - "biomass", "discard", "catch", - "f", "mean_size", "numbers", "sel", - "mean_body_wt", "natural_mortality" - ) - if (stringr::str_detect(tolower(parm_sel), paste(naming, collapse = "|"))) { - label <- stringr::str_extract(tolower(parm_sel), paste(naming, collapse = "|")) - if (length(label) > 1) cli::cli_alert_warning("Length of label is > 1.") - if (label == "f") { - label <- "fishing_mortality" + + # aa.al names + naming <- c( + "biomass", "discard", "catch", + "f", "mean_size", "numbers", "sel", + "mean_body_wt", "natural_mortality" + ) + if (stringr::str_detect(tolower(parm_sel), paste(naming, collapse = "|"))) { + label <- stringr::str_extract(tolower(parm_sel), paste(naming, collapse = "|")) + if (length(label) > 1) cli::cli_alert_warning("Length of label is > 1.") + if (label == "f") { + label <- "fishing_mortality" + } } - } - if (grepl("age", tolower(parm_sel))) { - fac <- "age" - } else if (any(grepl("length|len", tolower(parm_sel)))) { - fac <- "len_bins" - } else if (any(grepl("size", tolower(parm_sel)))) { - fac <- "age" - } else { - fac <- "age" - } - # Reformat dataframe - if (any(colnames(df3) %in% c("Yr", "yr", "year"))) { - df3 <- df3 |> - dplyr::rename(year = yr) - } - if (any(colnames(df3) %in% c("seas"))) { - df3 <- df3 |> - dplyr::rename(season = seas) - } - if (any(colnames(df3) %in% c("subseas"))) { - df3 <- df3 |> - dplyr::rename(subseason = subseas) - } - # if ("label" %in% colnames(df3)) { - # df3 <- dplyr::select(df3, -tidyselect::any_of("label")) - # } - # If factor exists, set to label - if ("factor" %in% colnames(df3)) { + if (grepl("age", tolower(parm_sel))) { + fac <- "age" + } else if (any(grepl("length|len", tolower(parm_sel)))) { + fac <- "len_bins" + } else if (any(grepl("size", tolower(parm_sel)))) { + fac <- "age" + } else { + fac <- "age" + } + # Reformat dataframe + if (any(colnames(df3) %in% c("Yr", "yr", "year"))) { + df3 <- df3 |> + dplyr::rename(year = yr) + } + if (any(colnames(df3) %in% c("seas"))) { + df3 <- df3 |> + dplyr::rename(season = seas) + } + if (any(colnames(df3) %in% c("subseas"))) { + df3 <- df3 |> + dplyr::rename(subseason = subseas) + } + # if ("label" %in% colnames(df3)) { + # df3 <- dplyr::select(df3, -tidyselect::any_of("label")) + # } + # If factor exists, set to label + if ("factor" %in% colnames(df3)) { + df3 <- df3 |> + dplyr::select(-tidyselect::any_of("label")) |> + dplyr::rename(label = factor) + } else { + df3 <- dplyr::mutate(df3, label = label[1]) + } + # Change all columns to chatacters to a avoid issues in pivoting - this will be changed in final df anyway df3 <- df3 |> - dplyr::select(-tidyselect::any_of("label")) |> - dplyr::rename(label = factor) - } else { - df3 <- dplyr::mutate(df3, label = label[1]) - } - # Change all columns to chatacters to a avoid issues in pivoting - this will be changed in final df anyway - df3 <- df3 |> - dplyr::mutate(dplyr::across(tidyselect::everything(), as.character)) - # Set all columns after factors as numeric - # Identify last factor col - other_factors <- c( - "bio_pattern", "birthseas", - "settlement", "morph", "beg/mid", - "type", "label", "label", - "platoon", "month", - "sexes", "part", "bin", "kind" - ) - num_cols <- setdiff(colnames(df3), c(factors, other_factors)) - df3 <- df3 |> - dplyr::mutate(dplyr::across(dplyr::all_of(num_cols), as.numeric)) - # Pivot table long - df4 <- df3 |> - tidyr::pivot_longer( - cols = -intersect(c(factors, errors, other_factors), colnames(df3)), - names_to = fac[1], - values_to = "estimate" - ) |> - dplyr::mutate( - # label = label[1], - module_name = parm_sel[1] + dplyr::mutate(dplyr::across(tidyselect::everything(), as.character)) + # Set all columns after factors as numeric + # Identify last factor col + other_factors <- c( + "bio_pattern", "birthseas", + "settlement", "morph", "beg/mid", + "type", "label", "label", + "platoon", "month", + "sexes", "part", "bin", "kind" ) - if ("sex" %in% colnames(df4)) { - df4 <- df4 |> + num_cols <- setdiff(colnames(df3), c(factors, other_factors)) + df3 <- df3 |> + dplyr::mutate(dplyr::across(dplyr::all_of(num_cols), as.numeric)) + # Pivot table long + df4 <- df3 |> + tidyr::pivot_longer( + cols = -intersect(c(factors, errors, other_factors), colnames(df3)), + names_to = fac[1], + values_to = "estimate" + ) |> dplyr::mutate( - sex = dplyr::case_when( - "sex" %in% colnames(df3) & sex == 1 ~ "female", - "sex" %in% colnames(df3) & sex == 2 ~ "male" - ) + # label = label[1], + module_name = parm_sel[1] ) - } - if (any(grepl("morph", colnames(df4)))) { - df4 <- df4 |> - dplyr::rename(growth_pattern = morph) - } - # Check if likelihood is in the df - if (any(grepl("like", colnames(df4)))) { - df4 <- df4 |> - dplyr::rename(likelihood = like) - } - # Check for error in the df - if (any(grepl(paste0("^", errors, "$", collapse = "|"), colnames(df4)))) { - error_col <- colnames(df4)[grep(paste0("^", errors, "$", collapse = "|"), colnames(df4))] - if (length(error_col) > 1) { - cli::cli_alert("Multiple error columns present. Error will not be added to module.") - } else { + if ("sex" %in% colnames(df4)) { df4 <- df4 |> dplyr::mutate( - uncertainty_label = tolower(unique(error_col)), - uncertainty = df4[[error_col]] + sex = dplyr::case_when( + "sex" %in% colnames(df3) & sex == 1 ~ "female", + "sex" %in% colnames(df3) & sex == 2 ~ "male" + ) ) } - } - if ("label" %in% colnames(df4) & "factor" %in% colnames(df4)) { - df4 <- df4 |> - dplyr::select(-label) |> - dplyr::mutate(label = dplyr::case_when( - grepl("sel", factor) ~ "sel", - TRUE ~ factor - )) |> - dplyr::select(-factor) - } - # Bind to new df - df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA - if (ncol(out_new) < ncol(df4)) { - diff <- setdiff(names(df4), names(out_new)) - cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) - # warning(parm_sel, " has more columns than the output data frame. The column(s) ", paste(diff, collapse = ", ")," are not found in the standard file. It was excluded from the resulting output. Please open an issue for developer fix.") - df4 <- dplyr::select(df4, -tidyselect::all_of(diff)) - out_list[[parm_sel]] <- df4 + if (any(grepl("morph", colnames(df4)))) { + df4 <- df4 |> + dplyr::rename(growth_pattern = morph) + } + # Check if likelihood is in the df + if (any(grepl("like", colnames(df4)))) { + df4 <- df4 |> + dplyr::rename(likelihood = like) + } + # Check for error in the df + if (any(grepl(paste0("^", errors, "$", collapse = "|"), colnames(df4)))) { + error_col <- colnames(df4)[grep(paste0("^", errors, "$", collapse = "|"), colnames(df4))] + if (length(error_col) > 1) { + cli::cli_alert("Multiple error columns present. Error will not be added to module.") + } else { + df4 <- df4 |> + dplyr::mutate( + uncertainty_label = tolower(unique(error_col)), + uncertainty = df4[[error_col]] + ) + } + } + if ("label" %in% colnames(df4) & "factor" %in% colnames(df4)) { + df4 <- df4 |> + dplyr::select(-label) |> + dplyr::mutate(label = dplyr::case_when( + grepl("sel", factor) ~ "sel", + TRUE ~ factor + )) |> + dplyr::select(-factor) + } + # Bind to new df + df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA + if (ncol(out_new) < ncol(df4)) { + diff <- setdiff(names(df4), names(out_new)) + cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) + # warning(parm_sel, " has more columns than the output data frame. The column(s) ", paste(diff, collapse = ", ")," are not found in the standard file. It was excluded from the resulting output. Please open an issue for developer fix.") + df4 <- dplyr::select(df4, -tidyselect::all_of(diff)) + out_list[[parm_sel]] <- df4 + } else { + out_list[[parm_sel]] <- df4 + } + # } else if (parm_sel %in% nn) { + # miss_parms <- c(miss_parms, parm_sel) + # next } else { - out_list[[parm_sel]] <- df4 + cli::cli_alert_info(glue::glue("Processing {parm_sel}")) + miss_parms <- c(miss_parms, parm_sel) + next } - # } else if (parm_sel %in% nn) { - # miss_parms <- c(miss_parms, parm_sel) - # next - } else { - cli::cli_alert_info(glue::glue("Processing {parm_sel}")) - miss_parms <- c(miss_parms, parm_sel) - next - } - } # close if param is in output file - } else { - cli::cli_alert(glue::glue("Skipped {parm_sel}")) - next + } # close if param is in output file + } else { + cli::cli_alert(glue::glue("Skipped {parm_sel}")) + next + } + } # close loop + if (length(miss_parms) > 0) { + cli::cli_alert_info( + paste0("Some parameters were not found or included in the output file. The following parameters were not added into the new output file: \n", paste(miss_parms, collapse = "\n")) + ) } - } # close loop - if (length(miss_parms) > 0) { - cli::cli_alert_info( - paste0("Some parameters were not found or included in the output file. The following parameters were not added into the new output file: \n", paste(miss_parms, collapse = "\n")) - ) + out_new <- Reduce(rbind, out_list) + out_new <- out_new |> + dplyr::mutate(fleet = dplyr::case_when( + any(unique(out_new$fleet) %in% fleet_names) ~ fleet, + TRUE ~ fleet_names[fleet] + )) + } else { + # r4ss output + dat <- file + } - out_new <- Reduce(rbind, out_list) - out_new <- out_new |> - dplyr::mutate(fleet = dplyr::case_when( - any(unique(out_new$fleet) %in% fleet_names) ~ fleet, - TRUE ~ fleet_names[fleet] - )) + } else if (model %in% c("bam", "BAM")) { #### BAM #### # Extract values from BAM output - model file after following ADMB2R From b60f387781530b37a5b1ac55693088b80c708a0e Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Fri, 27 Mar 2026 10:55:26 -0400 Subject: [PATCH 02/28] add modules to add into conout --- R/convert_output.R | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index ae201bf8..fe03e755 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -1258,9 +1258,44 @@ convert_output <- function( TRUE ~ fleet_names[fleet] )) } else { - # r4ss output + #### r4ss #### dat <- file - + select_modules <- c( + "recruit", + "SPAWN_RECRUIT_CURVE", + "Natural_Mortality", + "growth_series", + "sizeselex", + "ageselex", + "exploitation", + "catch"," + timeseries", + "discard", + "mngwt", # ??? + "sprseries", + "sprtarg", + "btarg", + "kobe", + "cpue", + "natage", + "batage", + "natlen", + "batlen", + "fatage", + "discard_at_age", + "catage", + "equil_yeild", + "Z_at_age", + "M_at_age", + "Z_by_area", + "M_by_area", + "Dynamic_Bzero", + "len_comp_fit_table", + "age_comp_fit_table", + "derived_quants", + "parameters", + "SBzero" + ) } } else if (model %in% c("bam", "BAM")) { From 915c623543a0cb2b4568024fbd0f15cd8f3ffdd0 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Mon, 29 Jun 2026 15:15:20 -0400 Subject: [PATCH 03/28] manipulate where te r4ss conversion goes; use current available code to apply similar logic --- R/convert_output.R | 1925 +++++++++++++++++++++++--------------------- 1 file changed, 999 insertions(+), 926 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index fe03e755..47b69019 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -189,9 +189,6 @@ convert_output <- function( cli::cli_alert_info("Identified fleet names:") cli::cli_alert_info("{fleet_names}") - # Extract units - - # Estimated and focal parameters to put into reformatted output df - naming conventions from SS3 # Extract keywords from ss3 file # Find row where keywords start @@ -275,45 +272,156 @@ convert_output <- function( "INDEX_1", "MEAN_BODY_WT_OUTPUT" ) + } else { + # r4ss::ss_output + dat <- file + # Extract fleet names + if (is.null(fleet_names)) { + fleet_names <- dat$FleetNames + } + # Output fleet names in console + cli::cli_alert_info("Identified fleet names:") + cli::cli_alert_info("{fleet_names}") - # Loop for all identified parameters to extract for plotting and use - # Create list of parameters that were not found in the output file - # 1,4,10,17,19,20,22,32,37 - factors <- c( - "era", "year", "fleet", - "fleet_name", "age", "sex", - "area", "seas", "season", - "time", "era", "subseas", - "subseason", "platoon", "platoo", - "growth_pattern", "gp", "month", - "like", "morph", "bio_pattern", - "settlement", "birthseas", "count", - "kind" + param_names <- c( + "recruit", + "SPAWN_RECRUIT_CURVE", # RAND + "Natural_Mortality", # AA.AL + "growth_series", # ? UNSURE THIS IS NULL IN EXAMPLE + "sizeselex", # AA.AL + "ageselex", # AA.AL + "exploitation", # STD + "catch", # STD + "timeseries", # STD + "discard", # STD + "mngwt", # ??? + "sprseries", # RAND + "sprtarg", # single value + "btarg", + "kobe", + "cpue", + "natage", + "batage", + "natlen", + "batlen", + "fatage", # AA.AL + "discard_at_age", + "catage", + "equil_yeild", + "Z_at_age", + "M_at_age", + "Z_by_area", + "M_by_area", + "Dynamic_Bzero", + "len_comp_fit_table", + "age_comp_fit_table", + "derived_quants", #STD + "parameters", # RAND + "SBzero" ) - - errors <- c( - "StdDev", "sd", "std", "stddev", - "se", "SE", - "cv", "CV" + # Group parameters base on table pattern + std <- c( + "DERIVED_QUANTITIES", + "MGparm_By_Year_after_adjustments", + "CATCH", + "SPAWN_RECRUIT", + "TIME_SERIES", + "DISCARD_OUTPUT", + "INDEX_2", + "FIT_LEN_COMPS", + "FIT_AGE_COMPS", + "FIT_SIZE_COMPS", + "SELEX_database", + "Growth_Parameters", + "Kobe_Plot" ) - - miss_parms <- c() - out_list <- list() - #### SS3 loop #### - for (i in seq_along(param_names)) { - # Processing data frame - parm_sel <- param_names[i] - if (parm_sel %in% c(std, std2, cha, rand, aa.al)) { - cli::cli_alert(glue::glue("Processing {parm_sel}")) + std2 <- c("OVERALL_COMPS") + cha <- c("Dynamic_Bzero") + rand <- c( + "Input_Variance_Adjustment", + "SPR_SERIES", + "selparm(Size)_By_Year_after_adjustments", + "selparm(Age)_By_Year_after_adjustments", + "BIOLOGY", + "SPR/YPR_Profile", + "Biology_at_age_in_endyr", + "SPAWN_RECR_CURVE", + "PARAMETERS" + ) + info <- c( + "LIKELIHOOD", + "DEFINITIONS" + ) + aa.al <- c( + "BIOMASS_AT_AGE", + "BIOMASS_AT_LENGTH", + "DISCARD_AT_AGE", + "CATCH_AT_AGE", + "F_AT_AGE", + "MEAN_SIZE_TIMESERIES", + "NUMBERS_AT_AGE", + "NUMBERS_AT_LENGTH", + "AGE_SELEX", + "LEN_SELEX", + "MEAN_BODY_WT(Begin)", + "Natural_Mortality" + ) + nn <- c( + "MORPH_INDEXING", + "EXPLOITATION", + "DISCARD_SPECIFICATION", + "INDEX_1", + "MEAN_BODY_WT_OUTPUT" + ) + } + + # Extract units + + + # Loop for all identified parameters to extract for plotting and use + # Create list of parameters that were not found in the output file + # 1,4,10,17,19,20,22,32,37 + factors <- c( + "era", "year", "fleet", + "fleet_name", "age", "sex", + "area", "seas", "season", + "time", "era", "subseas", + "subseason", "platoon", "platoo", + "growth_pattern", "gp", "month", + "like", "morph", "bio_pattern", + "settlement", "birthseas", "count", + "kind" + ) + + errors <- c( + "StdDev", "sd", "std", "stddev", + "se", "SE", + "cv", "CV" + ) + + miss_parms <- c() + out_list <- list() + #### SS3 loop #### + for (i in seq_along(param_names)) { + # Processing data frame + parm_sel <- param_names[i] + if (parm_sel %in% c(std, std2, cha, rand, aa.al)) { + cli::cli_alert(glue::glue("Processing {parm_sel}")) + if(is.character(file)) { extract <- SS3_extract_df(dat, parm_sel) - if (!is.data.frame(extract)) { - miss_parms <- c(miss_parms, parm_sel) - cli::cli_alert(glue::glue("Skipped {parm_sel}")) - next - } else { - ##### STD #### - # 1,4,10,17,19,36 - if (parm_sel %in% std) { + } else { + extract <- file[[parm_sel]] + } + + if (!is.data.frame(extract)) { + miss_parms <- c(miss_parms, parm_sel) + cli::cli_alert(glue::glue("Skipped {parm_sel}")) + next + } else { + ##### STD #### + # 1,4,10,17,19,36 + if (parm_sel %in% std) { + if (is.character(file)) { # remove first row - naming df1 <- extract[-1, ] # Find first row without NAs = headers @@ -341,963 +449,928 @@ convert_output <- function( # Subset data frame df3 <- df1[-c(1:rownum), ] colnames(df3) <- tolower(row) - # Remove any leftover NA columns if still present - NA_cols <- which(sapply(df3, function(x) all(is.na(x)))) - if (length(NA_cols) > 0) df3 <- df3[, -NA_cols] - # Remove suprper + use from df - if (any(grepl("suprper|use", colnames(df3)))) { - df3 <- df3 |> - dplyr::select(-tidyselect::any_of(c("suprper", "use"))) + } else { + # from 4rss output + df3 <- extract + colnames(df3) <- tolower(colnames(df3)) + } + + # Remove any leftover NA columns if still present + NA_cols <- which(sapply(df3, function(x) all(is.na(x)))) + if (length(NA_cols) > 0) df3 <- df3[, -NA_cols] + # Remove suprper + use from df + if (any(grepl("suprper|use", colnames(df3)))) { + df3 <- df3 |> + dplyr::select(-tidyselect::any_of(c("suprper", "use"))) + } + # Reformat data frame + if (any(colnames(df3) %in% c("Yr", "yr"))) { + df3 <- df3 |> + dplyr::rename(year = yr) + } + if ("label" %in% colnames(df3)) { + if (any(grepl("_[0-9]+$", df3$label))) { + df4 <- df3 |> + dplyr::mutate( + year = stringr::str_extract(label, "[0-9]+$"), + label = stringr::str_remove(label, "_[0-9]+$"), + # Add factors consistent with other else + area = NA, + sex = NA, + growth_pattern = NA, + fleet = NA + ) # need to remove the multiple error one } - # Reformat data frame - if (any(colnames(df3) %in% c("Yr", "yr"))) { + } else if (any(colnames(df3) %in% c(factors, errors))) { + # Keeping check here if case arises that there is a similar situation to the error + # aka there are multiple columns containing the string and they are not selected properly + + if ("sexes" %in% colnames(df3)) { df3 <- df3 |> - dplyr::rename(year = yr) - } - if ("label" %in% colnames(df3)) { - if (any(grepl("_[0-9]+$", df3$label))) { - df4 <- df3 |> - dplyr::mutate( - year = stringr::str_extract(label, "[0-9]+$"), - label = stringr::str_remove(label, "_[0-9]+$"), - # Add factors consistent with other else - area = NA, - sex = NA, - growth_pattern = NA, - fleet = NA - ) # need to remove the multiple error one - } - } else if (any(colnames(df3) %in% c(factors, errors))) { - # Keeping check here if case arises that there is a similar situation to the error - # aka there are multiple columns containing the string and they are not selected properly - - if ("sexes" %in% colnames(df3)) { - df3 <- df3 |> - # add in case if sexes is present and add sex as na if so - dplyr::mutate( - sex = dplyr::case_when( - any(grepl("^sexes$", colnames(df3))) ~ sexes, - TRUE ~ NA - ) - ) |> - dplyr::select(-sexes) - } else { - df3 <- dplyr::mutate(df3, sex = NA) - } - - df4 <- df3 |> - tidyr::pivot_longer( - !tidyselect::any_of(c(factors, errors)), - names_to = "label", - values_to = "estimate" - ) |> # , colnames(dplyr::select(df3, tidyselect::matches(errors))) + # add in case if sexes is present and add sex as na if so dplyr::mutate( - fleet = if ("fleet" %notin% colnames(df3)) { - dplyr::case_when( - # "fleet" %in% colnames(.data) ~ fleet, - grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), - TRUE ~ NA - ) - } else if ("fleet_name" %in% colnames(df3)) { - fleet_name - } else { - fleet - }, - area = if ("area" %notin% colnames(df3)) { - dplyr::case_when( - grepl("?_area_[0-9]_?", label) ~ stringr::str_extract(label, "(?<=area_)[0-9]+"), - grepl("_[0-9]_", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), - TRUE ~ NA - ) - } else { - area - }, - sex = if ("sex" %notin% colnames(df3)) { - dplyr::case_when( - grepl("_fem_", label) ~ "female", - grepl("_mal_", label) ~ "male", - grepl("_sx:1$", label) ~ "female", - grepl("_sx:2$", label) ~ "male", - grepl("_sx:1_", label) ~ "female", - grepl("_sx:2_", label) ~ "male", - TRUE ~ NA - ) - } else { - dplyr::case_when( - sex == 1 ~ "female", - sex == 2 ~ "male", - sex == 3 ~ "both", - TRUE ~ sex - ) - }, - growth_pattern = dplyr::case_when( - grepl("_gp_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - grepl("_gp:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), - grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), + sex = dplyr::case_when( + any(grepl("^sexes$", colnames(df3))) ~ sexes, TRUE ~ NA - ), - month = dplyr::case_when( - grepl("_month_[0-9]+$", label) ~ stringr::str_extract(label, "(?<=month_)[0-9]+$"), - TRUE ~ ifelse(any(grepl("^month$", colnames(df3))), month, NA) # this might remove month - ) - ) - - # if ("fleet" %in% colnames(df3)) { - # df4 <- df4 |> - # dplyr::mutate( - # fleet = dplyr::case_when( - # "fleet" %in% colnames(df3) ~ fleet, - # # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - # # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), - # TRUE ~ NA - # ), - # label = stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") - # ) - # } else { - df4 <- df4 |> - dplyr::mutate( - # fleet = dplyr::case_when( - # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), - # TRUE ~ NA - # ), - label = dplyr::case_when( - grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), - grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), - TRUE ~ stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") ) - ) - # } + ) |> + dplyr::select(-sexes) } else { - cli::cli_alert_warning(glue::glue("Data frame not compatible in {parm_sel}.")) - } - if (any(colnames(df4) %in% c("value"))) df4 <- dplyr::rename(df4, estimate = value) - - # Check if error values are in the labels column and extract out - if (any(sapply(paste0("(^|[_.])", errors, "($|[_.])"), function(x) grepl(x, unique(df4$label))))) { - err_names <- unique(df4$label)[grepl(paste(paste0("(^|[_.])", errors, "($|[_.])"), collapse = "|"), unique(df4$label)) & !unique(df4$label) %in% errors] - if (any(grepl("sel", err_names))) { - df4 <- df4 - } else if (length(intersect(errors, colnames(df4))) == 1) { - df4 <- df4[-grep(paste(errors, "_", collapse = "|", sep = ""), df4$label), ] - } else if (parm_sel == "MGparm_By_Year_after_adjustments") { # this is too specific - df4 <- df4 - cli::cli_alert_info("Error values are present, but are unique to the data frame and not to a selected parameter.") - } else { - df4 <- df4 |> - tidyr::pivot_wider( - names_from = label, - values_from = estimate, - id_cols = c(intersect(colnames(df4), factors)), - values_fill = NA - ) |> - tidyr::pivot_longer( - cols = -c(intersect(colnames(df4), factors), err_names), - names_to = "label", - values_to = "estimate" - ) |> - dplyr::select(tidyselect::any_of(c("label", "estimate", factors, errors, err_names))) - if (length(err_names) > 1) { - # warning("There are multiple reported error metrics.") - if (any(grepl(paste(err_names, collapse = "|"), colnames(df4)))) { - df4 <- df4 |> - dplyr::select(-tidyselect::all_of(err_names[2:length(err_names)])) - cli::cli_alert_info( - glue::glue("Multiple error metrics reported in {parm_sel}.") - ) - cli::cli_alert_info( - glue::glue("Error label(s) removed: \n {paste(err_names[-1], sep = '\n')}") - ) - } else { - df4 <- df4 |> - dplyr::filter(!(label %in% err_names[2:length(err_names)])) - } - # Find overlapping error values if still present - find_error_value <- function(column_names, to_match_vector) { - vals <- vapply(column_names, function(col_name) { - match <- vapply(to_match_vector, function(err) { - pattern <- paste0("(^|[_.])", err, "($|[_.])") - if (grepl(pattern, col_name)) err else NA_character_ - }, FUN.VALUE = character(1)) - stats::na.omit(match)[1] - }, FUN.VALUE = character(1)) - # } - # only unique values and those that intersect with values vector - intersect(unique(vals), to_match_vector) - } - # SS: I am not entirely sure what this step is doing, but is a good check - if (any(grepl(paste(err_names, collapse = "|"), colnames(df4)))) { - err_name <- find_error_value(names(df4), errors) - if (length(err_name) > 1) { - err_name <- stringr::str_extract(err_names[1], paste(errors, collapse = "|")) - # cli::cli_alert_info( - # glue::glue("Multiple error metrics reported in {parm_sel}. Error label(s) removed: {err_names[-1]}" - # ) - # ) - } - colnames(df4)[grepl(err_name, colnames(df4))] <- err_name - } else { - err_name <- find_error_value(unique(df4$label), errors) - colnames(df4)[grepl(paste(errors, collapse = "|"), colnames(df4))] <- err_name - } - } - } + df3 <- dplyr::mutate(df3, sex = NA) } - df5 <- df4 |> - dplyr::select(tidyselect::any_of(c("label", "estimate", "year", factors, errors))) |> + df4 <- df3 |> + tidyr::pivot_longer( + !tidyselect::any_of(c(factors, errors)), + names_to = "label", + values_to = "estimate" + ) |> # , colnames(dplyr::select(df3, tidyselect::matches(errors))) dplyr::mutate( - module_name = parm_sel, - label = dplyr::case_when( - label == "f" ~ "fishing_mortality", - TRUE ~ label + fleet = if ("fleet" %notin% colnames(df3)) { + dplyr::case_when( + # "fleet" %in% colnames(.data) ~ fleet, + grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), + TRUE ~ NA + ) + } else if ("fleet_name" %in% colnames(df3)) { + fleet_name + } else { + fleet + }, + area = if ("area" %notin% colnames(df3)) { + dplyr::case_when( + grepl("?_area_[0-9]_?", label) ~ stringr::str_extract(label, "(?<=area_)[0-9]+"), + grepl("_[0-9]_", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), + TRUE ~ NA + ) + } else { + area + }, + sex = if ("sex" %notin% colnames(df3)) { + dplyr::case_when( + grepl("_fem_", label) ~ "female", + grepl("_mal_", label) ~ "male", + grepl("_sx:1$", label) ~ "female", + grepl("_sx:2$", label) ~ "male", + grepl("_sx:1_", label) ~ "female", + grepl("_sx:2_", label) ~ "male", + TRUE ~ NA + ) + } else { + dplyr::case_when( + sex == 1 ~ "female", + sex == 2 ~ "male", + sex == 3 ~ "both", + TRUE ~ sex + ) + }, + growth_pattern = dplyr::case_when( + grepl("_gp_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + grepl("_gp:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), + grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), + TRUE ~ NA + ), + month = dplyr::case_when( + grepl("_month_[0-9]+$", label) ~ stringr::str_extract(label, "(?<=month_)[0-9]+$"), + TRUE ~ ifelse(any(grepl("^month$", colnames(df3))), month, NA) # this might remove month ) ) - if (any(colnames(df5) %in% errors)) { - df5 <- df5 |> - dplyr::mutate(uncertainty_label = intersect(names(df5), errors)) |> - dplyr::rename(uncertainty = intersect(colnames(df5), errors)) - colnames(df5) <- tolower(names(df5)) - } else { - df5 <- df5 |> - dplyr::mutate( - uncertainty_label = NA, - uncertainty = NA + # if ("fleet" %in% colnames(df3)) { + # df4 <- df4 |> + # dplyr::mutate( + # fleet = dplyr::case_when( + # "fleet" %in% colnames(df3) ~ fleet, + # # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + # # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), + # TRUE ~ NA + # ), + # label = stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") + # ) + # } else { + df4 <- df4 |> + dplyr::mutate( + # fleet = dplyr::case_when( + # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), + # TRUE ~ NA + # ), + label = dplyr::case_when( + grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), + grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), + TRUE ~ stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") ) - colnames(df5) <- tolower(names(df5)) - } - # param_df <- df5 - # if (ncol(out_new) < ncol(df5)){ - # warning(paste0("Transformed data frame for ", parm_sel, " has more columns than default.")) - # } else if (ncol(out_new) > ncol(df5)){ - # warning(paste0("Transformed data frame for ", parm_sel, " has less columns than default.")) + ) # } - if ("seas" %in% colnames(df5)) df5 <- dplyr::rename(df5, season = seas) - - if ("subseas" %in% colnames(df5)) df5 <- dplyr::rename(df5, subseason = subseas) - - if ("like" %in% colnames(df5)) df5 <- dplyr::rename(df5, likelihood = like) - - df5[setdiff(tolower(names(out_new)), tolower(names(df5)))] <- NA - if (ncol(out_new) < ncol(df5)) { - diff <- setdiff(names(df5), names(out_new)) - cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) - # warning(parm_sel, " has more columns than the output data frame. The column(s) ", paste(diff, collapse = ", ")," are not found in the standard file. It was excluded from the resulting output. Please open an issue for developer fix.") - df5 <- dplyr::select(df5, -tidyselect::all_of(c(diff))) - out_list[[parm_sel]] <- df5 - } else { - out_list[[parm_sel]] <- df5 - } - ##### STD2 #### - } else if (parm_sel %in% std2) { - # 4, 8 - # remove first row - naming - df1 <- extract[-1, ] - # check for age and length comps - rows <- df1 |> dplyr::filter_all(dplyr::any_vars(. %in% c("age_bins", "len_bins"))) - if (length(rows) > 1) { - matchr <- prodlim::row.match(rows, df1) - df1a <- df1[matchr[1]:matchr[2] - 1, ] - df1a <- Filter(function(x) !all(is.na(x)), df1a) - df1b <- df1[matchr[2]:nrow(df1), ] - df1b <- Filter(function(x) !all(is.na(x)), df1b) - df_list <- list(df1a, df1b) + } else { + cli::cli_alert_warning(glue::glue("Data frame not compatible in {parm_sel}.")) + } + if (any(colnames(df4) %in% c("value"))) df4 <- dplyr::rename(df4, estimate = value) + + # Check if error values are in the labels column and extract out + if (any(sapply(paste0("(^|[_.])", errors, "($|[_.])"), function(x) grepl(x, unique(df4$label))))) { + err_names <- unique(df4$label)[grepl(paste(paste0("(^|[_.])", errors, "($|[_.])"), collapse = "|"), unique(df4$label)) & !unique(df4$label) %in% errors] + if (any(grepl("sel", err_names))) { + df4 <- df4 + } else if (length(intersect(errors, colnames(df4))) == 1) { + df4 <- df4[-grep(paste(errors, "_", collapse = "|", sep = ""), df4$label), ] + } else if (parm_sel == "MGparm_By_Year_after_adjustments") { # this is too specific + df4 <- df4 + cli::cli_alert_info("Error values are present, but are unique to the data frame and not to a selected parameter.") } else { - # Find first row without NAs = headers - df_sel <- df1[stats::complete.cases(df1), ] - df_list <- list(df_sel) - } - comps_list <- list() - for (i in seq_along(df_list)) { - df2 <- df_list[[i]] - # identify first row - row <- tolower(df2[1, ]) - # make row the header names for first df - colnames(df2) <- row - df2 <- df2[-1, ] - # Defining columns for the grouping - if (any(grepl("len_bins", colnames(df2)))) { - std2_id <- "len_bins" - } else if (any(grepl("age_bins", colnames(df2)))) { - std2_id <- "age_bins" - } else { - std2_id <- "fleet" - } - # pivot data - if (any(grepl(":", df2[max(nrow(df2)), ]))) { - df2 <- df2[-max(nrow(df2)), ] - } else { - df2 <- df2 - } - df3 <- df2 |> + df4 <- df4 |> + tidyr::pivot_wider( + names_from = label, + values_from = estimate, + id_cols = c(intersect(colnames(df4), factors)), + values_fill = NA + ) |> tidyr::pivot_longer( - cols = -intersect(c(factors, errors, std2_id, "n_obs"), colnames(df2)), + cols = -c(intersect(colnames(df4), factors), err_names), names_to = "label", values_to = "estimate" ) |> - tidyr::pivot_wider( - names_from = tidyselect::all_of(std2_id), - values_from = estimate - ) - # if(!std2_id %in% factors){ - colnames(df3) <- stringr::str_replace(colnames(df3), "label", std2_id) - # } - if (any(duplicated(tolower(names(df3))))) { - repd_name <- names(which(table(tolower(names(df3))) > 1)) - df3 <- df3 |> - dplyr::select(-tidyselect::all_of(repd_name)) - colnames(df3) <- tolower(names(df3)) - } - if ("age_bins" %in% colnames(df3)) df3 <- dplyr::rename(df3, age = age_bins) - if (nrow(df3) > 0) { - df4 <- df3 |> - tidyr::pivot_longer( - cols = -intersect(c(factors, errors, std2_id, "n_obs"), colnames(df3)), - names_to = "label", - values_to = "estimate" - ) |> - dplyr::mutate(module_name = parm_sel) - } else { - df4 <- df3 - } - if ("seas" %in% colnames(df4)) { - df4 <- df4 |> - dplyr::rename(season = seas) - } - df4 <- dplyr::mutate(df4, module_name = parm_sel) - df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA - if (ncol(out_new) < ncol(df4)) { - diff <- setdiff(names(df4), names(out_new)) - cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) - # warning(parm_sel, " has more columns than the output data frame. The column(s) ", paste(diff, collapse = ", ")," are not found in the standard file. It was excluded from the resulting output. Please open an issue for developer fix.") - df4 <- dplyr::select(df4, -tidyselect::all_of(diff)) + dplyr::select(tidyselect::any_of(c("label", "estimate", factors, errors, err_names))) + if (length(err_names) > 1) { + # warning("There are multiple reported error metrics.") + if (any(grepl(paste(err_names, collapse = "|"), colnames(df4)))) { + df4 <- df4 |> + dplyr::select(-tidyselect::all_of(err_names[2:length(err_names)])) + cli::cli_alert_info( + glue::glue("Multiple error metrics reported in {parm_sel}.") + ) + cli::cli_alert_info( + glue::glue("Error label(s) removed: \n {paste(err_names[-1], sep = '\n')}") + ) + } else { + df4 <- df4 |> + dplyr::filter(!(label %in% err_names[2:length(err_names)])) + } + # Find overlapping error values if still present + find_error_value <- function(column_names, to_match_vector) { + vals <- vapply(column_names, function(col_name) { + match <- vapply(to_match_vector, function(err) { + pattern <- paste0("(^|[_.])", err, "($|[_.])") + if (grepl(pattern, col_name)) err else NA_character_ + }, FUN.VALUE = character(1)) + stats::na.omit(match)[1] + }, FUN.VALUE = character(1)) + # } + # only unique values and those that intersect with values vector + intersect(unique(vals), to_match_vector) + } + # SS: I am not entirely sure what this step is doing, but is a good check + if (any(grepl(paste(err_names, collapse = "|"), colnames(df4)))) { + err_name <- find_error_value(names(df4), errors) + if (length(err_name) > 1) { + err_name <- stringr::str_extract(err_names[1], paste(errors, collapse = "|")) + # cli::cli_alert_info( + # glue::glue("Multiple error metrics reported in {parm_sel}. Error label(s) removed: {err_names[-1]}" + # ) + # ) + } + colnames(df4)[grepl(err_name, colnames(df4))] <- err_name + } else { + err_name <- find_error_value(unique(df4$label), errors) + colnames(df4)[grepl(paste(errors, collapse = "|"), colnames(df4))] <- err_name + } } - comps_list[[i]] <- df4 } - # Add to new dataframe - df5 <- Reduce(rbind, comps_list) + } + + df5 <- df4 |> + dplyr::select(tidyselect::any_of(c("label", "estimate", "year", factors, errors))) |> + dplyr::mutate( + module_name = parm_sel, + label = dplyr::case_when( + label == "f" ~ "fishing_mortality", + TRUE ~ label + ) + ) + + if (any(colnames(df5) %in% errors)) { + df5 <- df5 |> + dplyr::mutate(uncertainty_label = intersect(names(df5), errors)) |> + dplyr::rename(uncertainty = intersect(colnames(df5), errors)) + colnames(df5) <- tolower(names(df5)) + } else { + df5 <- df5 |> + dplyr::mutate( + uncertainty_label = NA, + uncertainty = NA + ) + colnames(df5) <- tolower(names(df5)) + } + # param_df <- df5 + # if (ncol(out_new) < ncol(df5)){ + # warning(paste0("Transformed data frame for ", parm_sel, " has more columns than default.")) + # } else if (ncol(out_new) > ncol(df5)){ + # warning(paste0("Transformed data frame for ", parm_sel, " has less columns than default.")) + # } + if ("seas" %in% colnames(df5)) df5 <- dplyr::rename(df5, season = seas) + + if ("subseas" %in% colnames(df5)) df5 <- dplyr::rename(df5, subseason = subseas) + + if ("like" %in% colnames(df5)) df5 <- dplyr::rename(df5, likelihood = like) + + df5[setdiff(tolower(names(out_new)), tolower(names(df5)))] <- NA + if (ncol(out_new) < ncol(df5)) { + diff <- setdiff(names(df5), names(out_new)) + cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) + # warning(parm_sel, " has more columns than the output data frame. The column(s) ", paste(diff, collapse = ", ")," are not found in the standard file. It was excluded from the resulting output. Please open an issue for developer fix.") + df5 <- dplyr::select(df5, -tidyselect::all_of(c(diff))) out_list[[parm_sel]] <- df5 - - ##### cha #### - } else if (parm_sel %in% cha) { - # Only one keyword characterized as this - area_row <- which(apply(extract, 1, function(row) any(row == "Area:"))) - area_val <- c(t(extract[area_row, 3:ncol(extract)])) - gp_row <- which(apply(extract, 1, function(row) any(row == "GP:"))) - gp_val <- c(t(extract[gp_row, 3:ncol(extract)])) - df1 <- extract[-c(1:4), ] - col_name_repl <- paste(parm_sel, "_", area_val, "_", gp_val, sep = "") - colnames(df1) <- c("year", "era", col_name_repl) - df2 <- df1 |> + } else { + out_list[[parm_sel]] <- df5 + } + ##### STD2 #### + } else if (parm_sel %in% std2) { + # 4, 8 + # remove first row - naming + df1 <- extract[-1, ] + # check for age and length comps + rows <- df1 |> dplyr::filter_all(dplyr::any_vars(. %in% c("age_bins", "len_bins"))) + if (length(rows) > 1) { + matchr <- prodlim::row.match(rows, df1) + df1a <- df1[matchr[1]:matchr[2] - 1, ] + df1a <- Filter(function(x) !all(is.na(x)), df1a) + df1b <- df1[matchr[2]:nrow(df1), ] + df1b <- Filter(function(x) !all(is.na(x)), df1b) + df_list <- list(df1a, df1b) + } else { + # Find first row without NAs = headers + df_sel <- df1[stats::complete.cases(df1), ] + df_list <- list(df_sel) + } + comps_list <- list() + for (i in seq_along(df_list)) { + df2 <- df_list[[i]] + # identify first row + row <- tolower(df2[1, ]) + # make row the header names for first df + colnames(df2) <- row + df2 <- df2[-1, ] + # Defining columns for the grouping + if (any(grepl("len_bins", colnames(df2)))) { + std2_id <- "len_bins" + } else if (any(grepl("age_bins", colnames(df2)))) { + std2_id <- "age_bins" + } else { + std2_id <- "fleet" + } + # pivot data + if (any(grepl(":", df2[max(nrow(df2)), ]))) { + df2 <- df2[-max(nrow(df2)), ] + } else { + df2 <- df2 + } + df3 <- df2 |> tidyr::pivot_longer( - cols = -intersect(colnames(df1), c(factors, errors)), + cols = -intersect(c(factors, errors, std2_id, "n_obs"), colnames(df2)), names_to = "label", values_to = "estimate" ) |> - dplyr::mutate( - area = stringr::str_extract(label, "(?<=_)[0-9]+"), - growth_pattern = stringr::str_extract(label, "(?<=_)[0-9]+$"), - label = stringr::str_extract(label, "^.*?(?=_[0-9]+)"), - module_name = parm_sel + tidyr::pivot_wider( + names_from = tidyselect::all_of(std2_id), + values_from = estimate ) - df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA - if (ncol(out_new) < ncol(df2)) { - diff <- setdiff(names(df2), names(out_new)) - cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) - df2 <- dplyr::select(df2, -tidyselect::all_of(diff)) - out_list[[parm_sel]] <- df2 - } else { - out_list[[parm_sel]] <- df2 + # if(!std2_id %in% factors){ + colnames(df3) <- stringr::str_replace(colnames(df3), "label", std2_id) + # } + if (any(duplicated(tolower(names(df3))))) { + repd_name <- names(which(table(tolower(names(df3))) > 1)) + df3 <- df3 |> + dplyr::select(-tidyselect::all_of(repd_name)) + colnames(df3) <- tolower(names(df3)) } - ##### rand #### - } else if (parm_sel %in% rand) { - # KEYWORDS in RAND - # "Input_Variance_Adjustment" - # "SPR_SERIES" - # "selparm(Size)_By_Year_after_adjustments" - # "selparm(Age)_By_Year_after_adjustments" - # "BIOLOGY" - # "SPR/YPR_Profile" - # "SPAWN_RECR_CURVE" - # "Biology_at_age_in_endyr" - # "PARAMETERS" - - if (parm_sel == "SPAWN_RECR_CURVE") { - # 32 - # TODO: add this to converter - # set labels to "fitted_line_x" - # remove first row - naming - # df1 <- extract[-1, ] - # # Find first row without NAs = headers - # df2 <- df1[stats::complete.cases(df1), ] - # # identify first row - # row <- df2[1, ] - # # make row the header names for first df - # colnames(df1) <- row - # # find row number that matches 'row' - # rownum <- prodlim::row.match(row, df1) - # # Subset data frame - # df3 <- df1[-c(1:rownum), ] - # colnames(df3) <- tolower(row) - # # add year and manipulate df - # # Extract first year of recruitment - # fyr_row <- which(apply(dat, 1, function(row) any(row == "Start_year:"))) - # first_year <- dat[fyr_row,2] - # # Extract last year - # endyr_row <- which(apply(dat, 1, function(row) any(row == "End_year:"))) - # end_year <- dat[endyr_row,2] - # df4 <- df3 |> - # dplyr::mutate( - # year = seq(first_year, end_year, by = 1), - # ) - # skipping for now cuz not needed - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "SPR_SERIES") { - # split into the 3 dfs then stack - make sure all factors are present - # remove first row - naming - df1 <- extract[-1, ] - # Find first row without NAs = headers - df2 <- df1[stats::complete.cases(df1), ] - # identify first row - row <- df2[1, ] - # make row the header names for first df - colnames(df1) <- row - # find row number that matches 'row' - rownum <- prodlim::row.match(row, df1) - # Subset data frame - df3 <- df1[-(1:rownum), ] - colnames(df3) <- tolower(row) - # check if there are estimate and acual values within the df - if (any(grepl("actual", colnames(df3)) | grepl("more_f", colnames(df3)))) { - actual_col <- grep("actual", colnames(df3)) - moref_col <- grep("more_f", colnames(df3)) - # Separate out parts of the dataframe - sub_df1 <- df3[, 1:(actual_col - 1)] |> - tidyr::pivot_longer( - cols = -c(yr, era), - names_to = "label", - values_to = "estimate" - ) |> - dplyr::rename(year = yr) |> - dplyr::mutate( - label = dplyr::case_when( - label == "bio_all" ~ "biomass", - label == "bio_smry" ~ "biomass_midyear", - label == "ssbzero" ~ "spawning_biomass_zero", - # label == "ssbfished" ~ "spawning_biomass", - label == "ssbfished/r" ~ "ssbfished_r", - TRUE ~ label - ), - # label = paste("estimate_", label, sep = ""), - morph = NA - ) - - sub_df2 <- df3[, c(1:2, (actual_col + 1):(moref_col - 1))] |> - tidyr::pivot_longer( - cols = -c(yr, era), - names_to = "label", - values_to = "initial" - ) |> - dplyr::rename(year = yr) |> - dplyr::mutate( - label = dplyr::case_when( - label == "bio_all" ~ "biomass", - label == "bio_smry" ~ "biomass_midyear", - label == "num_smry" ~ "abundance_midyear", - label == "dead_catch" ~ "total_catch", # dead + retained - label == "retain_catch" ~ "landings", - label == "ssb" ~ "spawning_biomass", - label == "recruits" ~ "recruitment", - TRUE ~ label - ), - # change so that the values are placed in the column "initial" then combine w/ estimates - # label = paste("actual_", label, sep = ""), - morph = NA - ) - # combine above 2 since they show the estimate and actual values - matching - sub_df12 <- dplyr::full_join( - sub_df1, - sub_df2, - by = c("year", "era", "label", "morph") - ) - # extract last part of df - sub_df3 <- df3[, c(1:2, (moref_col + 1):ncol(df3))] |> - tidyr::pivot_longer( - cols = -c(yr, era), - names_to = "label", - values_to = "estimate" - ) |> - dplyr::rename(year = yr) |> - dplyr::mutate( - morph = dplyr::case_when( - grepl("avef_|maxf_", label) ~ stringr::str_extract(label, "[0-9]+$"), - TRUE ~ NA_character_ - ), - label = dplyr::case_when( - grepl("avef_", label) ~ stringr::str_remove(label, "_[0-9]+"), - grepl("maxf_", label) ~ stringr::str_remove(label, "_[0-9]+"), - label == "f=z-m" ~ "fishing_mortality", - TRUE ~ label - ), - initial = NA - ) - # combine all subdataframes - df4 <- rbind(sub_df12, sub_df3) |> - dplyr::mutate(module_name = parm_sel) - } else { - df4 <- df3 |> - tidyr::pivot_longer( - cols = -c(intersect(colnames(df3), c("Yr", "yr", "era"))), - names_to = "label", - values_to = "estimate" - ) |> - dplyr::rename(year = intersect(colnames(df3), c("Yr", "yr", "Year"))) |> - dplyr::mutate( - label = dplyr::case_when( - grepl("bio_all", label) ~ "biomass", - grepl("bio_smry", label) ~ "biomass_midyear", - label == "ssbzero" ~ "spawning_biomass_zero", - # label == "ssbfished" ~ "spawning_biomass", - grepl("SSB_unfished", label) ~ "SSB_unfished", - grepl("SSBfished_eq", label) ~ "SSB_fished", - label == "ssbfished/r" ~ "ssbfished_r", - TRUE ~ label - ), - # label = paste("estimate_", label, sep = ""), - morph = NA, - module_name = parm_sel - ) - } - # match to out_new - df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA - # Add to out list - out_list[[parm_sel]] <- df4 - } else if (parm_sel == "selparm(Size)_By_Year_after_adjustments") { - # TODO: revisit one day in group work - # skipping this one because there are no headers - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "selparm(Age)_By_Year_after_adjustments") { - # also skipping - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "BIOLOGY") { - # not sure how this output is helpful - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "SPR/YPR_Profile") { - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "Biology_at_age_in_endyr") { - miss_parms <- c(miss_parms, parm_sel) - next - } else if (parm_sel == "PARAMETERS") { - df1 <- extract[-1, ] - # Find first row without NAs = headers - # temp fix for catch df - df2 <- df1[stats::complete.cases(df1), ] - if (any(c("#") %in% df2[, 1])) { - full_row <- which(apply(df1, 1, function(row) is.na(row) | row == " " | row == "-" | row == "#"))[1] - df1 <- df1[-full_row[1], ] - df1 <- Filter(function(x) !all(is.na(x)), df1) - df2 <- df1[stats::complete.cases(df1), ] - } - # identify first row - row <- df2[1, ] - # make row the header names for first df - colnames(df1) <- row - # find row number that matches 'row' - rownum <- prodlim::row.match(row, df1) - # Subset data frame - df3 <- df1[-c(1:rownum), ] - colnames(df3) <- tolower(row) - # Pull out indexing variables and remove from labels + if ("age_bins" %in% colnames(df3)) df3 <- dplyr::rename(df3, age = age_bins) + if (nrow(df3) > 0) { df4 <- df3 |> - dplyr::select(intersect(colnames(df3), c("label", "value", "init", "parm_stdev"))) |> - dplyr::rename( - estimate = value, - initial = init, - uncertainty = parm_stdev + tidyr::pivot_longer( + cols = -intersect(c(factors, errors, std2_id, "n_obs"), colnames(df3)), + names_to = "label", + values_to = "estimate" ) |> + dplyr::mutate(module_name = parm_sel) + } else { + df4 <- df3 + } + if ("seas" %in% colnames(df4)) { + df4 <- df4 |> + dplyr::rename(season = seas) + } + df4 <- dplyr::mutate(df4, module_name = parm_sel) + df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA + if (ncol(out_new) < ncol(df4)) { + diff <- setdiff(names(df4), names(out_new)) + cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) + # warning(parm_sel, " has more columns than the output data frame. The column(s) ", paste(diff, collapse = ", ")," are not found in the standard file. It was excluded from the resulting output. Please open an issue for developer fix.") + df4 <- dplyr::select(df4, -tidyselect::all_of(diff)) + } + comps_list[[i]] <- df4 + } + # Add to new dataframe + df5 <- Reduce(rbind, comps_list) + out_list[[parm_sel]] <- df5 + + ##### cha #### + } else if (parm_sel %in% cha) { + # Only one keyword characterized as this + area_row <- which(apply(extract, 1, function(row) any(row == "Area:"))) + area_val <- c(t(extract[area_row, 3:ncol(extract)])) + gp_row <- which(apply(extract, 1, function(row) any(row == "GP:"))) + gp_val <- c(t(extract[gp_row, 3:ncol(extract)])) + df1 <- extract[-c(1:4), ] + col_name_repl <- paste(parm_sel, "_", area_val, "_", gp_val, sep = "") + colnames(df1) <- c("year", "era", col_name_repl) + df2 <- df1 |> + tidyr::pivot_longer( + cols = -intersect(colnames(df1), c(factors, errors)), + names_to = "label", + values_to = "estimate" + ) |> + dplyr::mutate( + area = stringr::str_extract(label, "(?<=_)[0-9]+"), + growth_pattern = stringr::str_extract(label, "(?<=_)[0-9]+$"), + label = stringr::str_extract(label, "^.*?(?=_[0-9]+)"), + module_name = parm_sel + ) + df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA + if (ncol(out_new) < ncol(df2)) { + diff <- setdiff(names(df2), names(out_new)) + cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) + df2 <- dplyr::select(df2, -tidyselect::all_of(diff)) + out_list[[parm_sel]] <- df2 + } else { + out_list[[parm_sel]] <- df2 + } + ##### rand #### + } else if (parm_sel %in% rand) { + # KEYWORDS in RAND + # "Input_Variance_Adjustment" + # "SPR_SERIES" + # "selparm(Size)_By_Year_after_adjustments" + # "selparm(Age)_By_Year_after_adjustments" + # "BIOLOGY" + # "SPR/YPR_Profile" + # "SPAWN_RECR_CURVE" + # "Biology_at_age_in_endyr" + # "PARAMETERS" + + if (parm_sel == "SPAWN_RECR_CURVE") { + # 32 + # TODO: add this to converter + # set labels to "fitted_line_x" + # remove first row - naming + # df1 <- extract[-1, ] + # # Find first row without NAs = headers + # df2 <- df1[stats::complete.cases(df1), ] + # # identify first row + # row <- df2[1, ] + # # make row the header names for first df + # colnames(df1) <- row + # # find row number that matches 'row' + # rownum <- prodlim::row.match(row, df1) + # # Subset data frame + # df3 <- df1[-c(1:rownum), ] + # colnames(df3) <- tolower(row) + # # add year and manipulate df + # # Extract first year of recruitment + # fyr_row <- which(apply(dat, 1, function(row) any(row == "Start_year:"))) + # first_year <- dat[fyr_row,2] + # # Extract last year + # endyr_row <- which(apply(dat, 1, function(row) any(row == "End_year:"))) + # end_year <- dat[endyr_row,2] + # df4 <- df3 |> + # dplyr::mutate( + # year = seq(first_year, end_year, by = 1), + # ) + # skipping for now cuz not needed + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "SPR_SERIES") { + # split into the 3 dfs then stack - make sure all factors are present + # remove first row - naming + df1 <- extract[-1, ] + # Find first row without NAs = headers + df2 <- df1[stats::complete.cases(df1), ] + # identify first row + row <- df2[1, ] + # make row the header names for first df + colnames(df1) <- row + # find row number that matches 'row' + rownum <- prodlim::row.match(row, df1) + # Subset data frame + df3 <- df1[-(1:rownum), ] + colnames(df3) <- tolower(row) + # check if there are estimate and acual values within the df + if (any(grepl("actual", colnames(df3)) | grepl("more_f", colnames(df3)))) { + actual_col <- grep("actual", colnames(df3)) + moref_col <- grep("more_f", colnames(df3)) + # Separate out parts of the dataframe + sub_df1 <- df3[, 1:(actual_col - 1)] |> + tidyr::pivot_longer( + cols = -c(yr, era), + names_to = "label", + values_to = "estimate" + ) |> + dplyr::rename(year = yr) |> dplyr::mutate( - uncertainty = dplyr::case_when( - uncertainty == "_" ~ NA, - TRUE ~ uncertainty - ), - uncertainty_label = dplyr::case_when( - is.na(uncertainty) ~ NA, - TRUE ~ "sd" - ), - area = dplyr::case_when( - grepl("?_area_[0-9]_?", label) ~ stringr::str_extract(label, "(?<=area_)[0-9]+"), - grepl("_[0-9]_", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), - TRUE ~ NA - ), - sex = dplyr::case_when( - grepl("_fem_", label) ~ "female", - grepl("_mal_", label) ~ "male", - grepl("_sx:1$", label) ~ "female", - grepl("_sx:2$", label) ~ "male", - grepl("_sx:1_", label) ~ "female", - grepl("_sx:2_", label) ~ "male", - grepl("Male", label) ~ "male", - grepl("Female", label) ~ "female", - TRUE ~ NA - ), - growth_pattern = dplyr::case_when( - grepl("_gp_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - grepl("_gp:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), - grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), - grepl("_GP_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - grepl("_GP:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), - grepl("_GP:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), - TRUE ~ NA - ), - month = dplyr::case_when( - grepl("_month_[0-9]+$", label) ~ stringr::str_extract(label, "(?<=month_)[0-9]+$"), - TRUE ~ ifelse(any(grepl("^month$", colnames(df3))), month, NA) - ), - age = dplyr::case_when( - grepl("InitAge", label) ~ stringr::str_extract(label, "(?<=InitAge_)[0-9]+"), - TRUE ~ NA - ), - year = dplyr::case_when( - grepl("RecrDev", label) ~ stringr::str_extract(label, "(?<=RecrDev_)[0-9]+$"), - grepl("_[0-9]{4}$", label) ~ stringr::str_extract(label, "[0-9]{4}$"), - TRUE ~ NA - ), - era = dplyr::case_when( - grepl("InitAge", label) ~ stringr::str_extract(label, "^.*?(?=_InitAge_[0-9]+$)"), - grepl("RecrDev", label) ~ stringr::str_extract(label, "^.*?(?=_RecrDev)"), - TRUE ~ NA + label = dplyr::case_when( + label == "bio_all" ~ "biomass", + label == "bio_smry" ~ "biomass_midyear", + label == "ssbzero" ~ "spawning_biomass_zero", + # label == "ssbfished" ~ "spawning_biomass", + label == "ssbfished/r" ~ "ssbfished_r", + TRUE ~ label ), - fleet = dplyr::case_when( - grepl( - paste( - fleet_names, - collapse = "|" - ), - label - ) ~ stringr::str_extract(label, paste0("(^.*?_)?<=|", paste(fleet_names, collapse = "|"))), - TRUE ~ NA + # label = paste("estimate_", label, sep = ""), + morph = NA + ) + + sub_df2 <- df3[, c(1:2, (actual_col + 1):(moref_col - 1))] |> + tidyr::pivot_longer( + cols = -c(yr, era), + names_to = "label", + values_to = "initial" + ) |> + dplyr::rename(year = yr) |> + dplyr::mutate( + label = dplyr::case_when( + label == "bio_all" ~ "biomass", + label == "bio_smry" ~ "biomass_midyear", + label == "num_smry" ~ "abundance_midyear", + label == "dead_catch" ~ "total_catch", # dead + retained + label == "retain_catch" ~ "landings", + label == "ssb" ~ "spawning_biomass", + label == "recruits" ~ "recruitment", + TRUE ~ label ), - block = dplyr::case_when( - grepl("_BLK[0-9]repl_[0-9]{4}$", label) ~ stringr::str_extract(label, "(?<=_BLK)[0-9](?=repl_[0-9]{4}$)"), - TRUE ~ NA + # change so that the values are placed in the column "initial" then combine w/ estimates + # label = paste("actual_", label, sep = ""), + morph = NA + ) + # combine above 2 since they show the estimate and actual values - matching + sub_df12 <- dplyr::full_join( + sub_df1, + sub_df2, + by = c("year", "era", "label", "morph") + ) + # extract last part of df + sub_df3 <- df3[, c(1:2, (moref_col + 1):ncol(df3))] |> + tidyr::pivot_longer( + cols = -c(yr, era), + names_to = "label", + values_to = "estimate" + ) |> + dplyr::rename(year = yr) |> + dplyr::mutate( + morph = dplyr::case_when( + grepl("avef_|maxf_", label) ~ stringr::str_extract(label, "[0-9]+$"), + TRUE ~ NA_character_ ), - # Must be last step in mutate bc all info comes from the label = dplyr::case_when( - grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), - grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), - grepl("InitAge", label) ~ "initial_age", - grepl("RecrDev", label) ~ "recruitment_deviations", - grepl( - paste0( - paste0( - "_", - fleet_names, - collapse = "|" - ), - "\\([0-9]+\\)_BLK[0-9]repl_[0-9]{4}$" - ), - label - ) ~ stringr::str_remove_all(label, "(Male_|Female_)|(_[[:alnum:]]+\\([0-9]+\\))|(_BLK[0-9]repl_[0-9]{4})"), - grepl("Male_|Female_", label) & grepl(paste0(paste0("_", fleet_names, collapse = "|"), "\\([0-9]+\\)"), label) ~ stringr::str_remove_all(label, "(Male_|Female_)|(_[[:alnum:]]+\\([0-9]+\\))"), - grepl(paste0(paste0("_", fleet_names, collapse = "|"), "\\([0-9]+\\)"), label) ~ stringr::str_remove(label, paste0(paste0("_", fleet_names, "\\([0-9]+\\)", collapse = "|"))), # , paste0("_", fleet_names, collapse = "|") - TRUE ~ stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") + grepl("avef_", label) ~ stringr::str_remove(label, "_[0-9]+"), + grepl("maxf_", label) ~ stringr::str_remove(label, "_[0-9]+"), + label == "f=z-m" ~ "fishing_mortality", + TRUE ~ label ), - # fix remaining labels - label = ifelse(grepl("_GP$", label), stringr::str_remove(label, "_GP$"), label), - label = ifelse(grepl("_Fem|_Mal", label), stringr::str_remove(label, "_Fem$|_Mal$"), label), - module_name = parm_sel + initial = NA ) - # match to out_new - df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA - # Add to out list - out_list[[parm_sel]] <- df4 + # combine all subdataframes + df4 <- rbind(sub_df12, sub_df3) |> + dplyr::mutate(module_name = parm_sel) } else { - miss_parms <- c(miss_parms, parm_sel) - next - } - # miss_parms <- c(miss_parms, parm_sel) - # next - #### info #### - } else if (parm_sel %in% info) { - if (parm_sel == "LIKELIHOOD") { - df1 <- extract[-1, ] - # make row the header names for first df - colnames(df1) <- df1[1, ] - # Remove first row containing column names - df2 <- df1[-1, ] |> - dplyr::rename(label = Component) |> + df4 <- df3 |> tidyr::pivot_longer( - cols = -label, - names_to = "type", - values_to = "likelihood" - ) - # match to out_new - df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA - # Add to out list - out_list[[parm_sel]] <- df2 - } else if (parm_sel == "DEFINITIONS") { - # Pull out only the first two columns and remove first row keyword - df1 <- extract[-1, 1:2] - colnames(df1) <- c("label", "estimate") - # find where rescale is located - col_rescale <- grep("rescaled_to_sum_to:", extract) - rescaled_months <- extract[4, col_rescale + 1] |> dplyr::pull() - # remove : from all labels and tolower and add in rescaled months - df2 <- df1 |> - rbind(data.frame( - label = "rescaled_months", - estimate = rescaled_months - )) |> + cols = -c(intersect(colnames(df3), c("Yr", "yr", "era"))), + names_to = "label", + values_to = "estimate" + ) |> + dplyr::rename(year = intersect(colnames(df3), c("Yr", "yr", "Year"))) |> dplyr::mutate( - label = tolower(stringr::str_remove_all(label, ":")), + label = dplyr::case_when( + grepl("bio_all", label) ~ "biomass", + grepl("bio_smry", label) ~ "biomass_midyear", + label == "ssbzero" ~ "spawning_biomass_zero", + # label == "ssbfished" ~ "spawning_biomass", + grepl("SSB_unfished", label) ~ "SSB_unfished", + grepl("SSBfished_eq", label) ~ "SSB_fished", + label == "ssbfished/r" ~ "ssbfished_r", + TRUE ~ label + ), + # label = paste("estimate_", label, sep = ""), + morph = NA, module_name = parm_sel ) - # match to out_new - df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA - # Add to out list - out_list[[parm_sel]] <- df2 - } else { - miss_parms <- c(miss_parms, parm_sel) - next } - #### aa.al #### - } else if (parm_sel %in% aa.al) { - # 8,9,11,12,13,14,15,16,28,29 - # remove first row - naming + # match to out_new + df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA + # Add to out list + out_list[[parm_sel]] <- df4 + } else if (parm_sel == "selparm(Size)_By_Year_after_adjustments") { + # TODO: revisit one day in group work + # skipping this one because there are no headers + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "selparm(Age)_By_Year_after_adjustments") { + # also skipping + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "BIOLOGY") { + # not sure how this output is helpful + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "SPR/YPR_Profile") { + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "Biology_at_age_in_endyr") { + miss_parms <- c(miss_parms, parm_sel) + next + } else if (parm_sel == "PARAMETERS") { df1 <- extract[-1, ] # Find first row without NAs = headers + # temp fix for catch df df2 <- df1[stats::complete.cases(df1), ] - # identify first row - row <- df2[1, ] - if (any(row %in% "XX")) { - loc_xx <- grep("XX", row) - row <- row[row != "XX"] - df1 <- df1[, -loc_xx] - } - - # TODO: apply this next if statement to a general process so it's part of the standard cleaning - # check if the headers make sense - # this is a temporary fix to a specific bug - # I have seen this issue in the past and I am not sure how to recognize this generally - if (any(parm_sel == "AGE_SELEX" & c("1", "2", "3") %notin% row)) { - rownum <- prodlim::row.match(row, df1) - # Subset data frame - df1 <- df1[-c(1:rownum), ] - cols_to_keep <- which(sapply(df1, function(x) !all(is.na(x)))) - df1 <- df1 |> dplyr::select(dplyr::all_of(c(names(cols_to_keep)))) + if (any(c("#") %in% df2[, 1])) { + full_row <- which(apply(df1, 1, function(row) is.na(row) | row == " " | row == "-" | row == "#"))[1] + df1 <- df1[-full_row[1], ] + df1 <- Filter(function(x) !all(is.na(x)), df1) df2 <- df1[stats::complete.cases(df1), ] - row <- df2[1, ] } - + # identify first row + row <- df2[1, ] # make row the header names for first df colnames(df1) <- row - # find row number that matches 'row' rownum <- prodlim::row.match(row, df1) # Subset data frame df3 <- df1[-c(1:rownum), ] colnames(df3) <- tolower(row) - - # aa.al names - naming <- c( - "biomass", "discard", "catch", - "f", "mean_size", "numbers", "sel", - "mean_body_wt", "natural_mortality" - ) - if (stringr::str_detect(tolower(parm_sel), paste(naming, collapse = "|"))) { - label <- stringr::str_extract(tolower(parm_sel), paste(naming, collapse = "|")) - if (length(label) > 1) cli::cli_alert_warning("Length of label is > 1.") - if (label == "f") { - label <- "fishing_mortality" - } - } - if (grepl("age", tolower(parm_sel))) { - fac <- "age" - } else if (any(grepl("length|len", tolower(parm_sel)))) { - fac <- "len_bins" - } else if (any(grepl("size", tolower(parm_sel)))) { - fac <- "age" - } else { - fac <- "age" - } - # Reformat dataframe - if (any(colnames(df3) %in% c("Yr", "yr", "year"))) { - df3 <- df3 |> - dplyr::rename(year = yr) - } - if (any(colnames(df3) %in% c("seas"))) { - df3 <- df3 |> - dplyr::rename(season = seas) - } - if (any(colnames(df3) %in% c("subseas"))) { - df3 <- df3 |> - dplyr::rename(subseason = subseas) - } - # if ("label" %in% colnames(df3)) { - # df3 <- dplyr::select(df3, -tidyselect::any_of("label")) - # } - # If factor exists, set to label - if ("factor" %in% colnames(df3)) { - df3 <- df3 |> - dplyr::select(-tidyselect::any_of("label")) |> - dplyr::rename(label = factor) - } else { - df3 <- dplyr::mutate(df3, label = label[1]) + # Pull out indexing variables and remove from labels + df4 <- df3 |> + dplyr::select(intersect(colnames(df3), c("label", "value", "init", "parm_stdev"))) |> + dplyr::rename( + estimate = value, + initial = init, + uncertainty = parm_stdev + ) |> + dplyr::mutate( + uncertainty = dplyr::case_when( + uncertainty == "_" ~ NA, + TRUE ~ uncertainty + ), + uncertainty_label = dplyr::case_when( + is.na(uncertainty) ~ NA, + TRUE ~ "sd" + ), + area = dplyr::case_when( + grepl("?_area_[0-9]_?", label) ~ stringr::str_extract(label, "(?<=area_)[0-9]+"), + grepl("_[0-9]_", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), + TRUE ~ NA + ), + sex = dplyr::case_when( + grepl("_fem_", label) ~ "female", + grepl("_mal_", label) ~ "male", + grepl("_sx:1$", label) ~ "female", + grepl("_sx:2$", label) ~ "male", + grepl("_sx:1_", label) ~ "female", + grepl("_sx:2_", label) ~ "male", + grepl("Male", label) ~ "male", + grepl("Female", label) ~ "female", + TRUE ~ NA + ), + growth_pattern = dplyr::case_when( + grepl("_gp_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + grepl("_gp:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), + grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), + grepl("_GP_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + grepl("_GP:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), + grepl("_GP:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), + TRUE ~ NA + ), + month = dplyr::case_when( + grepl("_month_[0-9]+$", label) ~ stringr::str_extract(label, "(?<=month_)[0-9]+$"), + TRUE ~ ifelse(any(grepl("^month$", colnames(df3))), month, NA) + ), + age = dplyr::case_when( + grepl("InitAge", label) ~ stringr::str_extract(label, "(?<=InitAge_)[0-9]+"), + TRUE ~ NA + ), + year = dplyr::case_when( + grepl("RecrDev", label) ~ stringr::str_extract(label, "(?<=RecrDev_)[0-9]+$"), + grepl("_[0-9]{4}$", label) ~ stringr::str_extract(label, "[0-9]{4}$"), + TRUE ~ NA + ), + era = dplyr::case_when( + grepl("InitAge", label) ~ stringr::str_extract(label, "^.*?(?=_InitAge_[0-9]+$)"), + grepl("RecrDev", label) ~ stringr::str_extract(label, "^.*?(?=_RecrDev)"), + TRUE ~ NA + ), + fleet = dplyr::case_when( + grepl( + paste( + fleet_names, + collapse = "|" + ), + label + ) ~ stringr::str_extract(label, paste0("(^.*?_)?<=|", paste(fleet_names, collapse = "|"))), + TRUE ~ NA + ), + block = dplyr::case_when( + grepl("_BLK[0-9]repl_[0-9]{4}$", label) ~ stringr::str_extract(label, "(?<=_BLK)[0-9](?=repl_[0-9]{4}$)"), + TRUE ~ NA + ), + # Must be last step in mutate bc all info comes from the + label = dplyr::case_when( + grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), + grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), + grepl("InitAge", label) ~ "initial_age", + grepl("RecrDev", label) ~ "recruitment_deviations", + grepl( + paste0( + paste0( + "_", + fleet_names, + collapse = "|" + ), + "\\([0-9]+\\)_BLK[0-9]repl_[0-9]{4}$" + ), + label + ) ~ stringr::str_remove_all(label, "(Male_|Female_)|(_[[:alnum:]]+\\([0-9]+\\))|(_BLK[0-9]repl_[0-9]{4})"), + grepl("Male_|Female_", label) & grepl(paste0(paste0("_", fleet_names, collapse = "|"), "\\([0-9]+\\)"), label) ~ stringr::str_remove_all(label, "(Male_|Female_)|(_[[:alnum:]]+\\([0-9]+\\))"), + grepl(paste0(paste0("_", fleet_names, collapse = "|"), "\\([0-9]+\\)"), label) ~ stringr::str_remove(label, paste0(paste0("_", fleet_names, "\\([0-9]+\\)", collapse = "|"))), # , paste0("_", fleet_names, collapse = "|") + TRUE ~ stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") + ), + # fix remaining labels + label = ifelse(grepl("_GP$", label), stringr::str_remove(label, "_GP$"), label), + label = ifelse(grepl("_Fem|_Mal", label), stringr::str_remove(label, "_Fem$|_Mal$"), label), + module_name = parm_sel + ) + # match to out_new + df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA + # Add to out list + out_list[[parm_sel]] <- df4 + } else { + miss_parms <- c(miss_parms, parm_sel) + next + } + # miss_parms <- c(miss_parms, parm_sel) + # next + #### info #### + } else if (parm_sel %in% info) { + if (parm_sel == "LIKELIHOOD") { + df1 <- extract[-1, ] + # make row the header names for first df + colnames(df1) <- df1[1, ] + # Remove first row containing column names + df2 <- df1[-1, ] |> + dplyr::rename(label = Component) |> + tidyr::pivot_longer( + cols = -label, + names_to = "type", + values_to = "likelihood" + ) + # match to out_new + df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA + # Add to out list + out_list[[parm_sel]] <- df2 + } else if (parm_sel == "DEFINITIONS") { + # Pull out only the first two columns and remove first row keyword + df1 <- extract[-1, 1:2] + colnames(df1) <- c("label", "estimate") + # find where rescale is located + col_rescale <- grep("rescaled_to_sum_to:", extract) + rescaled_months <- extract[4, col_rescale + 1] |> dplyr::pull() + # remove : from all labels and tolower and add in rescaled months + df2 <- df1 |> + rbind(data.frame( + label = "rescaled_months", + estimate = rescaled_months + )) |> + dplyr::mutate( + label = tolower(stringr::str_remove_all(label, ":")), + module_name = parm_sel + ) + # match to out_new + df2[setdiff(tolower(names(out_new)), tolower(names(df2)))] <- NA + # Add to out list + out_list[[parm_sel]] <- df2 + } else { + miss_parms <- c(miss_parms, parm_sel) + next + } + #### aa.al #### + } else if (parm_sel %in% aa.al) { + # 8,9,11,12,13,14,15,16,28,29 + # remove first row - naming + df1 <- extract[-1, ] + # Find first row without NAs = headers + df2 <- df1[stats::complete.cases(df1), ] + # identify first row + row <- df2[1, ] + if (any(row %in% "XX")) { + loc_xx <- grep("XX", row) + row <- row[row != "XX"] + df1 <- df1[, -loc_xx] + } + + # TODO: apply this next if statement to a general process so it's part of the standard cleaning + # check if the headers make sense + # this is a temporary fix to a specific bug + # I have seen this issue in the past and I am not sure how to recognize this generally + if (any(parm_sel == "AGE_SELEX" & c("1", "2", "3") %notin% row)) { + rownum <- prodlim::row.match(row, df1) + # Subset data frame + df1 <- df1[-c(1:rownum), ] + cols_to_keep <- which(sapply(df1, function(x) !all(is.na(x)))) + df1 <- df1 |> dplyr::select(dplyr::all_of(c(names(cols_to_keep)))) + df2 <- df1[stats::complete.cases(df1), ] + row <- df2[1, ] + } + + # make row the header names for first df + colnames(df1) <- row + + # find row number that matches 'row' + rownum <- prodlim::row.match(row, df1) + # Subset data frame + df3 <- df1[-c(1:rownum), ] + colnames(df3) <- tolower(row) + + # aa.al names + naming <- c( + "biomass", "discard", "catch", + "f", "mean_size", "numbers", "sel", + "mean_body_wt", "natural_mortality" + ) + if (stringr::str_detect(tolower(parm_sel), paste(naming, collapse = "|"))) { + label <- stringr::str_extract(tolower(parm_sel), paste(naming, collapse = "|")) + if (length(label) > 1) cli::cli_alert_warning("Length of label is > 1.") + if (label == "f") { + label <- "fishing_mortality" } - # Change all columns to chatacters to a avoid issues in pivoting - this will be changed in final df anyway + } + if (grepl("age", tolower(parm_sel))) { + fac <- "age" + } else if (any(grepl("length|len", tolower(parm_sel)))) { + fac <- "len_bins" + } else if (any(grepl("size", tolower(parm_sel)))) { + fac <- "age" + } else { + fac <- "age" + } + # Reformat dataframe + if (any(colnames(df3) %in% c("Yr", "yr", "year"))) { df3 <- df3 |> - dplyr::mutate(dplyr::across(tidyselect::everything(), as.character)) - # Set all columns after factors as numeric - # Identify last factor col - other_factors <- c( - "bio_pattern", "birthseas", - "settlement", "morph", "beg/mid", - "type", "label", "label", - "platoon", "month", - "sexes", "part", "bin", "kind" - ) - num_cols <- setdiff(colnames(df3), c(factors, other_factors)) + dplyr::rename(year = yr) + } + if (any(colnames(df3) %in% c("seas"))) { df3 <- df3 |> - dplyr::mutate(dplyr::across(dplyr::all_of(num_cols), as.numeric)) - # Pivot table long - df4 <- df3 |> - tidyr::pivot_longer( - cols = -intersect(c(factors, errors, other_factors), colnames(df3)), - names_to = fac[1], - values_to = "estimate" - ) |> + dplyr::rename(season = seas) + } + if (any(colnames(df3) %in% c("subseas"))) { + df3 <- df3 |> + dplyr::rename(subseason = subseas) + } + # if ("label" %in% colnames(df3)) { + # df3 <- dplyr::select(df3, -tidyselect::any_of("label")) + # } + # If factor exists, set to label + if ("factor" %in% colnames(df3)) { + df3 <- df3 |> + dplyr::select(-tidyselect::any_of("label")) |> + dplyr::rename(label = factor) + } else { + df3 <- dplyr::mutate(df3, label = label[1]) + } + # Change all columns to chatacters to a avoid issues in pivoting - this will be changed in final df anyway + df3 <- df3 |> + dplyr::mutate(dplyr::across(tidyselect::everything(), as.character)) + # Set all columns after factors as numeric + # Identify last factor col + other_factors <- c( + "bio_pattern", "birthseas", + "settlement", "morph", "beg/mid", + "type", "label", "label", + "platoon", "month", + "sexes", "part", "bin", "kind" + ) + num_cols <- setdiff(colnames(df3), c(factors, other_factors)) + df3 <- df3 |> + dplyr::mutate(dplyr::across(dplyr::all_of(num_cols), as.numeric)) + # Pivot table long + df4 <- df3 |> + tidyr::pivot_longer( + cols = -intersect(c(factors, errors, other_factors), colnames(df3)), + names_to = fac[1], + values_to = "estimate" + ) |> + dplyr::mutate( + # label = label[1], + module_name = parm_sel[1] + ) + if ("sex" %in% colnames(df4)) { + df4 <- df4 |> dplyr::mutate( - # label = label[1], - module_name = parm_sel[1] + sex = dplyr::case_when( + "sex" %in% colnames(df3) & sex == 1 ~ "female", + "sex" %in% colnames(df3) & sex == 2 ~ "male" + ) ) - if ("sex" %in% colnames(df4)) { + } + if (any(grepl("morph", colnames(df4)))) { + df4 <- df4 |> + dplyr::rename(growth_pattern = morph) + } + # Check if likelihood is in the df + if (any(grepl("like", colnames(df4)))) { + df4 <- df4 |> + dplyr::rename(likelihood = like) + } + # Check for error in the df + if (any(grepl(paste0("^", errors, "$", collapse = "|"), colnames(df4)))) { + error_col <- colnames(df4)[grep(paste0("^", errors, "$", collapse = "|"), colnames(df4))] + if (length(error_col) > 1) { + cli::cli_alert("Multiple error columns present. Error will not be added to module.") + } else { df4 <- df4 |> dplyr::mutate( - sex = dplyr::case_when( - "sex" %in% colnames(df3) & sex == 1 ~ "female", - "sex" %in% colnames(df3) & sex == 2 ~ "male" - ) + uncertainty_label = tolower(unique(error_col)), + uncertainty = df4[[error_col]] ) } - if (any(grepl("morph", colnames(df4)))) { - df4 <- df4 |> - dplyr::rename(growth_pattern = morph) - } - # Check if likelihood is in the df - if (any(grepl("like", colnames(df4)))) { - df4 <- df4 |> - dplyr::rename(likelihood = like) - } - # Check for error in the df - if (any(grepl(paste0("^", errors, "$", collapse = "|"), colnames(df4)))) { - error_col <- colnames(df4)[grep(paste0("^", errors, "$", collapse = "|"), colnames(df4))] - if (length(error_col) > 1) { - cli::cli_alert("Multiple error columns present. Error will not be added to module.") - } else { - df4 <- df4 |> - dplyr::mutate( - uncertainty_label = tolower(unique(error_col)), - uncertainty = df4[[error_col]] - ) - } - } - if ("label" %in% colnames(df4) & "factor" %in% colnames(df4)) { - df4 <- df4 |> - dplyr::select(-label) |> - dplyr::mutate(label = dplyr::case_when( - grepl("sel", factor) ~ "sel", - TRUE ~ factor - )) |> - dplyr::select(-factor) - } - # Bind to new df - df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA - if (ncol(out_new) < ncol(df4)) { - diff <- setdiff(names(df4), names(out_new)) - cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) - # warning(parm_sel, " has more columns than the output data frame. The column(s) ", paste(diff, collapse = ", ")," are not found in the standard file. It was excluded from the resulting output. Please open an issue for developer fix.") - df4 <- dplyr::select(df4, -tidyselect::all_of(diff)) - out_list[[parm_sel]] <- df4 - } else { - out_list[[parm_sel]] <- df4 - } - # } else if (parm_sel %in% nn) { - # miss_parms <- c(miss_parms, parm_sel) - # next + } + if ("label" %in% colnames(df4) & "factor" %in% colnames(df4)) { + df4 <- df4 |> + dplyr::select(-label) |> + dplyr::mutate(label = dplyr::case_when( + grepl("sel", factor) ~ "sel", + TRUE ~ factor + )) |> + dplyr::select(-factor) + } + # Bind to new df + df4[setdiff(tolower(names(out_new)), tolower(names(df4)))] <- NA + if (ncol(out_new) < ncol(df4)) { + diff <- setdiff(names(df4), names(out_new)) + cli::cli_alert_info(paste0("FACTORS REMOVED: ", parm_sel, " - ", paste(diff, collapse = ", "))) + # warning(parm_sel, " has more columns than the output data frame. The column(s) ", paste(diff, collapse = ", ")," are not found in the standard file. It was excluded from the resulting output. Please open an issue for developer fix.") + df4 <- dplyr::select(df4, -tidyselect::all_of(diff)) + out_list[[parm_sel]] <- df4 } else { - cli::cli_alert_info(glue::glue("Processing {parm_sel}")) - miss_parms <- c(miss_parms, parm_sel) - next + out_list[[parm_sel]] <- df4 } - } # close if param is in output file - } else { - cli::cli_alert(glue::glue("Skipped {parm_sel}")) - next - } - } # close loop - if (length(miss_parms) > 0) { - cli::cli_alert_info( - paste0("Some parameters were not found or included in the output file. The following parameters were not added into the new output file: \n", paste(miss_parms, collapse = "\n")) - ) + # } else if (parm_sel %in% nn) { + # miss_parms <- c(miss_parms, parm_sel) + # next + } else { + cli::cli_alert_info(glue::glue("Processing {parm_sel}")) + miss_parms <- c(miss_parms, parm_sel) + next + } + } # close if param is in output file + } else { + cli::cli_alert(glue::glue("Skipped {parm_sel}")) + next } - out_new <- Reduce(rbind, out_list) - out_new <- out_new |> - dplyr::mutate(fleet = dplyr::case_when( - any(unique(out_new$fleet) %in% fleet_names) ~ fleet, - TRUE ~ fleet_names[fleet] - )) - } else { - #### r4ss #### - dat <- file - select_modules <- c( - "recruit", - "SPAWN_RECRUIT_CURVE", - "Natural_Mortality", - "growth_series", - "sizeselex", - "ageselex", - "exploitation", - "catch"," - timeseries", - "discard", - "mngwt", # ??? - "sprseries", - "sprtarg", - "btarg", - "kobe", - "cpue", - "natage", - "batage", - "natlen", - "batlen", - "fatage", - "discard_at_age", - "catage", - "equil_yeild", - "Z_at_age", - "M_at_age", - "Z_by_area", - "M_by_area", - "Dynamic_Bzero", - "len_comp_fit_table", - "age_comp_fit_table", - "derived_quants", - "parameters", - "SBzero" + } # close loop + if (length(miss_parms) > 0) { + cli::cli_alert_info( + paste0("Some parameters were not found or included in the output file. The following parameters were not added into the new output file: \n", paste(miss_parms, collapse = "\n")) ) } - + out_new <- Reduce(rbind, out_list) + out_new <- out_new |> + dplyr::mutate(fleet = dplyr::case_when( + any(unique(out_new$fleet) %in% fleet_names) ~ fleet, + TRUE ~ fleet_names[fleet] + )) } else if (model %in% c("bam", "BAM")) { #### BAM #### # Extract values from BAM output - model file after following ADMB2R From 8cbdf34ab71a7db732b57f0b131fde04bb6f8136 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Mon, 29 Jun 2026 16:02:21 -0400 Subject: [PATCH 04/28] add more labels for categorization --- R/convert_output.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index 47b69019..46cc8854 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -297,9 +297,9 @@ convert_output <- function( "mngwt", # ??? "sprseries", # RAND "sprtarg", # single value - "btarg", - "kobe", - "cpue", + "btarg", # single value + "kobe", # maybe STD + "cpue", # STD "natage", "batage", "natlen", From 4fc5aa501417baa7488a65691a5c276f96e9449b Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Wed, 1 Jul 2026 10:30:48 -0400 Subject: [PATCH 05/28] categorize naming from r4ss::ss_output in same convention as report.sso approach --- R/convert_output.R | 119 +++++++++++++-------------------------------- 1 file changed, 35 insertions(+), 84 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index 46cc8854..404caf4b 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -46,12 +46,6 @@ convert_output <- function( ) { # check if entered save_dir exists so doesn't waste user time finding this out at the end if (!is.null(save_dir)) { - # if (!dir.exists(stringr::str_extract(save_dir, "^.*/(?=[^/]+\\.[^/]+$)") |> stringr::str_remove("/$"))) { - # cli::cli_abort("save_dir not a valid path.") - # } else { - # # create new save_dir with file name - # save_dir <- file.path(save_dir, "std_output.rda") - # } if (!grepl(".rda", save_dir)) { cli::cli_alert("save_dir does not contain a file name. Saved output will be named `std_output.rda`.") save_dir <- file.path(save_dir, "std_output.rda") @@ -283,96 +277,53 @@ convert_output <- function( cli::cli_alert_info("Identified fleet names:") cli::cli_alert_info("{fleet_names}") - param_names <- c( - "recruit", - "SPAWN_RECRUIT_CURVE", # RAND - "Natural_Mortality", # AA.AL - "growth_series", # ? UNSURE THIS IS NULL IN EXAMPLE - "sizeselex", # AA.AL - "ageselex", # AA.AL + param_names <- names(dat) + + std <- c( + "recruit", # STD "exploitation", # STD "catch", # STD "timeseries", # STD "discard", # STD - "mngwt", # ??? - "sprseries", # RAND - "sprtarg", # single value - "btarg", # single value "kobe", # maybe STD "cpue", # STD - "natage", - "batage", - "natlen", - "batlen", - "fatage", # AA.AL - "discard_at_age", - "catage", - "equil_yeild", - "Z_at_age", - "M_at_age", - "Z_by_area", - "M_by_area", - "Dynamic_Bzero", - "len_comp_fit_table", - "age_comp_fit_table", "derived_quants", #STD - "parameters", # RAND - "SBzero" - ) - # Group parameters base on table pattern - std <- c( - "DERIVED_QUANTITIES", - "MGparm_By_Year_after_adjustments", - "CATCH", - "SPAWN_RECRUIT", - "TIME_SERIES", - "DISCARD_OUTPUT", - "INDEX_2", - "FIT_LEN_COMPS", - "FIT_AGE_COMPS", - "FIT_SIZE_COMPS", - "SELEX_database", - "Growth_Parameters", - "Kobe_Plot" + "Dynamic_Bzero", # STD + "len_comp_fit_table", # STD + "age_comp_fit_table" # STD ) - std2 <- c("OVERALL_COMPS") - cha <- c("Dynamic_Bzero") rand <- c( - "Input_Variance_Adjustment", - "SPR_SERIES", - "selparm(Size)_By_Year_after_adjustments", - "selparm(Age)_By_Year_after_adjustments", - "BIOLOGY", - "SPR/YPR_Profile", - "Biology_at_age_in_endyr", - "SPAWN_RECR_CURVE", - "PARAMETERS" - ) - info <- c( - "LIKELIHOOD", - "DEFINITIONS" + "SPAWN_RECRUIT_CURVE", # RAND + "sprseries", # RAND + "parameters" # RAND + # "equil_yeild", # SKIP FOR NOW - RAND ) aa.al <- c( - "BIOMASS_AT_AGE", - "BIOMASS_AT_LENGTH", - "DISCARD_AT_AGE", - "CATCH_AT_AGE", - "F_AT_AGE", - "MEAN_SIZE_TIMESERIES", - "NUMBERS_AT_AGE", - "NUMBERS_AT_LENGTH", - "AGE_SELEX", - "LEN_SELEX", - "MEAN_BODY_WT(Begin)", - "Natural_Mortality" + "sizeselex", # AA.AL + "ageselex", # AA.AL + "Natural_Mortality", # AA.AL + "fatage", # AA.AL + "natage", # AA.AL + "batage", # AA.AL + "natlen", # AA.AL + "batlen", # AA.AL + "discard_at_age", # AA.AL + "catage", # AA.AL + "Z_at_age", # AA.AL - DO WE NEED BOTH? THIS AND Z_BY_AREA + "M_at_age", # AA.AL - DO WE NEED BOTH? THIS AND M_BY_AREA + "Z_by_area", # AA.AL + "M_by_area" # AA.AL ) - nn <- c( - "MORPH_INDEXING", - "EXPLOITATION", - "DISCARD_SPECIFICATION", - "INDEX_1", - "MEAN_BODY_WT_OUTPUT" + # "growth_series" # ? UNSURE THIS IS NULL IN EXAMPLE + # "mngwt" # ??? + single_val <- c( + "sprtarg", # single value + "btarg", # single value + "SBzero" # SINGLE VALUE ) + # ntentionally empty + std2 <- c() + cha <- c() } # Extract units @@ -405,7 +356,7 @@ convert_output <- function( for (i in seq_along(param_names)) { # Processing data frame parm_sel <- param_names[i] - if (parm_sel %in% c(std, std2, cha, rand, aa.al)) { + if (parm_sel %in% c(std, std2, cha, rand, aa.al, single_val)) { cli::cli_alert(glue::glue("Processing {parm_sel}")) if(is.character(file)) { extract <- SS3_extract_df(dat, parm_sel) From 92fb52c91f66e6f1ea62f4d8f0da9f684cdeab7b Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Wed, 1 Jul 2026 11:16:40 -0400 Subject: [PATCH 06/28] Add specific conditions in module groupings for approaching initial df before manipulation; add missing grouping to keep consistent bewteen r4ss and report file --- R/convert_output.R | 175 +++++++++++++++++++++++++++------------------ 1 file changed, 104 insertions(+), 71 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index 404caf4b..26a562d6 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -266,6 +266,8 @@ convert_output <- function( "INDEX_1", "MEAN_BODY_WT_OUTPUT" ) + # Intentionally left empty + single_val <- c() } else { # r4ss::ss_output dat <- file @@ -324,6 +326,7 @@ convert_output <- function( # ntentionally empty std2 <- c() cha <- c() + info <- c() } # Extract units @@ -357,7 +360,7 @@ convert_output <- function( # Processing data frame parm_sel <- param_names[i] if (parm_sel %in% c(std, std2, cha, rand, aa.al, single_val)) { - cli::cli_alert(glue::glue("Processing {parm_sel}")) + cli::cli_alert(glue::glue("[{i}] Processing {parm_sel}")) if(is.character(file)) { extract <- SS3_extract_df(dat, parm_sel) } else { @@ -504,10 +507,15 @@ convert_output <- function( grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), TRUE ~ NA ), - month = dplyr::case_when( - grepl("_month_[0-9]+$", label) ~ stringr::str_extract(label, "(?<=month_)[0-9]+$"), - TRUE ~ ifelse(any(grepl("^month$", colnames(df3))), month, NA) # this might remove month - ) + month = { + if ("month" %in% colnames(df3)) { + month + } else if (grepl("_month_[0-9]+$", label)) { + stringr::str_extract(label, "(?<=month_)[0-9]+$") + } else { + ifelse(any(grepl("^month$", colnames(df3))), month, NA) # this might remove month + } + } ) # if ("fleet" %in% colnames(df3)) { @@ -791,7 +799,7 @@ convert_output <- function( # "Biology_at_age_in_endyr" # "PARAMETERS" - if (parm_sel == "SPAWN_RECR_CURVE") { + if (parm_sel %in% c("SPAWN_RECR_CURVE", "SPAWN_RECRUIT_CURVE")) { # 32 # TODO: add this to converter # set labels to "fitted_line_x" @@ -822,21 +830,27 @@ convert_output <- function( # skipping for now cuz not needed miss_parms <- c(miss_parms, parm_sel) next - } else if (parm_sel == "SPR_SERIES") { - # split into the 3 dfs then stack - make sure all factors are present - # remove first row - naming - df1 <- extract[-1, ] - # Find first row without NAs = headers - df2 <- df1[stats::complete.cases(df1), ] - # identify first row - row <- df2[1, ] - # make row the header names for first df - colnames(df1) <- row - # find row number that matches 'row' - rownum <- prodlim::row.match(row, df1) - # Subset data frame - df3 <- df1[-(1:rownum), ] - colnames(df3) <- tolower(row) + } else if (parm_sel %in% c("sprseries", "SPR_SERIES")) { + if (is.character(file)) { + # split into the 3 dfs then stack - make sure all factors are present + # remove first row - naming + df1 <- extract[-1, ] + # Find first row without NAs = headers + df2 <- df1[stats::complete.cases(df1), ] + # identify first row + row <- df2[1, ] + # make row the header names for first df + colnames(df1) <- row + # find row number that matches 'row' + rownum <- prodlim::row.match(row, df1) + # Subset data frame + df3 <- df1[-(1:rownum), ] + colnames(df3) <- tolower(row) + } else { + df3 <- extract + colnames(df3) <- tolower(colnames(df3)) + } + # check if there are estimate and acual values within the df if (any(grepl("actual", colnames(df3)) | grepl("more_f", colnames(df3)))) { actual_col <- grep("actual", colnames(df3)) @@ -961,26 +975,32 @@ convert_output <- function( } else if (parm_sel == "Biology_at_age_in_endyr") { miss_parms <- c(miss_parms, parm_sel) next - } else if (parm_sel == "PARAMETERS") { - df1 <- extract[-1, ] - # Find first row without NAs = headers - # temp fix for catch df - df2 <- df1[stats::complete.cases(df1), ] - if (any(c("#") %in% df2[, 1])) { - full_row <- which(apply(df1, 1, function(row) is.na(row) | row == " " | row == "-" | row == "#"))[1] - df1 <- df1[-full_row[1], ] - df1 <- Filter(function(x) !all(is.na(x)), df1) + } else if (tolower(parm_sel) == "parameters") { + if (is.character(file)) { + df1 <- extract[-1, ] + # Find first row without NAs = headers + # temp fix for catch df df2 <- df1[stats::complete.cases(df1), ] + if (any(c("#") %in% df2[, 1])) { + full_row <- which(apply(df1, 1, function(row) is.na(row) | row == " " | row == "-" | row == "#"))[1] + df1 <- df1[-full_row[1], ] + df1 <- Filter(function(x) !all(is.na(x)), df1) + df2 <- df1[stats::complete.cases(df1), ] + } + # identify first row + row <- df2[1, ] + # make row the header names for first df + colnames(df1) <- row + # find row number that matches 'row' + rownum <- prodlim::row.match(row, df1) + # Subset data frame + df3 <- df1[-c(1:rownum), ] + colnames(df3) <- tolower(row) + } else { + df3 <- extract + colnames(df3) <- tolower(colnames(df3)) } - # identify first row - row <- df2[1, ] - # make row the header names for first df - colnames(df1) <- row - # find row number that matches 'row' - rownum <- prodlim::row.match(row, df1) - # Subset data frame - df3 <- df1[-c(1:rownum), ] - colnames(df3) <- tolower(row) + # Pull out indexing variables and remove from labels df4 <- df3 |> dplyr::select(intersect(colnames(df3), c("label", "value", "init", "parm_stdev"))) |> @@ -1139,41 +1159,46 @@ convert_output <- function( #### aa.al #### } else if (parm_sel %in% aa.al) { # 8,9,11,12,13,14,15,16,28,29 - # remove first row - naming - df1 <- extract[-1, ] - # Find first row without NAs = headers - df2 <- df1[stats::complete.cases(df1), ] - # identify first row - row <- df2[1, ] - if (any(row %in% "XX")) { - loc_xx <- grep("XX", row) - row <- row[row != "XX"] - df1 <- df1[, -loc_xx] - } - - # TODO: apply this next if statement to a general process so it's part of the standard cleaning - # check if the headers make sense - # this is a temporary fix to a specific bug - # I have seen this issue in the past and I am not sure how to recognize this generally - if (any(parm_sel == "AGE_SELEX" & c("1", "2", "3") %notin% row)) { - rownum <- prodlim::row.match(row, df1) - # Subset data frame - df1 <- df1[-c(1:rownum), ] - cols_to_keep <- which(sapply(df1, function(x) !all(is.na(x)))) - df1 <- df1 |> dplyr::select(dplyr::all_of(c(names(cols_to_keep)))) + if (is.character(file)) { + # remove first row - naming + df1 <- extract[-1, ] + # Find first row without NAs = headers df2 <- df1[stats::complete.cases(df1), ] + # identify first row row <- df2[1, ] + if (any(row %in% "XX")) { + loc_xx <- grep("XX", row) + row <- row[row != "XX"] + df1 <- df1[, -loc_xx] + } + + # TODO: apply this next if statement to a general process so it's part of the standard cleaning + # check if the headers make sense + # this is a temporary fix to a specific bug + # I have seen this issue in the past and I am not sure how to recognize this generally + if (any(parm_sel == "AGE_SELEX" & c("1", "2", "3") %notin% row)) { + rownum <- prodlim::row.match(row, df1) + # Subset data frame + df1 <- df1[-c(1:rownum), ] + cols_to_keep <- which(sapply(df1, function(x) !all(is.na(x)))) + df1 <- df1 |> dplyr::select(dplyr::all_of(c(names(cols_to_keep)))) + df2 <- df1[stats::complete.cases(df1), ] + row <- df2[1, ] + } + + # make row the header names for first df + colnames(df1) <- row + + # find row number that matches 'row' + rownum <- prodlim::row.match(row, df1) + # Subset data frame + df3 <- df1[-c(1:rownum), ] + colnames(df3) <- tolower(row) + } else { + df3 <- extract + colnames(df3) <- tolower(colnames(df3)) } - # make row the header names for first df - colnames(df1) <- row - - # find row number that matches 'row' - rownum <- prodlim::row.match(row, df1) - # Subset data frame - df3 <- df1[-c(1:rownum), ] - colnames(df3) <- tolower(row) - # aa.al names naming <- c( "biomass", "discard", "catch", @@ -1306,8 +1331,16 @@ convert_output <- function( next } } # close if param is in output file + } else if (parm_sel %in% single_val) { + df <- data.frame( + label = parm_sel, + estimate = extract[[1]], + module_name = parm_sel + ) + df[setdiff(tolower(names(out_new)), tolower(names(df)))] <- NA + out_list[[parm_sel]] <- df } else { - cli::cli_alert(glue::glue("Skipped {parm_sel}")) + if (is.character(file)) cli::cli_alert(glue::glue("Skipped [{i}] {parm_sel}")) next } } # close loop From 00e0f16fb284dc272e39036f803942d41846a0f7 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Wed, 1 Jul 2026 11:27:45 -0400 Subject: [PATCH 07/28] replace case_when with if statements in parts of converter per suggestion from dplyr: --- R/convert_output.R | 127 +++++++++++++++++++++++---------------------- 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index 26a562d6..a277f978 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -460,53 +460,74 @@ convert_output <- function( values_to = "estimate" ) |> # , colnames(dplyr::select(df3, tidyselect::matches(errors))) dplyr::mutate( - fleet = if ("fleet" %notin% colnames(df3)) { - dplyr::case_when( - # "fleet" %in% colnames(.data) ~ fleet, - grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), - TRUE ~ NA - ) - } else if ("fleet_name" %in% colnames(df3)) { - fleet_name - } else { - fleet + fleet = { + if ("fleet" %in% colnames(df3)) { + fleet + } else if ("fleet_name" %in% colnames(df3)) { + fleet_name + } else if (grepl(":_[0-9]$", label)) { + stringr::str_extract(label, "(?<=_)[0-9]+") + } else if (grepl(":_[0-9][0-9]$", label)) { + stringr::str_extract(label, "(?<=_)[0-9][0-9]+") + } else { + NA + } }, - area = if ("area" %notin% colnames(df3)) { - dplyr::case_when( - grepl("?_area_[0-9]_?", label) ~ stringr::str_extract(label, "(?<=area_)[0-9]+"), - grepl("_[0-9]_", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), - grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), - TRUE ~ NA - ) - } else { - area + area = { + if ("area" %in% colnames(df3)) { + area + } else if (grepl("?_area_[0-9]_?", label)) { + stringr::str_extract(label, "(?<=area_)[0-9]+") + } else if (grepl("_[0-9]_", label)) { + stringr::str_extract(label, "(?<=_)[0-9]+") + } else if (grepl(":_[0-9]$", label)) { + stringr::str_extract(label, "(?<=_)[0-9]+") + } else if (grepl(":_[0-9][0-9]$", label)) { + stringr::str_extract(label, "(?<=_)[0-9][0-9]+") + } else { + NA + } }, - sex = if ("sex" %notin% colnames(df3)) { - dplyr::case_when( - grepl("_fem_", label) ~ "female", - grepl("_mal_", label) ~ "male", - grepl("_sx:1$", label) ~ "female", - grepl("_sx:2$", label) ~ "male", - grepl("_sx:1_", label) ~ "female", - grepl("_sx:2_", label) ~ "male", - TRUE ~ NA - ) - } else { - dplyr::case_when( - sex == 1 ~ "female", - sex == 2 ~ "male", - sex == 3 ~ "both", - TRUE ~ sex - ) + sex = { + if ("sex" %in% colnames(df3)) { + if (sex == 1) { + "female" + } else if (sex == 2) { + "male" + } else if (sex == 3) { + "both" + } else { + sex + } + } else if (grepl("_fem_", label)) { + "female" + } else if (grepl("_mal_", label)) { + "male" + } else if (grepl("_sx:1$", label)) { + "female" + } else if (grepl("_sx:2$", label)) { + "male" + } else if (grepl("_sx:1_", label)) { + "female" + } else if (grepl("_sx:2_", label)) { + "male" + } else { + NA + } + }, + growth_pattern = { + if ("growth_pattern" %in% colnames(df3)) { + growth_pattern + } else if (grepl("_gp_[0-9]$", label)) { + stringr::str_extract(label, "(?<=_)[0-9]$") + } else if (grepl("_gp:[0-9]$", label)) { + stringr::str_extract(label, "(?<=:)[0-9]$") + } else if (grepl("_gp:[0-9][0-9]$", label)) { + stringr::str_extract(label, "(?<=:)[0-9][0-9]$") + } else { + NA + } }, - growth_pattern = dplyr::case_when( - grepl("_gp_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - grepl("_gp:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), - grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), - TRUE ~ NA - ), month = { if ("month" %in% colnames(df3)) { month @@ -518,32 +539,14 @@ convert_output <- function( } ) - # if ("fleet" %in% colnames(df3)) { - # df4 <- df4 |> - # dplyr::mutate( - # fleet = dplyr::case_when( - # "fleet" %in% colnames(df3) ~ fleet, - # # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - # # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), - # TRUE ~ NA - # ), - # label = stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") - # ) - # } else { df4 <- df4 |> dplyr::mutate( - # fleet = dplyr::case_when( - # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), - # TRUE ~ NA - # ), label = dplyr::case_when( grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), TRUE ~ stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") ) ) - # } } else { cli::cli_alert_warning(glue::glue("Data frame not compatible in {parm_sel}.")) } From ecf72e95399661e13ba2235e8d82ba6391775f28 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Wed, 1 Jul 2026 13:19:51 -0400 Subject: [PATCH 08/28] add condition to id r4ss dat arg --- R/convert_output.R | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/R/convert_output.R b/R/convert_output.R index a277f978..67972a6e 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -148,6 +148,10 @@ convert_output <- function( cli::cli_alert_info("Processing Rceattle output file...") "rceattle" }, + "list" = { + cli::cli_alert_info("Processing FIMS output file...") + "ss3" + } cli::cli_abort("Unknown file type. Please indicate model.") ) } From 916f4c46d415e3ea332459ee10885faf69417d5b Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Wed, 1 Jul 2026 13:30:36 -0400 Subject: [PATCH 09/28] Revert "replace case_when with if statements in parts of converter per suggestion from dplyr:" This reverts commit 00e0f16fb284dc272e39036f803942d41846a0f7. --- R/convert_output.R | 127 ++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 65 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index 67972a6e..9bf6098e 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -464,74 +464,53 @@ convert_output <- function( values_to = "estimate" ) |> # , colnames(dplyr::select(df3, tidyselect::matches(errors))) dplyr::mutate( - fleet = { - if ("fleet" %in% colnames(df3)) { - fleet - } else if ("fleet_name" %in% colnames(df3)) { - fleet_name - } else if (grepl(":_[0-9]$", label)) { - stringr::str_extract(label, "(?<=_)[0-9]+") - } else if (grepl(":_[0-9][0-9]$", label)) { - stringr::str_extract(label, "(?<=_)[0-9][0-9]+") - } else { - NA - } - }, - area = { - if ("area" %in% colnames(df3)) { - area - } else if (grepl("?_area_[0-9]_?", label)) { - stringr::str_extract(label, "(?<=area_)[0-9]+") - } else if (grepl("_[0-9]_", label)) { - stringr::str_extract(label, "(?<=_)[0-9]+") - } else if (grepl(":_[0-9]$", label)) { - stringr::str_extract(label, "(?<=_)[0-9]+") - } else if (grepl(":_[0-9][0-9]$", label)) { - stringr::str_extract(label, "(?<=_)[0-9][0-9]+") - } else { - NA - } + fleet = if ("fleet" %notin% colnames(df3)) { + dplyr::case_when( + # "fleet" %in% colnames(.data) ~ fleet, + grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), + TRUE ~ NA + ) + } else if ("fleet_name" %in% colnames(df3)) { + fleet_name + } else { + fleet }, - sex = { - if ("sex" %in% colnames(df3)) { - if (sex == 1) { - "female" - } else if (sex == 2) { - "male" - } else if (sex == 3) { - "both" - } else { - sex - } - } else if (grepl("_fem_", label)) { - "female" - } else if (grepl("_mal_", label)) { - "male" - } else if (grepl("_sx:1$", label)) { - "female" - } else if (grepl("_sx:2$", label)) { - "male" - } else if (grepl("_sx:1_", label)) { - "female" - } else if (grepl("_sx:2_", label)) { - "male" - } else { - NA - } + area = if ("area" %notin% colnames(df3)) { + dplyr::case_when( + grepl("?_area_[0-9]_?", label) ~ stringr::str_extract(label, "(?<=area_)[0-9]+"), + grepl("_[0-9]_", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), + grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), + TRUE ~ NA + ) + } else { + area }, - growth_pattern = { - if ("growth_pattern" %in% colnames(df3)) { - growth_pattern - } else if (grepl("_gp_[0-9]$", label)) { - stringr::str_extract(label, "(?<=_)[0-9]$") - } else if (grepl("_gp:[0-9]$", label)) { - stringr::str_extract(label, "(?<=:)[0-9]$") - } else if (grepl("_gp:[0-9][0-9]$", label)) { - stringr::str_extract(label, "(?<=:)[0-9][0-9]$") - } else { - NA - } + sex = if ("sex" %notin% colnames(df3)) { + dplyr::case_when( + grepl("_fem_", label) ~ "female", + grepl("_mal_", label) ~ "male", + grepl("_sx:1$", label) ~ "female", + grepl("_sx:2$", label) ~ "male", + grepl("_sx:1_", label) ~ "female", + grepl("_sx:2_", label) ~ "male", + TRUE ~ NA + ) + } else { + dplyr::case_when( + sex == 1 ~ "female", + sex == 2 ~ "male", + sex == 3 ~ "both", + TRUE ~ sex + ) }, + growth_pattern = dplyr::case_when( + grepl("_gp_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + grepl("_gp:[0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9]$"), + grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), + TRUE ~ NA + ), month = { if ("month" %in% colnames(df3)) { month @@ -543,14 +522,32 @@ convert_output <- function( } ) + # if ("fleet" %in% colnames(df3)) { + # df4 <- df4 |> + # dplyr::mutate( + # fleet = dplyr::case_when( + # "fleet" %in% colnames(df3) ~ fleet, + # # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + # # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), + # TRUE ~ NA + # ), + # label = stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") + # ) + # } else { df4 <- df4 |> dplyr::mutate( + # fleet = dplyr::case_when( + # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), + # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), + # TRUE ~ NA + # ), label = dplyr::case_when( grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), TRUE ~ stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") ) ) + # } } else { cli::cli_alert_warning(glue::glue("Data frame not compatible in {parm_sel}.")) } From 40187141b6d9fa69e9a20b0a41d741eedfbc0a11 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Wed, 1 Jul 2026 13:57:40 -0400 Subject: [PATCH 10/28] add final changes to std to address issue with missing sex value --- R/convert_output.R | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index 9bf6098e..df594932 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -149,9 +149,9 @@ convert_output <- function( "rceattle" }, "list" = { - cli::cli_alert_info("Processing FIMS output file...") + cli::cli_alert_info("Processing SS3 r4ss output file...") "ss3" - } + }, cli::cli_abort("Unknown file type. Please indicate model.") ) } @@ -502,7 +502,8 @@ convert_output <- function( sex == 1 ~ "female", sex == 2 ~ "male", sex == 3 ~ "both", - TRUE ~ sex + sex == 0 ~ "combined", + TRUE ~ as.character(sex) ) }, growth_pattern = dplyr::case_when( @@ -511,36 +512,18 @@ convert_output <- function( grepl("_gp:[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=:)[0-9][0-9]$"), TRUE ~ NA ), - month = { - if ("month" %in% colnames(df3)) { + month = if ("month" %in% colnames(df3)) { month - } else if (grepl("_month_[0-9]+$", label)) { - stringr::str_extract(label, "(?<=month_)[0-9]+$") } else { - ifelse(any(grepl("^month$", colnames(df3))), month, NA) # this might remove month + dplyr::case_when( + grepl("_month_[0-9]+$", label) ~ stringr::str_extract(label, "(?<=month_)[0-9]+$"), + TRUE ~ ifelse(any(grepl("^month$", colnames(df3))), month, NA) # this might remove month + ) } - } ) - # if ("fleet" %in% colnames(df3)) { - # df4 <- df4 |> - # dplyr::mutate( - # fleet = dplyr::case_when( - # "fleet" %in% colnames(df3) ~ fleet, - # # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - # # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), - # TRUE ~ NA - # ), - # label = stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") - # ) - # } else { df4 <- df4 |> dplyr::mutate( - # fleet = dplyr::case_when( - # grepl("):_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]$"), - # grepl("):_[0-9][0-9]+$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]$"), - # TRUE ~ NA - # ), label = dplyr::case_when( grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), @@ -1199,7 +1182,13 @@ convert_output <- function( df3 <- df1[-c(1:rownum), ] colnames(df3) <- tolower(row) } else { - df3 <- extract + # Remove XX columns left in dataframe + if (any("xx" %in% tolower(colnames(extract)))) { + # ID which cols contain XX + df3 <- extract[, -grep("xx", tolower(colnames(extract)))] + } else { + df3 <- extract + } colnames(df3) <- tolower(colnames(df3)) } @@ -1335,6 +1324,7 @@ convert_output <- function( next } } # close if param is in output file + #### single_val #### } else if (parm_sel %in% single_val) { df <- data.frame( label = parm_sel, @@ -1343,6 +1333,7 @@ convert_output <- function( ) df[setdiff(tolower(names(out_new)), tolower(names(df)))] <- NA out_list[[parm_sel]] <- df + #### skip parm in ss3 #### } else { if (is.character(file)) cli::cli_alert(glue::glue("Skipped [{i}] {parm_sel}")) next From 06ff31727b65cd8efa09dda2065b622616865806 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Wed, 1 Jul 2026 16:43:13 -0400 Subject: [PATCH 11/28] ignore module names in ss3 sheet in favor of those in r4ss --- R/convert_output.R | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/R/convert_output.R b/R/convert_output.R index df594932..395c857b 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -2295,7 +2295,13 @@ convert_output <- function( # Remove 'X' column if it exists var_names_sheet <- var_names_sheet |> dplyr::select(-dplyr::any_of("X")) - out_new <- dplyr::left_join(out_new, var_names_sheet, by = c("module_name", "label")) |> + if (model == "ss3" & !is.character(file)) { + var_names_sheet <- var_names_sheet |> dplyr::select(-module_name) + out_new <- dplyr::left_join(out_new, var_names_sheet, by = "label") + } else { + out_new <- dplyr::left_join(out_new, var_names_sheet, by = c("module_name", "label")) + } + out_new <- out_new |> dplyr::mutate(label = dplyr::case_when( !is.na(alt_label) ~ alt_label, # TODO: add this to ss3_var_names.xlsx From 7e73f831dcd8fb9f28a306c3bd252c67f7e7eb07 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Wed, 1 Jul 2026 16:53:32 -0400 Subject: [PATCH 12/28] add a test for running r4ss through convert_output --- tests/testthat/test-convert_output.R | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/testthat/test-convert_output.R b/tests/testthat/test-convert_output.R index 4e2e4fa0..78a7f4d1 100644 --- a/tests/testthat/test-convert_output.R +++ b/tests/testthat/test-convert_output.R @@ -71,3 +71,17 @@ test_that("missing arguments trigger warnings or errors", { unlink(fs::path("fixtures", "ss3_models_converted"), recursive = TRUE) }) + +test_that("r4ss::ss_output object is compatible.", { + install.packages("remotes") + remotes::install_github("r4ss/r4ss") + library(r4ss) + simple <- r4ss::SS_output(dir = file.path( + path.package("r4ss"), + file.path("extdata", "simple_small") + )) + + expect_no_error( + convert_output(simple) + ) +}) From c9d41d82f1bc625e33295520c29cad8cb8f34a8a Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:23:33 -0400 Subject: [PATCH 13/28] add condition to handle single values coming from r4ss output --- R/convert_output.R | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index 395c857b..c1559fc2 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -364,7 +364,7 @@ convert_output <- function( # Processing data frame parm_sel <- param_names[i] if (parm_sel %in% c(std, std2, cha, rand, aa.al, single_val)) { - cli::cli_alert(glue::glue("[{i}] Processing {parm_sel}")) + cli::cli_alert(glue::glue("Processing {parm_sel}")) # Remove [{i}] if(is.character(file)) { extract <- SS3_extract_df(dat, parm_sel) } else { @@ -372,9 +372,19 @@ convert_output <- function( } if (!is.data.frame(extract)) { - miss_parms <- c(miss_parms, parm_sel) - cli::cli_alert(glue::glue("Skipped {parm_sel}")) - next + if (is.numeric(extract)) { + df <- data.frame( + label = parm_sel, + module_name = parm_sel, + estimate = extract + ) + df[setdiff(tolower(names(out_new)), tolower(names(df)))] <- NA + out_list[[parm_sel]] <- df + } else { + miss_parms <- c(miss_parms, parm_sel) + cli::cli_alert(glue::glue("Skipped {parm_sel}")) + next + } } else { ##### STD #### # 1,4,10,17,19,36 From 2264a8f06905c9bf2017024a30b840cc31012537 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:25:36 -0400 Subject: [PATCH 14/28] add entries in ss3 excel sheet to standardize the values in single_val category --- inst/resources/ss3_var_names.csv | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/inst/resources/ss3_var_names.csv b/inst/resources/ss3_var_names.csv index 5d97027a..575aa840 100644 --- a/inst/resources/ss3_var_names.csv +++ b/inst/resources/ss3_var_names.csv @@ -257,4 +257,7 @@ Growth_Parameters,mat2, Growth_Parameters,fec1, Growth_Parameters,fec2, MEAN_BODY_WT(Begin),mean_body_wt, -Dynamic_Bzero,Dynamic_Bzero, +Dynamic_Bzero,Dynamic_Bzero,dynamic_biomass_zero +,sprtarg,spr_target +,btarg,biomass_target +,Sbzero,spawning_biomass_zero From 376f7f22914ebd2c174909883695dc147c855f52 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Thu, 2 Jul 2026 09:47:13 -0400 Subject: [PATCH 15/28] add example r4ss::ss_output to fixtures and use instead of downloading the package for test --- .../r4ss_output/simple_small/simple_r4ss.rds | Bin 0 -> 327187 bytes tests/testthat/test-convert_output.R | 10 ++-------- 2 files changed, 2 insertions(+), 8 deletions(-) create mode 100644 tests/testthat/fixtures/r4ss_output/simple_small/simple_r4ss.rds diff --git a/tests/testthat/fixtures/r4ss_output/simple_small/simple_r4ss.rds b/tests/testthat/fixtures/r4ss_output/simple_small/simple_r4ss.rds new file mode 100644 index 0000000000000000000000000000000000000000..5f46c0fa5f7245dd910c9756385b871d7841c311 GIT binary patch literal 327187 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
+oweB+q>Cc8Me(Boj2{)=Hod z@;^Qqkg~&_qHpz*b&@Tv0fRp9FI>vK>+D7c*nwV3Gd2hR=JrPPwQ;9k1=>}LNz@Uif0z_qE< z;IxY-u;SSpuruk_i_tX)>r(;!zrP;^3ofau+anjjtg&@%(UV><)BT#hsiPe}Cdl$- zSW_WgCM_rBsuT2Xeg5jJyaKke>qD$dB6V3Hhom>o0K3&ZUQ_$GqPuL{ywER^_>n+~ zJ>P+L+968DF_ zD!esS{0p&{EHCe454-<>JsA?`17oJJCrQ%K_x26!Nwnxy`fP$dq&)Cx>`|oXwSC@$ zJ&UH&`_}7YceHGs9wQmMcVFKpHn9V{ZcbiVAvF)%8WBJLY@2l*SRX0mP4`*d z0;@U=XKSMq!Twj{MaP1L&NPZD+FDxg_9)fIoH?>-H+9cpsCcJOA5{xuzVE%XiFy(f zH!YkzJ?8-!bIPB|4OM_RA`RRb2$><2(W{Bh|Mh*?vdDAC*v%VI5HRCch|x1_oV_<= zaF-so)D=Eoq9*|r1RL_D0ITjJ|2{Jd-2Fs9Ix z(!1a{W)O0VW}h+Bh)3Q{{0gQmKXcEoHy1SCiWa9#`r0Ma4nKT#7 zBH-80T`|#6qcf242>mBt-YirbMan+8J2JbrVxldq6w3|3c!I`hn~kvrj}1>qabV07 zwfe4C`55Kn=Xa-3A0wDj`2KqchWj=*|FYDQ(B*O%TBWi62=_B!W~ikn{<+1f zSN5;VIW7blXVrs0S_(kd;o|F0OT4kk&Lz#Yuot^`O8pX8`5E#F`H~rv;M=CN^oX+% z+77gTUVz&8A=?myvnXiAuA?yLc6Dxq!zT=TzO9l|eiY-lmV}Rwyuc)ei|XfHo8Vq( zUc#@7y%4|hvwiv3$kN>g&N(3FwA%_T7ZIpfI#^;0$bK41` z7F3KM&GLES137EI?pfHEkF^U4;hKv$+;jG&X0z{q;+)g6g6roYecP(1_w6H)_H-|y zXof>&8%9pqf5M>)g{yW43gaLlZ}i6;2UW>}83zRt1b2CiB6YyU@5QZGNG)92H%~kf zsYy*QvJKLZ8n#Nzv(E^rdgwT{xgV+5ghhWbtB@+h_v!bKK^z#;N*9>&!GWXd^A1P` zV_(tb`(+BF*b`aM6Efowb}5)$NlZJ0Z7w^1f8c)ocb)#NSLmtFk0dWX$2j>Fnzol3 zG3)XRM``;XnDry2>*1dZnE7#ZJYp&Yt9q;g_TBh^1%obkMkWNXxb>U)WXdM25YTy2 zLes!J;m;P1$xWCV^?t3QQ$0pU_{+Jy=EgK>E|kWNf%c)FndFp*GjVngAl{Q+0>u(z2IdXR?P&sSS-Z!Uwt z`$U0u4-MBm=AJnG94(#f`T1QAqsfE!4W4uMV~%0ptKBC}F|4(=s+{{h#_6w>U+i)N zDXZuTcEyYF*_Zu`-UxI;!g@)NIVcaAPb;e8xupN=`?8~Q*4!`0ilKb|kZpOqKIV#R zj<^L0WA!wSy5i@;T+#LQkR!*Z#%S#A<<&@p-o?KXmM8LtmaT0RGYo+ zp2~e37?*o@)%7s;XRFb7sit3DM7 zw#EYL!P#D=BA7`Yo4J@U?+d|n!i+!bn_qlFOygMWEBe(2DdFRMQED$Ssr-4{o9Bly z@$%u+1EaSvVbzigzrAZQeur+;LbYg&(-7g9&GiRk`&zoJ3)C=HZ7i$1Z3-BZJAE&t zngCOX%_C=)k%V;c@XN9+dUgU*{mAzLTK1=$-D91Cb)WB?sQNC1{k3fUjjRW3o_>Jo zvZ{|VA*l5*N7Peq3mRK;oc(o>!K!npw^P^TV~(@*Iqi5C3=1AU9p9Xcal2*Tw^nH( z#pC30&QTjwo28uVdNvM{{4czm?d}Fy{8RL~m$d)u`?KrBQh@=@KN6=Yg+3vvh+&T>8MAmO_zII@9|q1gH_GJ3@Bxb#~gL;qFGIg^XX;FtGJ zEUducT1p>9uN{ZI8Vi2aXy7nOLlMB?EzI0kEr*caqQ`Z3)fS`^U*(Aq(x>Ok^aE9U z=SW*2eU0NReTA7w`!7i@CRTqF0)AVfM7% zc8zDB;n<-qSaRToSigt>mLK?NZ|J!Rt51~WJ-soBMV_RP4dRw(0ggr9nCQ6~ZiNOR z{?2#g4{pHp_8TGZr+P8<#SFr!1S!+J+oYkS!3X2km>4nl-jiGYn2>as+kWmZj33{n zPqk6O_(%2UMygvd?(?sACk(P-I46Q~?>YyJoa4qF8{L6
Y!WU=bg9~I3j%)x8g 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 W=V`4Z>9xTdp`^Ap8vk$h5B~wj0jwMV literal 0 HcmV?d00001 diff --git a/tests/testthat/test-convert_output.R b/tests/testthat/test-convert_output.R index 78a7f4d1..b9670c98 100644 --- a/tests/testthat/test-convert_output.R +++ b/tests/testthat/test-convert_output.R @@ -73,15 +73,9 @@ test_that("missing arguments trigger warnings or errors", { }) test_that("r4ss::ss_output object is compatible.", { - install.packages("remotes") - remotes::install_github("r4ss/r4ss") - library(r4ss) - simple <- r4ss::SS_output(dir = file.path( - path.package("r4ss"), - file.path("extdata", "simple_small") - )) + simple_r4ss <- readRDS(fs::path("fixtures", "r4ss_output", "simple_small", "simple_r4ss.rds")) expect_no_error( - convert_output(simple) + convert_output(simple_r4ss) ) }) From a076f4386de46aa0df6550420f60f0b80676113e Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Thu, 2 Jul 2026 10:03:39 -0400 Subject: [PATCH 16/28] adjust code per copilot suggestions --- R/convert_output.R | 13 ++----------- inst/resources/ss3_var_names.csv | 2 +- tests/testthat/test-convert_output.R | 5 ++--- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index c1559fc2..e76def9b 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -376,7 +376,7 @@ convert_output <- function( df <- data.frame( label = parm_sel, module_name = parm_sel, - estimate = extract + estimate = extract[[1]] ) df[setdiff(tolower(names(out_new)), tolower(names(df)))] <- NA out_list[[parm_sel]] <- df @@ -1334,15 +1334,6 @@ convert_output <- function( next } } # close if param is in output file - #### single_val #### - } else if (parm_sel %in% single_val) { - df <- data.frame( - label = parm_sel, - estimate = extract[[1]], - module_name = parm_sel - ) - df[setdiff(tolower(names(out_new)), tolower(names(df)))] <- NA - out_list[[parm_sel]] <- df #### skip parm in ss3 #### } else { if (is.character(file)) cli::cli_alert(glue::glue("Skipped [{i}] {parm_sel}")) @@ -2305,7 +2296,7 @@ convert_output <- function( # Remove 'X' column if it exists var_names_sheet <- var_names_sheet |> dplyr::select(-dplyr::any_of("X")) - if (model == "ss3" & !is.character(file)) { + if (tolower(model) == "ss3" & !is.character(file)) { var_names_sheet <- var_names_sheet |> dplyr::select(-module_name) out_new <- dplyr::left_join(out_new, var_names_sheet, by = "label") } else { diff --git a/inst/resources/ss3_var_names.csv b/inst/resources/ss3_var_names.csv index 575aa840..3183b843 100644 --- a/inst/resources/ss3_var_names.csv +++ b/inst/resources/ss3_var_names.csv @@ -260,4 +260,4 @@ MEAN_BODY_WT(Begin),mean_body_wt, Dynamic_Bzero,Dynamic_Bzero,dynamic_biomass_zero ,sprtarg,spr_target ,btarg,biomass_target -,Sbzero,spawning_biomass_zero +,SBzero,spawning_biomass_zero diff --git a/tests/testthat/test-convert_output.R b/tests/testthat/test-convert_output.R index b9670c98..0b21d97d 100644 --- a/tests/testthat/test-convert_output.R +++ b/tests/testthat/test-convert_output.R @@ -75,7 +75,6 @@ test_that("missing arguments trigger warnings or errors", { test_that("r4ss::ss_output object is compatible.", { simple_r4ss <- readRDS(fs::path("fixtures", "r4ss_output", "simple_small", "simple_r4ss.rds")) - expect_no_error( - convert_output(simple_r4ss) - ) + expect_no_error(result <- convert_output(simple_r4ss)) + expect_equal(dim(result)[2], 33) }) From e4231615f55c6eac4783aff87e9ac768692f6b30 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Thu, 2 Jul 2026 11:16:23 -0400 Subject: [PATCH 17/28] update version number since this will be the last PR merge before next release tag --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 545ee470..c10ac2e1 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: stockplotr Title: Tables and Figures for Stock Assessments -Version: 0.12.1.9000 +Version: 0.13.0 Authors@R: c( person("Samantha", "Schiano", , "samantha.schiano@noaa.gov", role = c("aut", "cre"), comment = c(ORCID = "0009-0003-3744-6428")), From 210411b06fd21e92fae19790c4ce09bbeba781c2 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Mon, 6 Jul 2026 10:25:40 -0400 Subject: [PATCH 18/28] add conditions to aa plots to allow user to select module --- R/plot_abundance_at_age.R | 5 ++++- R/plot_biomass_at_age.R | 2 ++ man/plot_abundance_at_age.Rd | 2 ++ man/plot_biomass_at_age.Rd | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/R/plot_abundance_at_age.R b/R/plot_abundance_at_age.R index 2aefbc14..0763becb 100644 --- a/R/plot_abundance_at_age.R +++ b/R/plot_abundance_at_age.R @@ -70,6 +70,8 @@ plot_abundance_at_age <- function( unit_label = "fish", scale_amount = 1000, proportional = TRUE, + module = NULL, + interactive = TRUE, make_rda = FALSE, figures_dir = getwd() ) { @@ -85,8 +87,9 @@ plot_abundance_at_age <- function( label_name = "abundance", geom = "point", group = "age", + module = module, scale_amount = scale_amount, - interactive = FALSE + interactive = interactive ) if (!is.null(facet) && facet == "none") { diff --git a/R/plot_biomass_at_age.R b/R/plot_biomass_at_age.R index 4134e010..d8436fd9 100644 --- a/R/plot_biomass_at_age.R +++ b/R/plot_biomass_at_age.R @@ -45,6 +45,7 @@ plot_biomass_at_age <- function( unit_label = "mt", scale_amount = 1000, proportional = TRUE, + module = NULL, interactive = TRUE, make_rda = FALSE, figures_dir = getwd() @@ -62,6 +63,7 @@ plot_biomass_at_age <- function( geom = "point", group = "age", era = "time", + module = module, scale_amount = scale_amount, interactive = interactive ) diff --git a/man/plot_abundance_at_age.Rd b/man/plot_abundance_at_age.Rd index 8bf76f65..9020b9c0 100644 --- a/man/plot_abundance_at_age.Rd +++ b/man/plot_abundance_at_age.Rd @@ -10,6 +10,8 @@ plot_abundance_at_age( unit_label = "fish", scale_amount = 1000, proportional = TRUE, + module = NULL, + interactive = TRUE, make_rda = FALSE, figures_dir = getwd() ) diff --git a/man/plot_biomass_at_age.Rd b/man/plot_biomass_at_age.Rd index 854e979e..bbba2bd4 100644 --- a/man/plot_biomass_at_age.Rd +++ b/man/plot_biomass_at_age.Rd @@ -10,6 +10,7 @@ plot_biomass_at_age( unit_label = "mt", scale_amount = 1000, proportional = TRUE, + module = NULL, interactive = TRUE, make_rda = FALSE, figures_dir = getwd() From 09551061383607e2cadba12ed97f2e58b5b21fa6 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Mon, 6 Jul 2026 11:33:09 -0400 Subject: [PATCH 19/28] make beg/mid grouping available to remove issue in NAA and BAA --- R/convert_output.R | 34 +++++++++++++++++++++++++++++++--- R/utils_plot.R | 3 ++- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index e76def9b..f36c2ae8 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -82,7 +82,7 @@ convert_output <- function( bio_pattern = NA, settlement = NA, morph = NA, - # beg/mid = NA, # need to identify df where this is applicable + beg_mid = NA, type = NA, factor = NA, # sexes = NA, # remove sexes to see how it impacts the results @@ -1214,7 +1214,26 @@ convert_output <- function( if (label == "f") { label <- "fishing_mortality" } - } + } else ( + # add conditions for naming label from aa.al + label <- switch( + parm_sel, + "sizeselex" = "selectivity_length", + "ageselex" = "selectivity_age", + "Natural_Mortality" = "natural_mortality_age", + "fatage" = "fishing_mortality_age", + "natage" = "abundance_age", + "batage" = "biomass_age", + "natlen" = "abundance_length", + "batlen" = "biomass_length", + "discard_at_age" = "discard_age", + "catage" = "catch_age", + "Z_at_age" = "total_mortality_age", + "M_at_age" = "natural_mortality_age", + "Z_by_area" = "total_mortality", + "M_by_area" = "natural_mortality" + ) + ) if (grepl("age", tolower(parm_sel))) { fac <- "age" } else if (any(grepl("length|len", tolower(parm_sel)))) { @@ -1224,8 +1243,12 @@ convert_output <- function( } else { fac <- "age" } + + # remove fac from label + if (grepl(glue::glue("_{fac}"), label)) label <- stringr::str_remove(label, glue::glue("_{fac}")) + # Reformat dataframe - if (any(colnames(df3) %in% c("Yr", "yr", "year"))) { + if (any(colnames(df3) %in% c("Yr", "yr"))) { df3 <- df3 |> dplyr::rename(year = yr) } @@ -1292,6 +1315,11 @@ convert_output <- function( df4 <- df4 |> dplyr::rename(likelihood = like) } + # Rename beg/mid if present + if (any(grepl("beg/mid", colnames(df4)))) { + df4 <- df4 |> + dplyr::rename(beg_mid = "beg/mid") + } # Check for error in the df if (any(grepl(paste0("^", errors, "$", collapse = "|"), colnames(df4)))) { error_col <- colnames(df4)[grep(paste0("^", errors, "$", collapse = "|"), colnames(df4))] diff --git a/R/utils_plot.R b/R/utils_plot.R index a451189c..63aa9751 100644 --- a/R/utils_plot.R +++ b/R/utils_plot.R @@ -938,7 +938,8 @@ check_grouping <- function(dat) { "fleet", "sex", "area", "growth_pattern", "month", "season", "platoon", "bio_pattern", - "settlement", "morph", "block", "length_bins" + "settlement", "morph", "block", "length_bins", + "beg_mid" ) # non.index_variables <- c( # "estimate", "initial", "likelihood", From b92ebbb1f2c53b1b11686fec72beecf01d93441b Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Mon, 6 Jul 2026 14:07:14 -0400 Subject: [PATCH 20/28] add new condition to correct label in parameters module and length bins in ageselex module --- R/convert_output.R | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index f36c2ae8..f8efb04a 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -1098,6 +1098,7 @@ convert_output <- function( # fix remaining labels label = ifelse(grepl("_GP$", label), stringr::str_remove(label, "_GP$"), label), label = ifelse(grepl("_Fem|_Mal", label), stringr::str_remove(label, "_Fem$|_Mal$"), label), + label = ifelse(grepl(paste0(fleet_names, collapse = "|"), label), stringr::str_remove(label, paste0("_", fleet_names, collapse = "|")), label), module_name = parm_sel ) # match to out_new @@ -1205,7 +1206,7 @@ convert_output <- function( # aa.al names naming <- c( "biomass", "discard", "catch", - "f", "mean_size", "numbers", "sel", + "f", "mean_size", "numbers", "Lsel", "sel", "mean_body_wt", "natural_mortality" ) if (stringr::str_detect(tolower(parm_sel), paste(naming, collapse = "|"))) { @@ -1218,7 +1219,7 @@ convert_output <- function( # add conditions for naming label from aa.al label <- switch( parm_sel, - "sizeselex" = "selectivity_length", + # "sizeselex" = "selectivity_length", "ageselex" = "selectivity_age", "Natural_Mortality" = "natural_mortality_age", "fatage" = "fishing_mortality_age", @@ -1239,7 +1240,7 @@ convert_output <- function( } else if (any(grepl("length|len", tolower(parm_sel)))) { fac <- "len_bins" } else if (any(grepl("size", tolower(parm_sel)))) { - fac <- "age" + fac <- "len_bins" } else { fac <- "age" } From fd5f74e7c9f7594ec34bb8699e2b7ec363939c89 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Mon, 13 Jul 2026 14:31:56 -0400 Subject: [PATCH 21/28] adjust tests to account for new variable in return df --- R/convert_output.R | 1 + tests/testthat/test-convert_output.R | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index f8efb04a..746eb569 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -355,6 +355,7 @@ convert_output <- function( "StdDev", "sd", "std", "stddev", "se", "SE", "cv", "CV" + # "dev" # adding but unkwn what kind ) miss_parms <- c() diff --git a/tests/testthat/test-convert_output.R b/tests/testthat/test-convert_output.R index 0b21d97d..04a0a9f3 100644 --- a/tests/testthat/test-convert_output.R +++ b/tests/testthat/test-convert_output.R @@ -14,7 +14,7 @@ test_that("convert_output works for SS3", { )) # Check that the result has exactly 33 columns - expect_equal(dim(result)[2], 33) + expect_equal(dim(result)[2], 34) } # Test saving the output in a global environment @@ -22,7 +22,7 @@ test_that("convert_output works for SS3", { file = file.path(all_models[1], "Report.sso") ) - expect_equal(dim(output)[2], 33) + expect_equal(dim(output)[2], 34) }) @@ -76,5 +76,5 @@ test_that("r4ss::ss_output object is compatible.", { simple_r4ss <- readRDS(fs::path("fixtures", "r4ss_output", "simple_small", "simple_r4ss.rds")) expect_no_error(result <- convert_output(simple_r4ss)) - expect_equal(dim(result)[2], 33) + expect_equal(dim(result)[2], 34) }) From f579f90439bb0b5f11ab5bed9b295a112bc31e58 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Mon, 13 Jul 2026 16:15:33 -0400 Subject: [PATCH 22/28] remove raw_dev from df on condition --- R/convert_output.R | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/R/convert_output.R b/R/convert_output.R index 746eb569..67323e97 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -552,12 +552,17 @@ convert_output <- function( err_names <- unique(df4$label)[grepl(paste(paste0("(^|[_.])", errors, "($|[_.])"), collapse = "|"), unique(df4$label)) & !unique(df4$label) %in% errors] if (any(grepl("sel", err_names))) { df4 <- df4 - } else if (length(intersect(errors, colnames(df4))) == 1) { + } else if ("raw_dev" %in% colnames(df4)) { + # remove raw_dev bc dev already exists + df4 <- df4 |> + dplyr::select(-raw_dev) + } else if (length(intersect(errors, colnames(df4))) == 1 && "raw_dev" %notin% colnames(df4)) { df4 <- df4[-grep(paste(errors, "_", collapse = "|", sep = ""), df4$label), ] } else if (parm_sel == "MGparm_By_Year_after_adjustments") { # this is too specific df4 <- df4 cli::cli_alert_info("Error values are present, but are unique to the data frame and not to a selected parameter.") } else { + if ("raw_dev" %in% colnames(df4)) df4 <- df4 |> dplyr::select(-raw_dev) df4 <- df4 |> tidyr::pivot_wider( names_from = label, From 27ef880250679494b3f544901442c31e29ace0d2 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Tue, 14 Jul 2026 15:55:23 -0400 Subject: [PATCH 23/28] adjust selex module names --- R/convert_output.R | 17 ++++++++++------- inst/resources/ss3_var_names.csv | 10 +++++----- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index 67323e97..86660878 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -355,7 +355,7 @@ convert_output <- function( "StdDev", "sd", "std", "stddev", "se", "SE", "cv", "CV" - # "dev" # adding but unkwn what kind + # "dev" # not included bc this is dev in model, not uncertainty of the value ) miss_parms <- c() @@ -552,17 +552,20 @@ convert_output <- function( err_names <- unique(df4$label)[grepl(paste(paste0("(^|[_.])", errors, "($|[_.])"), collapse = "|"), unique(df4$label)) & !unique(df4$label) %in% errors] if (any(grepl("sel", err_names))) { df4 <- df4 - } else if ("raw_dev" %in% colnames(df4)) { - # remove raw_dev bc dev already exists - df4 <- df4 |> - dplyr::select(-raw_dev) - } else if (length(intersect(errors, colnames(df4))) == 1 && "raw_dev" %notin% colnames(df4)) { + } else if (length(intersect(errors, colnames(df4))) == 1 && "raw_dev" %notin% unique(df4$label)) { df4 <- df4[-grep(paste(errors, "_", collapse = "|", sep = ""), df4$label), ] } else if (parm_sel == "MGparm_By_Year_after_adjustments") { # this is too specific df4 <- df4 cli::cli_alert_info("Error values are present, but are unique to the data frame and not to a selected parameter.") } else { - if ("raw_dev" %in% colnames(df4)) df4 <- df4 |> dplyr::select(-raw_dev) + # remove dev and raw_dev from output -- no place for it atm + if ("raw_dev" %in% unique(df4$label)) { + df4 <- df4 |> dplyr::filter(label != "raw_dev") + err_names <- err_names[-grep("raw_dev", err_names)] + } + if ("dev" %in% unique(df4$label)) { + df4 <- df4 |> dplyr::filter(label != "dev") + } df4 <- df4 |> tidyr::pivot_wider( names_from = label, diff --git a/inst/resources/ss3_var_names.csv b/inst/resources/ss3_var_names.csv index 3183b843..82c450ec 100644 --- a/inst/resources/ss3_var_names.csv +++ b/inst/resources/ss3_var_names.csv @@ -117,15 +117,15 @@ INDEX_2,vuln_bio, INDEX_2,calc_q, INDEX_2,eff_q, INDEX_2,use, -AGE_SELEX,sel, +AGE_SELEX,sel,age_selectivity AGE_SELEX,Fecund,fecundity AGE_SELEX,bodywt,body_weight AGE_SELEX,dead_nums,dead_numbers AGE_SELEX,dead*wt, -,Ret, -,Mort, -,Keep, -,Dead, +,Ret,selectivity_retain +,Mort,selectivity_mortality +,Keep,selectivity_keep +,Dead,selectivity_dead ,Dynamic_Bzero,biomass_zero Kobe_Plot,b/bmsy,b_bmsy Kobe_Plot,f/fmsy,f_fmsy From 94b4ad017f0b965c842b813d954fcc8d8a07bd16 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:20:58 -0400 Subject: [PATCH 24/28] add new std naming for alternative conventions in r4ss ss_output; also add custom code to get fleet names into proper column for exploitation module --- R/convert_output.R | 13 ++++++++++++- inst/resources/ss3_var_names.csv | 3 +++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/R/convert_output.R b/R/convert_output.R index 86660878..509ee926 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -422,6 +422,15 @@ convert_output <- function( # from 4rss output df3 <- extract colnames(df3) <- tolower(colnames(df3)) + # ID any column names that are fleets (exploitation module in r4ss) + if (any(tolower(fleet_names) %in% colnames(df3))) { + for (i in intersect(tolower(fleet_names), colnames(df3))) { + col_name <- glue::glue("exploitation_{i}") + df3 <- df3 |> + dplyr::rename(!!col_name := i) + } + + } } # Remove any leftover NA columns if still present @@ -478,6 +487,7 @@ convert_output <- function( fleet = if ("fleet" %notin% colnames(df3)) { dplyr::case_when( # "fleet" %in% colnames(.data) ~ fleet, + grepl(paste0(tolower(fleet_names), collapse = "|"), label) ~ stringr::str_extract(label, paste(tolower(fleet_names), collapse = "|")), grepl(":_[0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9]+"), grepl(":_[0-9][0-9]$", label) ~ stringr::str_extract(label, "(?<=_)[0-9][0-9]+"), TRUE ~ NA @@ -533,11 +543,12 @@ convert_output <- function( } ) - df4 <- df4 |> + df4a <- df4 |> dplyr::mutate( label = dplyr::case_when( grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), grepl("?_area_[0-9]_?", label) ~ stringr::str_replace(label, "_?area_\\d?", ""), + grepl(paste0(tolower(fleet_names), collapse = "|"), label) ~ stringr::str_remove(label, paste0("_", tolower(fleet_names), collapse = "|")), TRUE ~ stringr::str_extract(label, "^.*?(?=_\\d|_gp|_fem|_mal|_sx|:|$)") ) ) diff --git a/inst/resources/ss3_var_names.csv b/inst/resources/ss3_var_names.csv index 82c450ec..dd2e2a7f 100644 --- a/inst/resources/ss3_var_names.csv +++ b/inst/resources/ss3_var_names.csv @@ -261,3 +261,6 @@ Dynamic_Bzero,Dynamic_Bzero,dynamic_biomass_zero ,sprtarg,spr_target ,btarg,biomass_target ,SBzero,spawning_biomass_zero +,seas_dur,season_duration +,annual_f,fishing_mortality +,annual_m,natural_mortality From 3ef45296e6d6fa108e2b41519bb80fc89f58896e Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:36:39 -0400 Subject: [PATCH 25/28] add condition to adjust error value in exploitation module --- R/convert_output.R | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/R/convert_output.R b/R/convert_output.R index 509ee926..9cbff8f9 100644 --- a/R/convert_output.R +++ b/R/convert_output.R @@ -477,6 +477,14 @@ convert_output <- function( df3 <- dplyr::mutate(df3, sex = NA) } + # Identify which errors were identified in a column & rename + err_col_id <- colnames(df3)[grepl(paste0(errors, "$", collapse = "|"), colnames(df3))] + # rename error column + if (length(err_col_id) > 0) { + uncert_name <- stringr::str_extract(err_col_id, paste0(errors, collapse = "|")) + df3 <- df3 |> + dplyr::rename(!!uncert_name := err_col_id) + } df4 <- df3 |> tidyr::pivot_longer( !tidyselect::any_of(c(factors, errors)), @@ -543,7 +551,7 @@ convert_output <- function( } ) - df4a <- df4 |> + df4 <- df4 |> dplyr::mutate( label = dplyr::case_when( grepl("?_month_[0-9]_?", label) ~ stringr::str_replace(label, "_?month_\\d?", ""), @@ -660,12 +668,6 @@ convert_output <- function( ) colnames(df5) <- tolower(names(df5)) } - # param_df <- df5 - # if (ncol(out_new) < ncol(df5)){ - # warning(paste0("Transformed data frame for ", parm_sel, " has more columns than default.")) - # } else if (ncol(out_new) > ncol(df5)){ - # warning(paste0("Transformed data frame for ", parm_sel, " has less columns than default.")) - # } if ("seas" %in% colnames(df5)) df5 <- dplyr::rename(df5, season = seas) if ("subseas" %in% colnames(df5)) df5 <- dplyr::rename(df5, subseason = subseas) From 6c078c863b564e2e6c0ccab8578ba911c2a0fe9c Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Tue, 14 Jul 2026 17:02:29 -0400 Subject: [PATCH 26/28] add std naming for sprseries module --- inst/resources/ss3_var_names.csv | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/inst/resources/ss3_var_names.csv b/inst/resources/ss3_var_names.csv index dd2e2a7f..3585548b 100644 --- a/inst/resources/ss3_var_names.csv +++ b/inst/resources/ss3_var_names.csv @@ -264,3 +264,20 @@ Dynamic_Bzero,Dynamic_Bzero,dynamic_biomass_zero ,seas_dur,season_duration ,annual_f,fishing_mortality ,annual_m,natural_mortality +,bio_all_eq,biomass +,bio_smry_eq,biomass_reference_age +,ssbfished_eq,spawning_biomass_fished +,ssbfished_r, +,f_std,fishing_mortality +,ave_f,fishing_mortality_average +,maxf,fishing_mortality_max +,tot_exploit, +,dead_catch_b, +,retain_catch_n, +,retain_catch_b, +,enc_catch_n, +,dead_catch_n, +,m,natural_mortality +,enc_catch, +,mnage_smry, +,mnage_catch, From c8883ab7c609e25b18002679c0a61646be5cd325 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Mon, 20 Jul 2026 10:58:19 -0400 Subject: [PATCH 27/28] update naming conventions found in r4ss --- inst/resources/ss3_var_names.csv | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/inst/resources/ss3_var_names.csv b/inst/resources/ss3_var_names.csv index 3585548b..83fb4093 100644 --- a/inst/resources/ss3_var_names.csv +++ b/inst/resources/ss3_var_names.csv @@ -267,7 +267,7 @@ Dynamic_Bzero,Dynamic_Bzero,dynamic_biomass_zero ,bio_all_eq,biomass ,bio_smry_eq,biomass_reference_age ,ssbfished_eq,spawning_biomass_fished -,ssbfished_r, +,ssbfished_r,spawning_biomass_fished_recruitment ,f_std,fishing_mortality ,ave_f,fishing_mortality_average ,maxf,fishing_mortality_max @@ -281,3 +281,6 @@ Dynamic_Bzero,Dynamic_Bzero,dynamic_biomass_zero ,enc_catch, ,mnage_smry, ,mnage_catch, +,ssb,spawning_biomass +,ssb_nofishing,spawning_biomass_no_fishing +,f_msy,fishing_mortality_msy From 56ef452db658aef1f28f28902be398a0f1b4af65 Mon Sep 17 00:00:00 2001 From: Sam Schiano <125507018+Schiano-NOAA@users.noreply.github.com> Date: Mon, 20 Jul 2026 14:34:20 -0400 Subject: [PATCH 28/28] add documentation for new arguments in aa plots --- R/plot_abundance_at_age.R | 10 ++++++++++ man/plot_abundance_at_age.Rd | 12 ++++++++++++ man/plot_biomass_at_age.Rd | 8 ++++++++ 3 files changed, 30 insertions(+) diff --git a/R/plot_abundance_at_age.R b/R/plot_abundance_at_age.R index 0763becb..a28dae86 100644 --- a/R/plot_abundance_at_age.R +++ b/R/plot_abundance_at_age.R @@ -28,6 +28,16 @@ #' #' Default: `TRUE` #' +#' @param module (Optional) A string indicating the module_name found in `dat`. +#' If selecting >1 module, place them in a vector like c("module1", "module2"). +#' +#' Default: NULL +#' +#' If the interactive and >1 module_name is found, user will select the +#' module_name in the console. @seealso [filter_data()] +#' @param interactive A logical value indicating if the environment is interactive. +#' +#' Default: `FALSE` #' @param make_rda TRUE/FALSE; indicate whether to produce an .rda file containing #' a list with the figure/table, caption, and alternative text (if figure). If TRUE, #' the .rda will be exported to the folder indicated in the argument "rda_dir". diff --git a/man/plot_abundance_at_age.Rd b/man/plot_abundance_at_age.Rd index 9020b9c0..e88052b4 100644 --- a/man/plot_abundance_at_age.Rd +++ b/man/plot_abundance_at_age.Rd @@ -46,6 +46,18 @@ is relative to z Default: `TRUE`} +\item{module}{(Optional) A string indicating the module_name found in `dat`. +If selecting >1 module, place them in a vector like c("module1", "module2"). + +Default: NULL + +If the interactive and >1 module_name is found, user will select the +module_name in the console. @seealso [filter_data()]} + +\item{interactive}{A logical value indicating if the environment is interactive. + +Default: `FALSE`} + \item{make_rda}{TRUE/FALSE; indicate whether to produce an .rda file containing a list with the figure/table, caption, and alternative text (if figure). If TRUE, the .rda will be exported to the folder indicated in the argument "rda_dir". diff --git a/man/plot_biomass_at_age.Rd b/man/plot_biomass_at_age.Rd index bbba2bd4..abf4734b 100644 --- a/man/plot_biomass_at_age.Rd +++ b/man/plot_biomass_at_age.Rd @@ -44,6 +44,14 @@ is relative to z Default: `TRUE`} +\item{module}{(Optional) A string indicating the module_name found in `dat`. +If selecting >1 module, place them in a vector like c("module1", "module2"). + +Default: NULL + +If the interactive and >1 module_name is found, user will select the +module_name in the console. @seealso [filter_data()]} + \item{interactive}{TRUE/FALSE; indicate whether the environment in which the function is operating is interactive. This bypasses some options for filtering when preparing data for the plot.