Nothing
# fbst - The Full Bayesian Significance Test and the e-value for testing
# a sharp hypothesis against its alternative
# Copyright (C) 2020 Riko Kelter
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#' Conduct the Full Bayesian Significance Test and return an fbst class object.
#'
#' @method
#' @export
#' @examples
fbst <- function(posteriorDensityDraws, nullHypothesisValue=0, FUN=NULL, par=NULL, dimensionTheta, dimensionNullset, dim=1, gridSize = 1000){
if(dim == 2){
# Check whether a matrix of posterior draws has been submitted
if(class(posteriorDensityDraws)[1]!="matrix"){
stop("Please provide a matrix with two columns for the argument posteriorDensityDraws.")
}
# STEP 1 - Multivariate kernel density estimation
H = diag(c(1, 1)) # bandwith matrix
kde <- ks::kde(x = posteriorDensityDraws, H = H, gridsize = c(gridSize, gridSize)) # grid of size 2000x2000 in R^2 for creating the kernel density
# STEP 2 - Determine supremum of multivariate kernel density estimate over the null hypothesis set
index_nullHypothesisValue = min(which(round(kde$eval.points[[1]],2) %in% c(nullHypothesisValue)))
index_par2MaxTangentialSet = which.max(kde$estimate[index_nullHypothesisValue,])
kde_nullHypothesisValue_par2MaxTangentialSet = kde$estimate[index_nullHypothesisValue,index_par2MaxTangentialSet]
# STEP 3 - Evaluate the multivariate kernel density estimate at the posterior MCMC draws
kde_eval <- ks::kde(x = posteriorDensityDraws, H = H, gridsize = c(gridSize, gridSize),
eval.points = posteriorDensityDraws) # grid of size gridSizexgridSize in R^2 for creating the kernel density
# note that we specify eval.points as the posteriorDensityDraws, this allows later to use the kernel density estimates
# at the values of the posterior draws we obtained
# thus, the call below simply evaluates the kde above at the posteriorDensityDraws values
# STEP 4 - Compute the evidence against the null hypothesis via Monte Carlo integration
# iterate over posterior draws
barEv = 0
for(m in 1:nrow(kde_eval$eval.points)){
if(kde_eval$estimate[m] > kde_nullHypothesisValue_par2MaxTangentialSet){
# barEv = barEv + kde_eval$estimate[m]
barEv = barEv + 1
}
}
barEv = barEv / nrow(kde_eval$eval.points)
# set reference function string
refString = "Flat"
# Compute standardized e-value sev(H_0)
sev_H_0 = 1-pchisq(qchisq(barEv, df=dimensionTheta),df=dimensionTheta-dimensionNullset)
# return fbst object
res = new("fbst", data = list(posteriorDensityDraws=posteriorDensityDraws,
postEffSizeSorted=sort(posteriorDensityDraws),
densZero=kde_nullHypothesisValue_par2MaxTangentialSet,
postDensValues=kde_eval$estimate,
indices=c(index_nullHypothesisValue,index_par2MaxTangentialSet),
nullHypothesisValue=nullHypothesisValue,
referenceFunction=refString,
dimensionTheta=dimensionTheta,
dimensionNullset=dimensionNullset,
eValue=barEv,
pValue=NULL,
sev_H_0 = sev_H_0))
} else {
# Sort posterior draws ascending
postEffSizeSorted = sort(posteriorDensityDraws, decreasing = FALSE)
# Construct density of posterior effect size
postDens <- approxfun(density(postEffSizeSorted), rule = 2) # rule = 2 means: use closest data extreme for NA values produced
# Calculate posterior density at the null set, that is at null hypothesis H_0: delta = 0
if(!is.null(FUN)) {
parNull = c(list(x=nullHypothesisValue),par)
densZero = postDens(nullHypothesisValue)/do.call(FUN, parNull)
}
if(is.null(FUN)){
densZero = postDens(nullHypothesisValue)/1
}
# Calculate posterior density values for all posterior effect size samples
if(!is.null(FUN)){
par[[1]] = rep(par[[1]],length(posteriorDensityDraws))
par[[2]] = rep(par[[2]],length(posteriorDensityDraws))
par = c(list(x=postEffSizeSorted),par)
postDensValues = postDens(postEffSizeSorted)/do.call(FUN, par) # user defined reference function
} else {
postDensValues = postDens(postEffSizeSorted)/1 # flat reference function
}
# Compute p-values for Bayesian evidence value in support of $H_0$
m_0 = postDens(nullHypothesisValue)
M_0 = bayestestR::map_estimate(postEffSizeSorted)$MAP_Estimate
d_0 = abs((m_0-M_0)^2)
# WARNING: The solution given in the 2008 paper is wrong. ev can be approximated as the upper tail of the
# cumulative chi_k^2 distribution function starting from ||m-M||^2
p_value_ev_H_0 = 1-pchisq(d_0, df=dimensionNullset, lower.tail = TRUE)
# Get indices of posterior draws belonging to the tangential set (flat prior)
indices = which(postDensValues > densZero)
# Calculate posterior probability mass of tangential set to H_0: delta = 0 (this is the Bayesian evidence value against H, \bar{ev})
if (length(indices)>0){ # is there at least one posterior density value in the tangential set?
barEv = cubature::cubintegrate(postDens, lower = postEffSizeSorted[min(indices)], upper = postEffSizeSorted[max(indices)])$integral
} else { # tangential set is empty, Lebesgue-integral over it is zero then
barEv = 0
}
if(barEv > 1){ # if integrate function makes some rounding errors set e-value against H_0 to 1, to avoid the quantile functions below to produce errors like NaN
barEv =1
}
if(barEv < 0){
barEv = 0
}
# Compute standardized e-value sev(H_0)
sev_H_0 = 1-pchisq(qchisq(barEv, df=dimensionTheta),df=dimensionTheta-dimensionNullset)
if (is.null(FUN)){
refString = "Flat"
} else {
refString = "User-defined"
}
# return fbst object
res = new("fbst", data = list(posteriorDensityDraws=posteriorDensityDraws,
postEffSizeSorted=postEffSizeSorted,
densZero=densZero,
postDensValues=postDensValues,
indices=indices,
nullHypothesisValue=nullHypothesisValue,
referenceFunction=refString,
dimensionTheta=dimensionTheta,
dimensionNullset=dimensionNullset,
eValue=barEv,
pValue=p_value_ev_H_0,
sev_H_0 = sev_H_0))
}
return(res)
}
#' fbst class
#'
#' Stores the results of a Full Bayesian Significance Test
#'
#' @slot data A named list for storing the user-accessible data of an fbst object
#' posteriorDensityDraws A numeric (vector) of posterior MCMC parameter draws.
#' postEffSizeSorted A numeric (vector) of sorted posterior MCMC parameter draws.
#' densZero A numeric storing the surprise function value at the sharp null hypothesis parameter value.
#' postDensValues A numeric (vector) of posterior density values.
#' indices A numeric (vector) storing indices for deciding which values are located inside the tangential set.
#' nullHypothesisValue A numeric storing the sharp null hypothesis parameter value.
#' referenceFunction A character holding the name of the reference function used.
#' dimensionTheta A numeric holding the dimension of the parameter space.
#' dimensionNullset A numeric holding the dimension of the null set.
#' eValue A numeric holding the Bayesian evidence against the sharp null hypothesis, the e-value.
#' pValue A numeric holding the p-value associated with the Bayesian e-value in favour of the sharp null hypothesis.
#' sev_H_0 A numeric holding the standardized e-value as a replacement of the frequentist p-value
#' @name fbst-class
#' @rdname fbst-class
#' @export
setClass("fbst", representation(data="list"),
prototype = NULL,
validity = function(object) return(TRUE)
)
#' Conduct the Full Bayesian Evidence Test and return an fbet class object.
#'
#' @method
#' @export
#' @examples
fbet <- function(posteriorDensityDraws=NULL, interval, nu=1, FUN=NULL, par=NULL, posterior=NULL, par_posterior=NULL){
if(is.null(posterior) && is.null(posteriorDensityDraws)){
stop("You must either provide the posteriorDensityDraws argument or the posterior argument!")
}
if((!is.null(posterior)) && (!is.null(posteriorDensityDraws))){
stop("You must either provide the posteriorDensityDraws argument or the posterior argument, not both!")
}
if(is.null(posterior)){ # posterior draws provided as input
# Sort posterior draws ascending
postEffSizeSorted = sort(posteriorDensityDraws, decreasing = FALSE)
# Construct density of posterior effect size
postDens <- approxfun(density(postEffSizeSorted), rule = 2) # rule = 2 means: use closest data extreme for NA values produced
# Calculate surprise function values for all posterior effect size samples
if(!is.null(FUN)){ # reference function provided
for(i in 1:length(par)){
par[[i]] = rep(par[[i]],length(posteriorDensityDraws))
}
par = c(list(x=postEffSizeSorted),par)
postDensValues = postDens(postEffSizeSorted)/do.call(FUN, par) # user defined reference function
} else { # no reference function provided, then use flat improper prior as reference function
postDensValues = postDens(postEffSizeSorted)/1 # flat reference function
}
if(nu==0 && is.null(FUN)){ # if flat ref function and nu == 0 the posterior is the surprise function
evidenceInterval = c(-Inf,Inf)
bayesianEvidenceValueIntervalNullHyp = cubintegrate(postDens, lower = interval[1], upper = interval[2])$integral
bayesianEvidenceValueAlternative = 1-bayesianEvidenceValueIntervalNullHyp
indices = "All"
# rounding errors
if(bayesianEvidenceValueIntervalNullHyp > 1){
bayesianEvidenceValueIntervalNullHyp = 1
}
if(bayesianEvidenceValueAlternative > 1){
bayesianEvidenceValueAlternative = 1
}
} else {
# Compute indices of posterior parameter draws which belong to the expanded tangential set \tilde{T}(\nu)
indices = which(postDensValues >= nu)
# Get smallest and largest values as the boundaries of the evidence interval
if(length(indices)>0){
evidenceInterval = c(postEffSizeSorted[min(indices)],postEffSizeSorted[max(indices)])
} else { # expanded tangential set is empty
evidenceInterval = "Empty set"
}
if(!inherits(evidenceInterval, "character")){ # evidence interval is not the empty set? then compute Bayesian evidence values
# Calculate the Bayesian evidence value for the interval null hypothesis
if (length(indices)>0 && max(evidenceInterval[1],interval[1])<min(evidenceInterval[2],interval[2])){ # is there at least one posterior density value in the expanded tangential set?
# integrate over intersection between the evidence interval and rope, indices [1] and [2] denote the lower and upper bounds of the evidence interval and rope
bayesianEvidenceValueIntervalNullHyp = cubintegrate(postDens, lower = max(evidenceInterval[1],interval[1]), upper = min(evidenceInterval[2],interval[2]))$integral
} else { # expanded tangential set is empty, Lebesgue-integral over an empty set is zero then
bayesianEvidenceValueIntervalNullHyp = 0
}
# Calculate the Bayesian evidence value for the alternative hypothesis
bayesianEvidenceValueAlternative = 0
if(evidenceInterval[1]<interval[1] && evidenceInterval[2]<interval[1]){
# intersection of Bayesian evidence interval and alternative hypothesis (left part)
from.z <- evidenceInterval[1]
to.z <- evidenceInterval[2]
bayesianEvidenceValueAlternative = bayesianEvidenceValueAlternative + cubintegrate(postDens, lower = from.z, upper = to.z)$integral
}
if(evidenceInterval[1]>interval[2] && evidenceInterval[2]>interval[2]){
# intersection of Bayesian evidence interval and alternative hypothesis (right part)
from.z <- evidenceInterval[1]
to.z <- evidenceInterval[2]
bayesianEvidenceValueAlternative = bayesianEvidenceValueAlternative + cubintegrate(postDens, lower = from.z, upper = to.z)$integral
}
if(evidenceInterval[1]<interval[1] && evidenceInterval[2]>interval[1]){
# intersection of Bayesian evidence interval and alternative hypothesis (right part)
from.z <- evidenceInterval[1]
to.z <- interval[1]
bayesianEvidenceValueAlternative = bayesianEvidenceValueAlternative + cubintegrate(postDens, lower = from.z, upper = to.z)$integral
}
if(evidenceInterval[1]<interval[2] && evidenceInterval[2]>interval[2]){
# intersection of Bayesian evidence interval and alternative hypothesis (right part)
from.z <- interval[2]
to.z <- evidenceInterval[2]
bayesianEvidenceValueAlternative = bayesianEvidenceValueAlternative + cubintegrate(postDens, lower = from.z, upper = to.z)$integral
}
# rounding errors
if(bayesianEvidenceValueIntervalNullHyp > 1){
bayesianEvidenceValueIntervalNullHyp = 1
}
if(bayesianEvidenceValueAlternative > 1){
bayesianEvidenceValueAlternative = 1
}
} else { # if evidence interval is empty, set Bayesian evidence values accordingly
bayesianEvidenceValueIntervalNullHyp = 0
bayesianEvidenceValueAlternative = 0
}
}
if (is.null(FUN)){
refString = "Flat"
} else {
refString = "User-defined"
}
res = new("fbet", data=list(
posteriorDensityDraws = posteriorDensityDraws,
posteriorDensityDrawsSorted = postEffSizeSorted,
postDensValues = postDensValues,
indices = indices,
interval = interval,
referenceFunction = refString,
nu = nu,
evidenceInterval = evidenceInterval,
eValueH0 = bayesianEvidenceValueIntervalNullHyp,
eValueH1 = bayesianEvidenceValueAlternative))
}
if(is.null(posteriorDensityDraws)){ # calculation of FBET based on analytic posterior
integrand <- function(x){
par_posterior = c(x=x,par_posterior)
numerator = do.call(posterior,par_posterior)
par = c(x=x,par)
denominator = do.call(FUN,par)
if(numerator/denominator >= nu){
res = numerator
}
else {
res = 0
}
res
}
# integrate over null Hypothesis Interval
EvH0 = cubintegrate(integrand,lower=interval[1],upper=interval[2])
#cat("Evidence for the hypothesis specified inside interval argument:\n")
res = EvH0$integral
}
res
}
#' fbet class
#'
#' Stores the results of a Full Bayesian Evidence Test
#'
#' @slot data A named list for storing the user-accessible data of an fbet object
#' posteriorDensityDraws A numeric (vector) of posterior MCMC parameter draws.
#' posteriorDensityDrawsSorted A numeric (vector) of sorted posterior MCMC parameter draws.
#' postDensValues A numeric (vector) of posterior density values.
#' indices A numeric (vector) storing indices for deciding which values are located inside the tangential set.
#' interval A numeric (vector) storing the boundaries of the interval null hypothesis (ROPE).
#' referenceFunction A character holding the name of the reference function used.
#' nu Evidence-threshold used for computation of the evidence interval
#' evidenceInterval A numeric (vector) storing the lower and upper boundaries of the resulting Bayesian evidence interval
#' eValueH0 Bayesian evidence value for the interval null hypothesis
#' eValueH1 Bayesian evidence value for the alternative hypothesis
#' @name fbet-class
#' @rdname fbet-class
#' @export
setClass("fbet", representation(data="list"),
prototype = NULL,
validity = function(object) return(TRUE)
)
#' plot object of class fbst
#' @usage \\method{plot}{fbst}(x, ...)
#' @export
plot.fbst <- function(x, ..., leftBoundary= -100, rightBoundary = 100, type = "contour", parNames = NULL, xlimleft = NULL, xlimright = NULL, xlabString = "Parameter", ylabString = NULL){
if(inherits(x$posteriorDensityDraws, "numeric")){
postDens <- approxfun(x=x$postEffSizeSorted,y=x$postDensValues, rule = 2)
# prior-posterior plot
if(is.null(xlimleft)){
xlimleft = min(x$postEffSizeSorted)
}
if(is.null(xlimright)){
xlimright = max(x$postEffSizeSorted)
}
if(is.null(ylabString)){
ylabString = "density"
}
plot(x$postEffSizeSorted,x$postDensValues,ty="l",lty=1,xlim=c(xlimleft,xlimright),
main="",ylab=ylabString,xlab=xlabString)
# tangential area
from.z <- x$postEffSizeSorted[min(x$indices)]
to.z <- x$postEffSizeSorted[max(x$indices)]
S.x <- c(from.z, seq(from.z, to.z, by = 0.0001), to.z)
S.y <- c(0, postDens(seq(from.z, to.z, 0.0001)), 0)
polygon(S.x,S.y, col = rgb(red = 0, green = 0.8, blue = 1, alpha = 1))
# left tail (null) area
from.z <- leftBoundary
to.z <- x$postEffSizeSorted[min(x$indices)]
# plot(postEffSizeSorted,postDensValues,ty="l", main = "", xlab = expression(paste("p(", delta, "| x)")), ylab = "Density")
S.x <- c(from.z, seq(from.z, to.z, by = 0.0001), to.z)
S.y <- c(0, postDens(seq(from.z, to.z, 0.0001)), 0)
polygon(S.x,S.y, col = rgb(red = 1, green = 0, blue = 0, alpha = 1))
# right tail (null) area
from.z <- x$postEffSizeSorted[max(x$indices)]
to.z <- rightBoundary
S.x <- c(from.z, seq(from.z, to.z, by = 0.0001), to.z)
S.y <- c(0, postDens(seq(from.z, to.z, 0.0001)), 0)
polygon(S.x,S.y, col = rgb(red = 1, green = 0, blue = 0, alpha = 1))
# null density value and separating line for tangential set
points(x=0,y=x$densZero,col="blue",pch=19)
abline(h=x$densZero,lty=2,lwd=1,col="blue")
}
if(inherits(x$posteriorDensityDraws, "matrix")){
# Contour plot
if(type == "contour"){
H = diag(c(1, 1))
kde <- ks::kde(x = x$posteriorDensityDraws, H = H, gridsize = c(1000, 1000))
# contour plot
graphics::image(kde$eval.points[[1]], kde$eval.points[[2]], kde$estimate,
col = viridis::viridis(20), xlab = parNames[1], ylab = parNames[2])
points(kde$x)
index_nullHypothesisValue = min(which(round(kde$eval.points[[1]],2) %in% c(x$nullHypothesisValue)))
index_par2MaxTangentialSet = which.max(kde$estimate[index_nullHypothesisValue,])
kde_nullHypothesisValue_par2MaxTangentialSet = kde$estimate[index_nullHypothesisValue,index_par2MaxTangentialSet]
points(kde$eval.points[[1]][index_nullHypothesisValue],kde$eval.points[[2]][index_par2MaxTangentialSet],col="magenta",pch=18)
}
if(type == "persp"){
H = diag(c(1, 1))
kde <- ks::kde(x = x$posteriorDensityDraws, H = H, gridsize = c(250, 250))
plot(kde, display = "persp", col.fun = viridis::viridis, xlab = parNames[1], ylab = parNames[2])
}
}
}
#' plot object of class fbet
#' @usage \\method{plot}{fbet}(x, ...)
#' @export
plot.fbet <- function(x, ..., leftBoundary= -100, rightBoundary = 100, type = "posterior", legendposition = "topleft", main = ""){
if(type=="surprise"){
postDens <- approxfun(x=x$posteriorDensityDrawsSorted,y=x$postDensValues, rule = 2)
# prior-posterior plot
plot(x$posteriorDensityDrawsSorted,x$postDensValues,ty="l",lty=1,xlim=c(min(x$posteriorDensityDrawsSorted),max(x$posteriorDensityDrawsSorted)),
main=main,ylab="density",xlab="Parameter")
}
if(type=="posterior"){
postDens <- approxfun(density(x$posteriorDensityDraws))
plot(density(x$posteriorDensityDraws),ty="l",lty=1,xlim=c(min(x$posteriorDensityDrawsSorted),max(x$posteriorDensityDrawsSorted)),
main=main,ylab="density",xlab="Parameter")
}
# Visualize interval hypothesis
abline(v=x$interval[1],lty=2,lwd=1,col="blue")
abline(v=x$interval[2],lty=2,lwd=1,col="blue")
# Visualize Bayesian evidence interval
abline(v=x$evidenceInterval[1],lty=1,lwd=1,col="blue")
abline(v=x$evidenceInterval[2],lty=1,lwd=1,col="blue")
# intersection of Bayesian evidence interval and interval null hypothesis
if (max(x$evidenceInterval[1],x$interval[1])<min(x$evidenceInterval[2],x$interval[2])){
# intersection between the evidence interval and rope, indices [1] and [2] denote the lower and upper bounds of the evidence interval and rope
from.z <- max(x$evidenceInterval[1],x$interval[1])
to.z <- min(x$evidenceInterval[2],x$interval[2])
S.x <- c(from.z, seq(from.z, to.z, by = 0.0001), to.z)
S.y <- c(0, postDens(seq(from.z, to.z, 0.0001)), 0)
polygon(S.x,S.y, col = rgb(red = 0, green = 0.8, blue = 1, alpha = 1))
}
# intersection of Bayesian evidence interval and alternative hypothesis
if(x$evidenceInterval[1]<x$interval[1] && x$evidenceInterval[2]<x$interval[1]){
# intersection of Bayesian evidence interval and alternative hypothesis (left part)
from.z <- min(x$evidenceInterval[1],x$interval[1])
to.z <- min(x$evidenceInterval[2],x$interval[1])
if(from.z < to.z){
S.x <- c(from.z, seq(from.z, to.z, by = 0.0001), to.z)
S.y <- c(0, postDens(seq(from.z, to.z, 0.0001)), 0)
polygon(S.x,S.y, col = rgb(red = 1, green = 0, blue = 0, alpha = 1))
}
}
if(is.infinite(x$evidenceInterval[1]) && is.infinite(x$evidenceInterval[2])){
S.x <- c(-1000, seq(-1000, x$interval[1], by = 0.001), x$interval[1])
S.y <- c(0, postDens(seq(-1000, x$interval[1], 0.001)), 0)
polygon(S.x,S.y, col = rgb(red = 1, green = 0, blue = 0, alpha = 1))
}
if(x$evidenceInterval[1]>x$interval[2] && x$evidenceInterval[2]>x$interval[2]){
# intersection of Bayesian evidence interval and alternative hypothesis (right part)
from.z <- x$evidenceInterval[1]
to.z <- x$evidenceInterval[2]
if(from.z < to.z){
S.x <- c(from.z, seq(from.z, to.z, by = 0.0001), to.z)
S.y <- c(0, postDens(seq(from.z, to.z, 0.0001)), 0)
polygon(S.x,S.y, col = rgb(red = 1, green = 0, blue = 0, alpha = 1))
}
}
if(x$evidenceInterval[1]<x$interval[1] && x$evidenceInterval[2]>x$interval[1]){
# intersection of Bayesian evidence interval and alternative hypothesis (right part)
from.z <- x$evidenceInterval[1]
to.z <- x$interval[1]
if(is.infinite(from.z)){
from.z = -100
}
if(from.z < to.z){
S.x <- c(from.z, seq(from.z, to.z, by = 0.0001), to.z)
S.y <- c(0, postDens(seq(from.z, to.z, 0.0001)), 0)
polygon(S.x,S.y, col = rgb(red = 1, green = 0, blue = 0, alpha = 1))
}
}
if(x$evidenceInterval[1]<x$interval[2] && x$evidenceInterval[2]>x$interval[2]){
# intersection of Bayesian evidence interval and alternative hypothesis (right part)
from.z <- x$interval[2]
to.z <- x$evidenceInterval[2]
if(is.infinite(to.z)){
to.z = 100
}
if(from.z < to.z){
S.x <- c(from.z, seq(from.z, to.z, by = 0.0001), to.z)
S.y <- c(0, postDens(seq(from.z, to.z, 0.0001)), 0)
polygon(S.x,S.y, col = rgb(red = 1, green = 0, blue = 0, alpha = 1))
}
}
if(type=="surprise"){
# separating line for evidence-threshold nu used for the Bayesian evidence interval
abline(h=x$nu,lty=2,lwd=1,col="black")
graphics::legend(legendposition, legend=c("information function", "Null hypothesis", "Evidence Interval", "Evidence threshold"),
col=c("black", "blue", "blue", "black"), lty=c(1,2,1,2), cex=1)
}
if(type=="posterior"){
graphics::legend(legendposition, legend=c("posterior density", "Null hypothesis", "Evidence Interval"),
col=c("black", "blue", "blue"), lty=c(1,2,1), cex=1)
}
}
#' Print summary of an object of class fbst
#' @usage \\method{summary}{fbst}(object, ...)
#' @export
summary.fbst <- function(object, ...){
cat("Full Bayesian Significance Test for testing a sharp hypothesis against its alternative:\n")
cat("Reference function:", object$referenceFunction, "\n")
cat("Hypothesis H_0:Parameter=", object$nullHypothesisValue, "against its alternative H_1\n")
cat("Bayesian e-value against H_0:", object$eValue, "\n")
cat("Standardized e-value:", object$sev_H_0, "\n")
}
#' Print summary of an object of class fbet
#' @usage \\method{summary}{fbet}(object, ...)
#' @export
summary.fbet <- function(object, ...){
cat("Full Bayesian Evidence Test:\n")
cat("Reference function:", object$referenceFunction, "\n")
cat("Testing Hypothesis H_0:=[",object$interval[1], ",",object$interval[2],"]\n")
cat("Bayesian e-value in favour of H_0:", object$eValueH0, "\n")
cat("Bayesian e-value against H_0:", object$eValueH1, "\n")
}
#' Show method for an object of class fbst
#' @usage \\method{show}{fbst}(object)
#' @export
show.fbst <- function(object){
cat("FBST for testing H_0:Parameter =", object$nullHypothesisValue, "against its alternative H_1\n")
cat("Reference function:", object$referenceFunction, "\n")
cat("Bayesian e-value against H_0:", object$eValue, "\n")
}
#' Show method for an object of class fbet
#' @usage \\method{show}{fbet}(object)
#' @export
show.fbet <- function(object){
cat("FBET for testing H_0:Parameter in", object$interval, "against its alternative H_1\n")
cat("Reference function:", object$referenceFunction, "\n")
cat("Bayesian e-value in favour of H_0:", object$eValueH0, "\n")
}
#' Access results stored in the data slot of an object of class fbst
#' @usage \\method{$}{fbst}(object, ...)
#' @export
setMethod('$', signature="fbst",
definition=function(x, name) {
return_value = x@data[[name]]
names(return_value) = name
return(return_value)}
)
#' Access results stored in the data slot of an object of class fbet
#' @usage \\method{$}{fbet}(object, ...)
#' @export
setMethod('$', signature="fbet",
definition=function(x, name) {
return_value = x@data[[name]]
names(return_value) = name
return(return_value)}
)
#' Get names of the data slot of an object of class fbst
#' @usage \\method{names}{fbst}(object, ...)
#' @export
names.fbst <- function(x){
names(x@data)
}
#' Get names of the data slot of an object of class fbet
#' @usage \\method{names}{fbet}(object, ...)
#' @export
names.fbet <- function(x){
names(x@data)
}
#' Compute the Bayesian discrepancy measure (BDM)
#' @method
#' @export
#' @examples
bdm <- function(posteriorDensityDraws, nullHypothesisValue=0){
# Step 1: Compute median of posterior draws
m=stats::median(posteriorDensityDraws)
# Step 2: Define discrepancy interval
if(m<nullHypothesisValue){
I_H=c(m,nullHypothesisValue)
}
if(m==nullHypothesisValue){
I_H=m
}
if(m>nullHypothesisValue){
I_H=c(nullHypothesisValue,m)
}
# Step 3: Build kernel density estimate of posterior
# Sort posterior draws ascending
postEffSizeSorted = sort(posteriorDensityDraws, decreasing = FALSE)
# Construct density of posterior effect size
postDens <- approxfun(density(postEffSizeSorted), rule = 2) # rule = 2 means: use closest data extreme for NA values produced
# Step 4: Integrate over discrepancy interval and double the value, which is the BDM
bdm = 2 * cubature::cubintegrate(postDens, lower = I_H[1], upper = I_H[2])$integral
# Step 5: return BDM
return(bdm)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.