Diff of /R/summaries.R [000000] .. [ede2d4]

Switch to unified view

a b/R/summaries.R
1
##=============================================================================
2
##
3
## Copyright (c) 2019 Marco Colombo and Paul McKeigue
4
##
5
## This program is free software: you can redistribute it and/or modify
6
## it under the terms of the GNU General Public License as published by
7
## the Free Software Foundation, either version 3 of the License, or
8
## (at your option) any later version.
9
##
10
## This program is distributed in the hope that it will be useful,
11
## but WITHOUT ANY WARRANTY; without even the implied warranty of
12
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
## GNU General Public License for more details.
14
##
15
## You should have received a copy of the GNU General Public License
16
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
##
18
##=============================================================================
19
20
21
#' Summary for the fitted model
22
#'
23
#' @param object An object of class `hsstan`.
24
#' @param pars Vector of parameter names to be extracted. If `NULL`
25
#'        (default) then this refers to the set of predictors used in the
26
#'        model.
27
#' @param prob Width of the posterior intervals (0.95, by default).
28
#' @param digits Number of decimal places to be reported (2 by default).
29
#' @param sort Column name used to sort the results according to the absolute
30
#'        value of the column. If `NULL` (default) or the column name cannot
31
#'        be found, no sorting occurs.
32
#' @param decreasing Whether the results should be sorted in decreasing order
33
#'        when a valid column name is specified in `sort` (`TRUE` by default).
34
#' @param max.rows Maximum number of rows to be returned. If `NULL`
35
#'        (default) or 0, all results are returned.
36
#' @param ... Currently ignored.
37
#'
38
#' @return
39
#' A matrix with summaries from the posterior distribution of the parameters
40
#' of interest.
41
#'
42
#' @examples
43
#' \dontshow{utils::example("hsstan", echo=FALSE)}
44
#' # continued from ?hsstan
45
#' summary(hs.biom)
46
#'
47
#' @importMethodsFrom rstan summary
48
#' @method summary hsstan
49
#' @export
50
summary.hsstan <- function(object, pars=NULL, prob=0.95, digits=2,
51
                           sort=NULL, decreasing=TRUE, max.rows=NULL, ...) {
52
    validate.samples(object)
53
    validate.probability(prob)
54
    pars <- get.pars(object, pars)
55
    low <- (1 - prob) / 2
56
    upp <- 1 - low
57
    summary <- summary(object$stanfit, pars=pars, probs=c(low, upp))$summary
58
    summary[, "n_eff"] <- round(summary[, "n_eff"], 0)
59
    if (!is.null(sort) && sort %in% colnames(summary)) {
60
        ord <- order(abs(summary[, sort]), decreasing=decreasing)
61
        summary <- summary[ord, ]
62
    }
63
    if (!is.null(max.rows)) {
64
        if (max.rows > 0 && max.rows < nrow(summary))
65
            summary <- summary[1:max.rows, , drop=FALSE]
66
    }
67
    round(summary[, -match("se_mean", colnames(summary)), drop=FALSE],
68
                digits)
69
}
70
71
#' Print a summary for the fitted model
72
#'
73
#' @param x An object of class `hsstan`.
74
#' @param ... Further arguments to [summary()].
75
#'
76
#' @export
77
print.hsstan <- function(x, ...) {
78
    print(summary(x, ...))
79
}
80
81
#' Posterior summary
82
#'
83
#' Produce a summary of the posterior samples for the quantities of interest.
84
#'
85
#' @param x An object containing or representing posterior samples. If `x`
86
#'        is a matrix, it should have size `S` by `Q`, where `S`
87
#'        is the number of posterior samples, and `Q` is the number of
88
#'        quantities of interest.
89
#' @param prob Width of the posterior intervals (0.95, by default).
90
#' @param ... Further arguments passed to or from other methods.
91
#'
92
#' @return
93
#' A matrix with columns containing mean, standard deviation and posterior
94
#' intervals for the given quantities.
95
#'
96
#' @seealso
97
#' [summary()] to produce summaries of `hsstan` objects that include the number
98
#' of effective samples and the split-Rhat diagnostic.
99
#'
100
#' @export
101
posterior_summary <- function(x, prob, ...) {
102
    UseMethod("posterior_summary")
103
}
104
105
#' @rdname posterior_summary
106
#' @export
107
posterior_summary.default <- function(x, prob=0.95, ...) {
108
    validate.probability(prob)
109
    if (NCOL(x) == 1)
110
        x <- as.matrix(x)
111
    t(apply(x, 2, vector.summary, prob))
112
}
113
114
#' @rdname posterior_summary
115
#' @param pars Vector of parameter names to be extracted. If `NULL`
116
#'        (default) then this refers to the set of predictors used in the
117
#'        model.
118
#'
119
#' @examples
120
#' \dontshow{utils::example("hsstan", echo=FALSE)}
121
#' # continued from ?hsstan
122
#' posterior_summary(hs.biom)
123
#'
124
#' @export
125
posterior_summary.hsstan <- function(x, prob=0.95, pars=NULL, ...) {
126
    validate.samples(x)
127
    pars <- get.pars(x, pars)
128
    posterior_summary(as.matrix(x$stanfit, pars=pars), prob, ...)
129
}
130
131
#' Sampler statistics
132
#'
133
#' Report statistics on the parameters used in the sampler, the sampler
134
#' behaviour and the sampling time.
135
#'
136
#' @param object An object of class `hsstan`.
137
#'
138
#' @return
139
#' A matrix with `C + 1` rows, where `C` is the number of Markov
140
#' chains, reporting average acceptance probability, average stepsize, number
141
#' of divergent transitions, maximum tree depth, total number of gradient
142
#' evaluations, warmup and sampling times in seconds.
143
#'
144
#' @examples
145
#' \dontshow{utils::example("hsstan", echo=FALSE)}
146
#' # continued from ?hsstan
147
#' sampler.stats(hs.biom)
148
#'
149
#' @export
150
sampler.stats <- function(object) {
151
    validate.hsstan(object)
152
    validate.samples(object)
153
    sp <- rstan::get_sampler_params(object$stanfit, inc_warmup=FALSE)
154
    accept.stat <- sapply(sp, function(x) mean(x[, "accept_stat__"]))
155
    stepsize <- sapply(sp, function(x) mean(x[, "stepsize__"]))
156
    divergences <- sapply(sp, function(x) sum(x[, "divergent__"]))
157
    treedepth <- sapply(sp, function(x) max(x[, "treedepth__"]))
158
    gradients <- sapply(sp, function(z) sum(z[, "n_leapfrog__"]))
159
    et <- round(rstan::get_elapsed_time(object$stanfit), 2)
160
    res <- cbind(accept.stat, stepsize, divergences, treedepth, gradients, et)
161
    avg <- colMeans(res)
162
    tot <- colSums(res)
163
    round(rbind(res, all=c(avg[1:2], tot[3], max(res[, 4]), tot[5:7])), 4)
164
}
165
166
#' Number of posterior samples
167
#'
168
#' Extracts the number of posterior samples stored in a fitted model.
169
#'
170
#' @param object An object of class `hsstan`.
171
#' @param ... Currently ignored.
172
#'
173
#' @return
174
#' The total number of posterior samples across the chains after discarding
175
#' the warmup iterations.
176
#'
177
#' @examples
178
#' \dontshow{utils::example("hsstan", echo=FALSE)}
179
#' # continued from ?hsstan
180
#' nsamples(hs.biom)
181
#'
182
#' @importFrom rstantools nsamples
183
#' @method nsamples hsstan
184
#' @aliases nsamples
185
#' @export nsamples
186
#' @export
187
nsamples.hsstan <- function(object, ...) {
188
    validate.samples(object)
189
    with(object$stanfit@sim, sum(n_save - warmup2))
190
}