pfmc-assessments / indexwc

Estimate indices of abundance for west coast fish species
2 stars 1 forks source link

[BUG]: Error in diagnostic plots #27

Closed chantelwetzel-noaa closed 6 months ago

chantelwetzel-noaa commented 6 months ago

Is there an existing issue for this?

Current Behavior

The diagnostic plots error out for delta models (have not fully tested for tweedie models) on the following lines in the diagnose function:

    ignore <- purrr::map(
      seq_along(fit[["formula"]]),
      .f = function(x, y, f_dir) {
        y[["residuals"]] <- y[[
          paste0("residuals", ifelse(x == 1, "", x))
        ]]
        map_residuals(
          y,
          save_prefix = file.path(f_dir, paste0("residuals_", x, "_"))
        )
      },
      y = fit[["data"]],
      f_dir = dir
    )

The error that prints to the screen is:

image

And output from rlang::last_trace() is:

``` rlang::last_trace() Error in `dplyr::mutate()`: ℹ In argument: `results = purrr::pmap(...)`. Caused by error in `purrr::pmap()`: ℹ In index: 1. --- Backtrace: ▆ 1. ├─data %>% ... 2. ├─dplyr::mutate(...) 3. ├─dplyr:::mutate.data.frame(...) 4. │ └─dplyr:::mutate_cols(.data, dplyr_quosures(...), by) 5. │ ├─base::withCallingHandlers(...) 6. │ └─dplyr:::mutate_col(dots[[i]], data, mask, new_columns) 7. │ └─mask$eval_all_mutate(quo) 8. │ └─dplyr (local) eval() 9. ├─purrr::pmap(...) 10. │ └─purrr:::pmap_("list", .l, .f, ..., .progress = .progress) 11. │ ├─purrr:::with_indexed_errors(...) 12. │ │ └─base::withCallingHandlers(...) 13. │ ├─purrr:::call_with_cleanup(...) 14. │ └─indexwc (local) .f(...) 15. │ └─indexwc:::diagnose(dir = dir_index, fit = fit, prediction_grid = grid) at indexwc/R/run_sdmtmb.R:153:3 16. │ └─purrr::map(...) at indexwc/R/diagnose.R:82:5 17. │ └─purrr:::map_("list", .x, .f, ..., .progress = .progress) 18. │ ├─purrr:::with_indexed_errors(...) 19. │ │ └─base::withCallingHandlers(...) 20. │ ├─purrr:::call_with_cleanup(...) 21. │ └─indexwc (local) .f(.x[[i]], ...) 22. │ └─indexwc::map_residuals(...) at indexwc/R/diagnose.R:88:9 23. │ ├─purrr::map(...) at indexwc/R/map_residuals.R:63:3 24. │ │ └─purrr:::map_("list", .x, .f, ..., .progress = .progress) 25. │ │ └─purrr:::vctrs_vec_compat(.x, .purrr_user_env) 26. │ ├─base::seq(ggforce::n_pages(gg)) at indexwc/R/map_residuals.R:63:3 27. │ └─ggforce::n_pages(gg) at indexwc/R/map_residuals.R:63:3 28. │ ├─ggplot2::ggplot_build(plot) 29. │ └─ggplot2:::ggplot_build.ggplot(plot) 30. │ └─ggplot2:::by_layer(...) 31. │ ├─rlang::try_fetch(...) 32. │ │ ├─base::tryCatch(...) 33. │ │ │ └─base (local) tryCatchList(expr, classes, parentenv, handlers) 34. │ │ │ └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]]) 35. │ │ │ └─base (local) doTryCatch(return(expr), name, parentenv, handler) 36. │ │ └─base::withCallingHandlers(...) 37. │ └─ggplot2 (local) f(l = layers[[i]], d = data[[i]]) 38. │ └─l$compute_aesthetics(d, plot) 39. │ └─ggplot2 (local) compute_aesthetics(..., self = self) 40. │ └─cli::cli_abort(...) 41. │ └─rlang::abort(...) 42. │ └─rlang:::signal_abort(cnd, .file) 43. │ └─base::signalCondition(cnd) 44. ├─rlang (local) ``(``) 45. │ └─handlers[[1L]](cnd) 46. │ └─cli::cli_abort(...) 47. │ └─rlang::abort(...) 48. │ └─rlang:::signal_abort(cnd, .file) 49. │ └─base::signalCondition(cnd) 50. ├─purrr (local) ``(``) 51. │ └─cli::cli_abort(...) 52. │ └─rlang::abort(...) 53. │ └─rlang:::signal_abort(cnd, .file) 54. │ └─base::signalCondition(cnd) 55. └─purrr (local) ``(``) 56. └─cli::cli_abort(...) --- Caused by error in `purrr::map()` at indexwc/R/diagnose.R:82:5: ℹ In index: 2. Caused by error in `ggplot2::geom_point()` at indexwc/R/map_residuals.R:41:3: ! Problem while computing aesthetics. ℹ Error occurred in the 2nd layer. --- Backtrace: ▆ 1. ├─data %>% ... 2. ├─dplyr::mutate(...) 3. ├─dplyr:::mutate.data.frame(...) 4. │ └─dplyr:::mutate_cols(.data, dplyr_quosures(...), by) 5. │ ├─base::withCallingHandlers(...) 6. │ └─dplyr:::mutate_col(dots[[i]], data, mask, new_columns) 7. │ └─mask$eval_all_mutate(quo) 8. │ └─dplyr (local) eval() 9. ├─purrr::pmap(...) 10. │ └─purrr:::pmap_("list", .l, .f, ..., .progress = .progress) 11. │ ├─purrr:::with_indexed_errors(...) 12. │ │ └─base::withCallingHandlers(...) 13. │ ├─purrr:::call_with_cleanup(...) 14. │ └─indexwc (local) .f(...) 15. │ └─indexwc:::diagnose(dir = dir_index, fit = fit, prediction_grid = grid) at indexwc/R/run_sdmtmb.R:153:3 16. │ └─purrr::map(...) at indexwc/R/diagnose.R:82:5 17. │ └─purrr:::map_("list", .x, .f, ..., .progress = .progress) 18. │ ├─purrr:::with_indexed_errors(...) 19. │ │ └─base::withCallingHandlers(...) 20. │ ├─purrr:::call_with_cleanup(...) 21. │ └─indexwc (local) .f(.x[[i]], ...) 22. │ └─indexwc::map_residuals(...) at indexwc/R/diagnose.R:88:9 23. │ ├─purrr::map(...) at indexwc/R/map_residuals.R:63:3 24. │ │ └─purrr:::map_("list", .x, .f, ..., .progress = .progress) 25. │ │ └─purrr:::vctrs_vec_compat(.x, .purrr_user_env) 26. │ ├─base::seq(ggforce::n_pages(gg)) at indexwc/R/map_residuals.R:63:3 27. │ └─ggforce::n_pages(gg) at indexwc/R/map_residuals.R:63:3 28. │ ├─ggplot2::ggplot_build(plot) 29. │ └─ggplot2:::ggplot_build.ggplot(plot) 30. │ └─ggplot2:::by_layer(...) 31. │ ├─rlang::try_fetch(...) 32. │ │ ├─base::tryCatch(...) 33. │ │ │ └─base (local) tryCatchList(expr, classes, parentenv, handlers) 34. │ │ │ └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]]) 35. │ │ │ └─base (local) doTryCatch(return(expr), name, parentenv, handler) 36. │ │ └─base::withCallingHandlers(...) 37. │ └─ggplot2 (local) f(l = layers[[i]], d = data[[i]]) 38. │ └─l$compute_aesthetics(d, plot) 39. │ └─ggplot2 (local) compute_aesthetics(..., self = self) 40. │ └─cli::cli_abort(...) 41. │ └─rlang::abort(...) 42. │ └─rlang:::signal_abort(cnd, .file) 43. │ └─base::signalCondition(cnd) 44. └─rlang (local) ``(``) 45. └─handlers[[1L]](cnd) 46. └─cli::cli_abort(...) Caused by error in `compute_aesthetics()`: ! Aesthetics are not valid data columns. ✖ The following aesthetics are invalid: ✖ `colour = NULL` ✖ `fill = NULL` ℹ Did you mistype the name of a data column or forget to add `after_stat()`? --- Backtrace: ▆ 1. ├─data %>% ... 2. ├─dplyr::mutate(...) 3. ├─dplyr:::mutate.data.frame(...) 4. │ └─dplyr:::mutate_cols(.data, dplyr_quosures(...), by) 5. │ ├─base::withCallingHandlers(...) 6. │ └─dplyr:::mutate_col(dots[[i]], data, mask, new_columns) 7. │ └─mask$eval_all_mutate(quo) 8. │ └─dplyr (local) eval() 9. └─purrr::pmap(...) 10. └─purrr:::pmap_("list", .l, .f, ..., .progress = .progress) 11. ├─purrr:::with_indexed_errors(...) 12. │ └─base::withCallingHandlers(...) 13. ├─purrr:::call_with_cleanup(...) 14. └─indexwc (local) .f(...) 15. └─indexwc:::diagnose(dir = dir_index, fit = fit, prediction_grid = grid) at indexwc/R/run_sdmtmb.R:153:3 16. └─purrr::map(...) at indexwc/R/diagnose.R:82:5 17. └─purrr:::map_("list", .x, .f, ..., .progress = .progress) 18. ├─purrr:::with_indexed_errors(...) 19. │ └─base::withCallingHandlers(...) 20. ├─purrr:::call_with_cleanup(...) 21. └─indexwc (local) .f(.x[[i]], ...) 22. └─indexwc::map_residuals(...) at indexwc/R/diagnose.R:88:9 23. ├─purrr::map(...) at indexwc/R/map_residuals.R:63:3 24. │ └─purrr:::map_("list", .x, .f, ..., .progress = .progress) 25. │ └─purrr:::vctrs_vec_compat(.x, .purrr_user_env) 26. ├─base::seq(ggforce::n_pages(gg)) at indexwc/R/map_residuals.R:63:3 27. └─ggforce::n_pages(gg) at indexwc/R/map_residuals.R:63:3 28. ├─ggplot2::ggplot_build(plot) 29. └─ggplot2:::ggplot_build.ggplot(plot) 30. └─ggplot2:::by_layer(...) 31. ├─rlang::try_fetch(...) 32. │ ├─base::tryCatch(...) 33. │ │ └─base (local) tryCatchList(expr, classes, parentenv, handlers) 34. │ │ └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]]) 35. │ │ └─base (local) doTryCatch(return(expr), name, parentenv, handler) 36. │ └─base::withCallingHandlers(...) 37. └─ggplot2 (local) f(l = layers[[i]], d = data[[i]]) 38. └─l$compute_aesthetics(d, plot) 39. └─ggplot2 (local) compute_aesthetics(..., self = self) Run rlang::last_trace(drop = FALSE) to see 5 hidden frames. ``` ### Expected Behavior _No response_ ### Steps To Reproduce The model was run using the template call in the configuration.R file where the call to the model is: ``` to_run <- "aurora rockfish" species_data <- catch[which(catch$Common_name %in% to_run), ] configuration <- tibble::as_tibble(read.csv( file.path("data-raw", "configuration.csv") )) configuration <- configuration[which(configuration$species %in% to_run), ] data <-configuration %>% # Row by row ... do stuff then ungroup dplyr::rowwise() %>% # Pull the data based on the function found in fxn column dplyr::mutate( data_raw = list(format_data(data = species_data)), data_filtered = list(data_raw %>% dplyr::filter( depth <= min_depth, depth >= max_depth, latitude >= min_latitude, latitude <= max_latitude, year >= min_year, year <= max_year )) ) %>% dplyr::ungroup() best <- data %>% dplyr::mutate( # Evaluate the call in family family = purrr::map(family, .f = ~ eval(parse(text = .x))), # Run the model on each row in data results = purrr::pmap( .l = list( data = data_filtered, formula = formula, family = family, anisotropy = anisotropy, n_knots = knots, spatiotemporal = purrr::map2(spatiotemporal1, spatiotemporal2, list) ), .f = indexwc::run_sdmtmb ) ) ```

