Skip to content

Commit 65c0687

Browse files
author
Nicholas Clark
committed
begin support for ggplot plotting
1 parent c1ab3a3 commit 65c0687

File tree

6 files changed

+296
-3
lines changed

6 files changed

+296
-3
lines changed

DESCRIPTION

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Suggests:
5252
rjags,
5353
coda,
5454
runjags,
55+
tibble (>= 3.0.0),
5556
usethis,
5657
testthat
5758
Additional_repositories: https://mc-stan.org/r-packages/

NAMESPACE

+12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ S3method(as_draws_matrix,mvgam)
1414
S3method(as_draws_rvars,mvgam)
1515
S3method(coef,mvgam)
1616
S3method(conditional_effects,mvgam)
17+
S3method(eval_smooth,mod.smooth)
18+
S3method(eval_smooth,moi.smooth)
1719
S3method(find_predictors,mvgam)
1820
S3method(find_predictors,mvgam_prefit)
1921
S3method(fitted,mvgam)
@@ -130,6 +132,7 @@ importFrom(brms,pstudent_t)
130132
importFrom(brms,qstudent_t)
131133
importFrom(brms,rbeta_binomial)
132134
importFrom(brms,rstudent_t)
135+
importFrom(brms,stancode)
133136
importFrom(brms,student)
134137
importFrom(ggplot2,scale_colour_discrete)
135138
importFrom(ggplot2,scale_fill_discrete)
@@ -154,6 +157,14 @@ importFrom(graphics,polygon)
154157
importFrom(graphics,rect)
155158
importFrom(graphics,rug)
156159
importFrom(graphics,title)
160+
importFrom(gratia,by_level)
161+
importFrom(gratia,by_variable)
162+
importFrom(gratia,eval_smooth)
163+
importFrom(gratia,is_factor_by_smooth)
164+
importFrom(gratia,smooth_dim)
165+
importFrom(gratia,smooth_label)
166+
importFrom(gratia,smooths)
167+
importFrom(gratia,spline_values)
157168
importFrom(insight,find_predictors)
158169
importFrom(insight,get_data)
159170
importFrom(insight,get_predictors)
@@ -271,6 +282,7 @@ importFrom(stats,ts)
271282
importFrom(stats,update)
272283
importFrom(stats,update.formula)
273284
importFrom(stats,var)
285+
importFrom(tibble,add_column)
274286
importFrom(utils,getFromNamespace)
275287
importFrom(utils,head)
276288
importFrom(utils,lsf.str)

R/monotonic.R

