Skip to content

Commit 0851661

Browse files
committed
Merge branch 'main' into project
2 parents 0c6fcdc + 3b7b1bc commit 0851661

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+610
-73
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@
2121
^CRAN-SUBMISSION$
2222
^vignettes/web_only$
2323
revdep/
24+
^vignettes/articles$

.github/workflows/pkgdown.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ jobs:
4040
remotes::install_cran("cowplot")
4141
remotes::install_cran("rnaturalearth")
4242
remotes::install_cran("rnaturalearthdata")
43+
remotes::install_cran("pROC")
4344
install.packages("Matrix", type = "source")
4445
install.packages("TMB", type = "source")
4546
shell: Rscript {0}

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Type: Package
22
Package: sdmTMB
33
Title: Spatial and Spatiotemporal SPDE-Based GLMMs with 'TMB'
4-
Version: 0.6.0.9001
4+
Version: 0.6.0.9010
55
Authors@R: c(
66
person(c("Sean", "C."), "Anderson", , "sean@seananderson.ca",
77
role = c("aut", "cre"),
@@ -110,5 +110,5 @@ Config/testthat/parallel: true
110110
Encoding: UTF-8
111111
LazyData: true
112112
Roxygen: list(markdown = TRUE)
113-
RoxygenNote: 7.3.1
113+
RoxygenNote: 7.3.2
114114
SystemRequirements: GNU make

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ S3method(nobs,sdmTMB)
1414
S3method(plot,sdmTMBmesh)
1515
S3method(predict,sdmTMB)
1616
S3method(print,sdmTMB)
17+
S3method(print,sdmTMB_cv)
1718
S3method(ranef,sdmTMB)
1819
S3method(residuals,sdmTMB)
1920
S3method(simulate,sdmTMB)

NEWS.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,31 @@
22

33
* Add `project()` experimental function.
44

5-
* Add progress bar to `simulate.sdmTMB()`.
5+
* Add print method for `sdmTMB_cv()` output. #319
6+
7+
* Add progress bar to `simulate.sdmTMB()`. #346
8+
9+
* Add AUC and TSS examples to cross validation vignette. #268
10+
11+
* Add `model` (linear predictor number) argument to coef() method. Also,
12+
write documentation for `?coef.sdmTMB`. #351
13+
14+
* Add helpful error message if some coordinates in make_mesh() are NA. #365
15+
16+
* Add informative message if fitting with an offset but predicting with offset
17+
argument left at NULL on newdata. #372
18+
19+
* Fix passing of `offset` argument through in `sdmTMB_cv()`. Before it was being
20+
omitted in the prediction (i.e., set to 0). #372
21+
22+
* Fig bug in `exponentiate` argument for `tidy()`. Set `conf.int = TRUE` as
23+
default. #353
24+
25+
* Fix bug in prediction from `delta_truncated_nbinom1()` and
26+
`delta_truncated_nbinom2()` families. The positive component
27+
needs to be transformed to represent the mean of the *un*truncated
28+
distribution first before multiplying by the probability of a non-zero.
29+
Thanks to @tom-peatman #350
630

731
* Add `get_eao()` to calculate effective area occupied.
832

@@ -56,7 +80,7 @@
5680
# sdmTMB 0.5.0
5781

5882
* Overhaul residuals vignette ('article')
59-
<https://pbs-assess.github.io/sdmTMB/articles/web_only/residual-checking.html>
83+
<https://pbs-assess.github.io/sdmTMB/articles/residual-checking.html>
6084
including brief intros to randomized quantile residuals, simulation-based
6185
residuals, 'one-sample' residuals, and uniform vs. Gaussian residuals.
6286

R/cross-val.R

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,10 @@ sdmTMB_cv <- function(
287287
cli_abort("`weights` cannot be specified within sdmTMB_cv().")
288288
}
289289
if ("offset" %in% names(dot_args)) {
290-
.offset <- eval(dot_args$offset)
291-
if (parallel && !is.character(.offset) && !is.null(.offset)) {
292-
cli_abort("We recommend using a character value for 'offset' (indicating the column name) when applying parallel cross validation.")
290+
if (!is.character(dot_args$offset)) {
291+
cli_abort("Please use a character value for 'offset' (indicating the column name) for cross validation.")
293292
}
293+
.offset <- eval(dot_args$offset)
294294
} else {
295295
.offset <- NULL
296296
}
@@ -369,7 +369,9 @@ sdmTMB_cv <- function(
369369

370370
# FIXME: only use TMB report() below to be faster!
371371
# predict for withheld data:
372-
predicted <- predict(object, newdata = cv_data, type = "response")
372+
predicted <- predict(object, newdata = cv_data, type = "response",
373+
offset = if (!is.null(.offset)) cv_data[[.offset]] else rep(0, nrow(cv_data)))
374+
373375
cv_data$cv_predicted <- predicted$est
374376
response <- get_response(object$formula[[1]])
375377
withheld_y <- predicted[[response]]
@@ -451,7 +453,7 @@ sdmTMB_cv <- function(
451453
pdHess <- vapply(out, `[[`, "pdHess", FUN.VALUE = logical(1L))
452454
max_grad <- vapply(out, `[[`, "max_gradient", FUN.VALUE = numeric(1L))
453455
converged <- all(pdHess)
454-
list(
456+
out <- list(
455457
data = data,
456458
models = models,
457459
fold_loglik = fold_cv_ll,
@@ -460,9 +462,35 @@ sdmTMB_cv <- function(
460462
pdHess = pdHess,
461463
max_gradients = max_grad
462464
)
465+
`class<-`(out, "sdmTMB_cv")
463466
}
464467

465468
log_sum_exp <- function(x) {
466469
max_x <- max(x)
467470
max_x + log(sum(exp(x - max_x)))
468471
}
472+
473+
#' @export
474+
#' @import methods
475+
print.sdmTMB_cv <- function(x, ...) {
476+
nmods <- length(x$models)
477+
nconverged <- sum(x$converged)
478+
cat(paste0("Cross validation of sdmTMB models with ", nmods, " folds.\n"))
479+
cat("\n")
480+
cat("Summary of the first fold model fit:\n")
481+
cat("\n")
482+
print(x$models[[1]])
483+
cat("\n")
484+
cat("Access the rest of the models in a list element named `models`.\n")
485+
cat("E.g. `object$models[[2]]` for the 2nd fold model fit.\n")
486+
cat("\n")
487+
cat(paste0(nconverged, " out of ", nmods, " models are consistent with convergence.\n"))
488+
cat("Figure out which folds these are in the `converged` list element.\n")
489+
cat("\n")
490+
cat(paste0("Out-of-sample log likelihood for each fold: ", paste(round(x$fold_loglik, 2), collapse = ", "), ".\n"))
491+
cat("Access these values in the `fold_loglik` list element.\n")
492+
cat("\n")
493+
cat("Sum of out-of-sample log likelihoods:", round(x$sum_loglik, 2), "\n")
494+
cat("More positive values imply better out-of-sample prediction.\n")
495+
cat("Access this value in the `sum_loglik` list element.\n")
496+
}

R/dharma.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#'
2828
#' @details
2929
#'
30-
#' See the [residuals vignette](https://pbs-assess.github.io/sdmTMB/articles/web_only/residual-checking.html).
30+
#' See the [residuals vignette](https://pbs-assess.github.io/sdmTMB/articles/residual-checking.html).
3131
#'
3232
#' Advantages to these residuals over the ones from the [residuals.sdmTMB()]
3333
#' method are (1) they work with delta/hurdle models for the combined

R/families.R

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ nbinom1 <- function(link = "log") {
222222
add_to_family(x)
223223
}
224224

225+
utils::globalVariables(".phi") ## avoid R CMD check NOTE
226+
225227
#' @export
226228
#' @examples
227229
#' truncated_nbinom2(link = "log")
@@ -235,11 +237,21 @@ truncated_nbinom2 <- function(link = "log") {
235237
stats <- stats::make.link(linktemp)
236238
else if (is.character(link))
237239
stats <- stats::make.link(link)
238-
240+
linkinv <- function(eta, phi = NULL) {
241+
s1 <- eta
242+
if (is.null(phi)) phi <- .phi
243+
s2 <- logspace_add(0, s1 - log(phi)) # log(1 + mu/phi)
244+
log_nzprob <- logspace_sub(0, -phi * s2)
245+
exp(eta) / exp(log_nzprob)
246+
}
239247
structure(list(family = "truncated_nbinom2", link = linktemp, linkfun = stats$linkfun,
240-
linkinv = stats$linkinv), class = "family")
248+
linkinv = linkinv), class = "family")
241249
}
242250

251+
logspace_sub <- function (lx, ly) lx + log1mexp(lx - ly)
252+
logspace_add <- function (lx, ly) pmax(lx, ly) + log1p(exp(-abs(lx - ly)))
253+
log1mexp <- function(x) ifelse(x <= log(2), log(-expm1(-x)), log1p(-exp(-x)))
254+
243255
#' @export
244256
#' @examples
245257
#' truncated_nbinom1(link = "log")
@@ -253,9 +265,15 @@ truncated_nbinom1 <- function(link = "log") {
253265
stats <- stats::make.link(linktemp)
254266
else if (is.character(link))
255267
stats <- stats::make.link(link)
256-
268+
linkinv <- function(eta, phi = NULL) {
269+
mu <- exp(eta)
270+
if (is.null(phi)) phi <- .phi
271+
s2 <- logspace_add(0, log(phi)) # log(1 + phi)
272+
log_nzprob <- logspace_sub(0, -mu / phi * s2) # 1 - prob(0)
273+
mu / exp(log_nzprob)
274+
}
257275
structure(list(family = "truncated_nbinom1", link = linktemp, linkfun = stats$linkfun,
258-
linkinv = stats$linkinv), class = "family")
276+
linkinv = linkinv), class = "family")
259277
}
260278

261279
#' @param df Student-t degrees of freedom fixed value parameter.

R/fit.R

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,16 @@ sdmTMB <- function(
15011501
sd_report <- TMB::sdreport(tmb_obj, getJointPrecision = get_joint_precision)
15021502
conv <- get_convergence_diagnostics(sd_report)
15031503

1504+
## save params that families need to grab from environments:
1505+
if (any(family$family %in% c("truncated_nbinom1", "truncated_nbinom2"))) {
1506+
phi <- exp(tmb_obj$par[["ln_phi"]])
1507+
if (delta) {
1508+
assign(".phi", phi, environment(out_structure[["family"]][[2]][["linkinv"]]))
1509+
} else {
1510+
assign(".phi", phi, environment(out_structure[["family"]][["linkinv"]]))
1511+
}
1512+
}
1513+
15041514
out_structure$tmb_obj <- tmb_obj
15051515
out <- c(out_structure, list(
15061516
model = tmb_opt,

R/mesh.R

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ make_mesh <- function(data, xy_cols,
8888
cli_abort(msg)
8989
}
9090

91+
all_x_non_na <- sum(is.na(data[[xy_cols[[1]]]])) == 0L
92+
all_y_non_na <- sum(is.na(data[[xy_cols[[2]]]])) == 0L
93+
if (!all_x_non_na || !all_y_non_na) {
94+
msg <- c("Some coordinates in `xy_cols` were NA.", "
95+
Remove or fix these rows before proceeding.")
96+
cli_abort(msg)
97+
}
98+
9199
if (max(data[[xy_cols[1]]]) > 1e4 || max(data[[xy_cols[2]]] > 1e4)) {
92100
msg <- paste0(
93101
"The x or y column values are fairly large. ",
@@ -216,30 +224,11 @@ binary_search_knots <- function(loc_xy,
216224
#' @param ... Passed to [graphics::plot()].
217225
#'
218226
#' @importFrom graphics points
219-
#' @return `plot.sdmTMBmesh()`: A plot of the mesh and data points. If
220-
#' \pkg{ggplot2} is installed, a \pkg{ggplot2} object is
221-
#' returned, otherwise a base graphics R plot is returned. To make your own,
222-
#' pass `your_mesh$mesh` to `inlabru::gg()`.
227+
#' @return `plot.sdmTMBmesh()`: A plot of the mesh and data points. To make your
228+
#' own \pkg{ggplot2} version, pass `your_mesh$mesh` to `inlabru::gg()`.
223229
#' @rdname make_mesh
224230
#' @export
225231
plot.sdmTMBmesh <- function(x, ...) {
226-
# r1 <- requireNamespace("inlabru", quietly = TRUE)
227-
# r2 <- requireNamespace("ggplot2", quietly = TRUE)
228-
# if (r1 && r2) {
229-
# dat <- data.frame(
230-
# x = x$loc_xy[,1,drop=TRUE],
231-
# y = x$loc_xy[,2,drop=TRUE]
232-
# )
233-
# ggplot2::ggplot() +
234-
# # inlabru::gg(x$mesh, ext.color = "grey20", ext.linewidth = 0.5, edge.color = "grey50") +
235-
# ggplot2::coord_sf() +
236-
# fmesher::geom_fm(data = x$mesh) +
237-
# ggplot2::geom_point(
238-
# data = dat,
239-
# mapping = ggplot2::aes(x = .data$x, y = .data$y), alpha = 0.4, pch = 20, colour = "#3182BD") +
240-
# # ggplot2::coord_fixed() +
241-
# ggplot2::labs(x = x$xy_cols[[1]], y = x$xy_cols[[2]])
242-
# } else {
243232
plot(x$mesh, main = NA, edge.color = "grey60", asp = 1, ...)
244233
points(x$loc_xy, pch = 21, cex = 0.3, col = "#00000080")
245234
points(x$loc_centers, pch = 20, col = "red")

0 commit comments

Comments
 (0)