Environment

Encountered using R version 4.2.2

Anything else?

No response

chantelwetzel-noaa commented 6 months ago

Attaching a txt document with the output from rlang::last_trace() since the format got messed up in the original issue.

diagnose_error.txt

kellijohnson-NOAA commented 6 months ago

@chantelwetzel-noaa I have been doing some research to try and remedy this bug that I built into the code accidently. And, I believe that the easiest way to fix it is to change the configuration file to just have a single column for spatiotemporal instead of spatiotemporal1 and spatiotemporal2. That way we can pass either a vector or a single character to the spatiotemporal column. Does that sound like an okay fix? And, sorry it took me so long to wrap my head around how to get this done.

chantelwetzel-noaa commented 6 months ago

I think that proposed approach is reasonable and would resolve the issues I was encountering when running tweedie model (see fix-tweedie branch) but I am not sure if that would fix this error. Let me test this out locally and let you know what I get back.

kellijohnson-NOAA commented 6 months ago

Right, I got mixed up on the issue. This is an error with the mapping of the residuals. I just got the same error on my machine, so I can investigate it.

kellijohnson-NOAA commented 6 months ago

This is happening because in fit[["data"]] the names are as follows:

Browse[1]> names(fit[["data"]])
 [1] "year"                 "fyear"                "survey_name"
 [4] "common_name"          "catch_numbers"        "catch_weight"
 [7] "effort"               "pass_scaled"          "vessel_year"
[10] "longitude"            "latitude"             "depth"
[13] "depth_scaled"         "depth_scaled_squared" "x"
[16] "y"                    "residuals"

and it is expected that there would be "residuals_2" as well.

kellijohnson-NOAA commented 6 months ago

Looks like I broke the code here:

  if (
    lookup_is_delta(fit[["formula"]]) &&
    lookup_is_mixture(fit[["formula"]])
  ) {
    fit[["data"]][["residuals2"]] <- stats::residuals(fit, model = 2)
  }

I will fix it.