+220
Original file line numberDiff line numberDiff line change
@@ -412,3 +412,223 @@ add_mono_model_file = function(model_file,
412412
return(list(model_file = model_file,
413413
model_data = model_data))
414414
}
415+
416+
#' Evaluation of a monotonically increasing function
417+
#' These evaluation functions are needed so that gratia::draw methods work with mvgam
418+
#' monotonic smooths
419+
#' @importFrom gratia eval_smooth smooths by_variable smooth_label spline_values is_factor_by_smooth by_level smooth_dim
420+
#' @rdname monotonic
421+
#' @export
422+
eval_smooth.moi.smooth = function(smooth,
423+
model,
424+
n = 100,
425+
n_3d = NULL,
426+
n_4d = NULL,
427+
data = NULL,
428+
unconditional = FALSE,
429+
overall_uncertainty = TRUE,
430+
dist = NULL,
431+
...) {
432+
model$cmX <- model$coefficients
433+
434+
## deal with data if supplied
435+
data <- process_user_data_for_eval(
436+
data = data, model = model,
437+
n = n, n_3d = n_3d, n_4d = n_4d,
438+
id = which_smooth(
439+
model,
440+
smooth_label(smooth)
441+
)
442+
)
443+
444+
by_var <- gratia::by_variable(smooth) # even if not a by as we want NA later
445+
if (by_var == "NA") {
446+
by_var <- NA_character_
447+
}
448+
449+
## values of spline at data
450+
eval_sm <- gratia::spline_values(smooth,
451+
data = data,
452+
unconditional = unconditional,
453+
model = model,
454+
overall_uncertainty = overall_uncertainty
455+
)
456+
457+
## add on info regarding by variable
458+
eval_sm <- add_by_var_column(eval_sm, by_var = by_var)
459+
## add on spline type info
460+
eval_sm <- add_smooth_type_column(eval_sm, sm_type = "Mono inc P spline")
461+
462+
# set some values to NA if too far from the data
463+
if (gratia::smooth_dim(smooth) == 2L && (!is.null(dist) && dist > 0)) {
464+
eval_sm <- too_far_to_na(smooth,
465+
input = eval_sm,
466+
reference = model[["model"]],
467+
cols = c(".estimate", ".se"),
468+
dist = dist
469+
)
470+
}
471+
## return
472+
eval_sm
473+
}
474+
475+
#' Evaluation of a monotonically decreasing function
476+
#' @rdname monotonic
477+
#' @param model an object of class `"gam"`
478+
#' @param smooth a smooth object of class `"moi.smooth"` or `"mod.smooth"`
479+
#' @param n numeric; the number of points over the range of the covariate at
480+
#' which to evaluate the smooth.
481+
#' @param n_3d,n_4d numeric; the number of points over the range of last
482+
#' covariate in a 3D or 4D smooth. The default is `NULL` which achieves the
483+
#' standard behaviour of using `n` points over the range of all covariate,
484+
#' resulting in `n^d` evaluation points, where `d` is the dimension of the
485+
#' smooth. For `d > 2` this can result in very many evaluation points and slow
486+
#' performance. For smooths of `d > 4`, the value of `n_4d` will be used for
487+
#' all dimensions `> 4`, unless this is `NULL`, in which case the default
488+
#' behaviour (using `n` for all dimensions) will be observed.
489+
#' @param data a data frame of covariate values at which to evaluate the
490+
#' smooth.
491+
#' @param unconditional logical; should confidence intervals include the
492+
#' uncertainty due to smoothness selection? If `TRUE`, the corrected Bayesian
493+
#' covariance matrix will be used.
494+
#' @param overall_uncertainty logical; should the uncertainty in the model
495+
#' constant term be included in the standard error of the evaluate values of
496+
#' the smooth?
497+
#' @param dist numeric; if greater than 0, this is used to determine when
498+
#' a location is too far from data to be plotted when plotting 2-D smooths.
499+
#' The data are scaled into the unit square before deciding what to exclude,
500+
#' and `dist` is a distance within the unit square. See
501+
#' [mgcv::exclude.too.far()] for further details.
502+
#' @param ... ignored.
503+
#' @export
504+
eval_smooth.mod.smooth = function(smooth,
505+
model,
506+
n = 100,
507+
n_3d = NULL,
508+
n_4d = NULL,
509+
data = NULL,
510+
unconditional = FALSE,
511+
overall_uncertainty = TRUE,
512+
dist = NULL,
513+
...) {
514+
model$cmX <- model$coefficients
515+
516+
## deal with data if supplied
517+
data <- process_user_data_for_eval(
518+
data = data, model = model,
519+
n = n, n_3d = n_3d, n_4d = n_4d,
520+
id = which_smooth(
521+
model,
522+
smooth_label(smooth)
523+
)
524+
)
525+
526+
by_var <- gratia::by_variable(smooth) # even if not a by as we want NA later
527+
if (by_var == "NA") {
528+
by_var <- NA_character_
529+
}
530+
531+
## values of spline at data
532+
eval_sm <- gratia::spline_values(smooth,
533+
data = data,
534+
unconditional = unconditional,
535+
model = model,
536+
overall_uncertainty = overall_uncertainty
537+
)
538+
539+
## add on info regarding by variable
540+
eval_sm <- add_by_var_column(eval_sm, by_var = by_var)
541+
## add on spline type info
542+
eval_sm <- add_smooth_type_column(eval_sm, sm_type = "Mono dec P spline")
543+
544+
# set some values to NA if too far from the data
545+
if (gratia::smooth_dim(smooth) == 2L && (!is.null(dist) && dist > 0)) {
546+
eval_sm <- too_far_to_na(smooth,
547+
input = eval_sm,
548+
reference = model[["model"]],
549+
cols = c(".estimate", ".se"),
550+
dist = dist
551+
)
552+
}
553+
## return
554+
eval_sm
555+
}
556+
557+
#' Utility functions; full credit goes to Gavin Simpson, the developer and
558+
#' maintainer of the gratia package
559+
#' @noRd
560+
`is.gamm` <- function(object) {
561+
inherits(object, "gamm")
562+
}
563+
564+
#' @noRd
565+
`is.gamm4` <- function(object) {
566+
is.list(object) & (!is.null(object[["gam"]]))
567+
}
568+
569+
#' @noRd
570+
`is.gam` <- function(object) {
571+
inherits(object, "gam")
572+
}
573+
574+
#' @noRd
575+
`is.bam` <- function(object) {
576+
inherits(object, "bam")
577+
}
578+
579+
#' @noRd
580+
`which_smooth` <- function(object, term) {
581+
if (is.gamm(object) || is.gamm4(object)) {
582+
object <- object[["gam"]]
583+
}
584+
smooths <- smooths(object)
585+
which(term == smooths)
586+
}
587+
588+
#' @noRd
589+
`process_user_data_for_eval` <- function(
590+
data, model, n, n_3d, n_4d, id,
591+
var_order = NULL) {
592+
if (is.null(data)) {
593+
data <- smooth_data(
594+
model = model,
595+
n = n,
596+
n_3d = n_3d,
597+
n_4d = n_4d,
598+
id = id,
599+
var_order = var_order
600+
)
601+
} else {
602+
smooth <- get_smooths_by_id(model, id)[[1L]]
603+
vars <- smooth_variable(smooth)
604+
by_var <- by_variable(smooth)
605+
if (!identical(by_var, "NA")) {
606+
vars <- append(vars, by_var)
607+
}
608+
## if this is a by variable, filter the by variable for the required
609+
## level now
610+
if (gratia::is_factor_by_smooth(smooth)) {
611+
data <- data %>% filter(.data[[by_var]] == gratia::by_level(smooth))
612+
}
613+
}
614+
data
615+
}
616+
617+
#' @importFrom tibble add_column
618+
#' @noRd
619+
`add_by_var_column` <- function(object, by_var, n = NULL) {
620+
if (is.null(n)) {
621+
n <- NROW(object)
622+
}
623+
insight::check_if_installed("tibble")
624+
tibble::add_column(object, .by = rep(by_var, times = n), .after = 1L)
625+
}
626+
627+
#' @noRd
628+
`add_smooth_type_column` <- function(object, sm_type, n = NULL) {
629+
if (is.null(n)) {
630+
n <- NROW(object)
631+
}
632+
insight::check_if_installed("tibble")
633+
tibble::add_column(object, .type = rep(sm_type, times = n), .after = 1L)
634+
}

R/stan_utils.R

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ print.mvgammodel = function(x, ...){
3434
}
3535

3636
#' @export
37+
#' @importFrom brms stancode
3738
#' @rdname code
3839
stancode.mvgam_prefit = function(object){
3940

man/monotonic.Rd

+62-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/mvgam.dll

23 KB
Binary file not shown.

0 commit comments

Comments
 (0)