Skip to content

Commit

Permalink
Improve sanity check, fix #320
Browse files Browse the repository at this point in the history
  • Loading branch information
seananderson committed Mar 16, 2024
1 parent e997f2a commit 96e5a92
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 10 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
@@ -1,7 +1,7 @@
Type: Package
Package: sdmTMB
Title: Spatial and Spatiotemporal SPDE-Based GLMMs with 'TMB'
Version: 0.4.3.9001
Version: 0.4.3.9002
Authors@R: c(
person(c("Sean", "C."), "Anderson", , "sean@seananderson.ca",
role = c("aut", "cre"),
Expand Down
6 changes: 6 additions & 0 deletions NEWS.md
@@ -1,5 +1,11 @@
# sdmTMB (development version)

* Detect possible issue with factor(time) in formula if same column name is used
for `time` and `extra_time` is specified. #320

* Improve `sanity()` check output when there are NA fixed effect standard
errors.

* Set `intern = FALSE` within index bias correction, which seems to be
considerably faster when testing with most models.

Expand Down
19 changes: 12 additions & 7 deletions R/check.R
Expand Up @@ -112,14 +112,19 @@ sanity <- function(object, big_sd_log10 = 2, gradient_thresh = 0.001, silent = F

obj <- object$tmb_obj
random <- unique(names(obj$env$par[obj$env$random]))
s <- summary(object$sd_report)
se <- s[, "Std. Error"]
fixed_se <- !names(se) %in% random
se <- se[fixed_se]
np <- names(se)

pl <- as.list(object$sd_report, "Estimate")
ple <- as.list(object$sd_report, "Std. Error")
pars <- names(object$model$par)
pl <- pl[pars]
ple <- ple[pars]
np <- names(ple)
if (is_delta(object)) {
ple$ln_phi[1] <- 0 # don't flag NA, not estimated
}
se_na_ok <- TRUE
for (i in seq_along(se)) {
if (is.na(se[i])) {
for (i in seq_along(ple)) {
if (any(is.na(ple[i]))) {
if (!silent) cli::cli_alert_danger(c("`", np[i], paste0("` standard error is NA")))
par_message(np[i])
if (!silent) {
Expand Down
7 changes: 7 additions & 0 deletions R/fit.R
Expand Up @@ -711,6 +711,13 @@ sdmTMB <- function(
msg = "Specified `time` column is missing from `data`.")
assert_that(sum(is.na(as.numeric(data[[time]]))) == 0L,
msg = "Specified `time` column can't be coerced to a numeric value or contains NAs. Please remove any NAs in the time column.")
if (!is.null(extra_time)) { #320 protect against factor(time), extra_time clash
if (!is.list(formula)) .form <- list(formula)
x <- unlist(lapply(list(formula), \(x) attr(stats::terms(x), "term.labels")))
xf <- x[grep("factor\\(", x)]
if (any(c(grep(time, xf), grep(paste0("^", time, "$"), x))))
cli::cli_warn("Detected potential formula-time column clash. E.g., assuming 'year' is your time column: `formula = ... + factor(year)` combined with `time = 'year'`, and 'extra_time' specified. This can produce a non-identiable model because extra factor levels for the missing time slices will be created. To avoid this, rename your factor time column used in your formula. E.g. create a new column 'year_factor' in your data and use that in the formula. See issue https://github.com/pbs-assess/sdmTMB/issues/320.")
}
}
if (is.null(time)) {
time <- "_sdmTMB_time"
Expand Down
1 change: 1 addition & 0 deletions src/sdmTMB.cpp
@@ -1,4 +1,5 @@
#define TMB_LIB_INIT R_init_sdmTMB
#define EIGEN_DONT_PARALLELIZE
#include <TMB.hpp>
#include "utils.h"
// #include <omp.h>
Expand Down
4 changes: 2 additions & 2 deletions tests/testthat/test-2-print-anisotropy.R
Expand Up @@ -12,8 +12,8 @@ test_that("Print anisotropy prints correctly", {
)

expect_output(print(fit1), regexp = "range: 33.23")
expect_null(plot_anisotropy(fit1))
expect_null(plot_anisotropy2(fit1))
# expect_null(plot_anisotropy(fit1))
# expect_null(plot_anisotropy2(fit1))

# -------------------
# Anisotropy with spatial only
Expand Down
26 changes: 26 additions & 0 deletions tests/testthat/test-extra-time.R
Expand Up @@ -176,3 +176,29 @@ test_that("extra time does not affect estimation (without time series estimation
)
expect_equal(m$model$par, m1$model$par)
})

test_that("factor year extra time clash is detected and warned about", {
skip_on_cran()
skip_on_ci()
mesh <- make_mesh(pcod_2011, c("X", "Y"), cutoff = 20)
expect_warning({fit <- sdmTMB(
density ~ 0 + as.factor(year),
time = "year", extra_time = 2030, do_fit = FALSE,
data = pcod_2011, mesh = mesh,
family = tweedie(link = "log")
)}, regexp = "rename")
pcod_2011$year_f <- factor(pcod_2011$year)
expect_warning({fit <- sdmTMB(
density ~ 0 + year_f,
time = "year_f", do_fit = FALSE, extra_time = factor(2030),
data = pcod_2011, mesh = mesh,
family = tweedie(link = "log")
)})
pcod_2011$year_f2 <- pcod_2011$year_f
fit <- sdmTMB(
density ~ 0 + year_f,
time = "year_f2", do_fit = FALSE, extra_time = factor(2030),
data = pcod_2011, mesh = mesh,
family = tweedie(link = "log")
)
})

0 comments on commit 96e5a92

Please sign in to comment.