Nothing
# constructor
BFBayesFactor <- function(numerator, denominator, bayesFactor, data){
names(numerator) = rownames(bayesFactor)
new("BFBayesFactor", numerator = numerator,
denominator = denominator,
bayesFactor = bayesFactor,
data = data,
version = BFInfo(FALSE))
}
setValidity("BFBayesFactor", function(object){
if( length(object@numerator) != nrow(object@bayesFactor)) return("Number of numerator models does not equal number of Bayes factors.")
numeratorsAreBFs = sapply(object@numerator,function(el) inherits(el,"BFmodel"))
if( any(!numeratorsAreBFs)) return("Some numerators are not BFmodel objects.")
# check numerators all have same data types as denominator
dataTypeDenom = object@denominator@dataTypes
dataTypesEqual = unlist(lapply(object@numerator,
function(model, compType)
model@dataTypes %com% compType,
compType=dataTypeDenom))
if( any(!dataTypesEqual)) return("Data types are not equal across models.")
typeDenom = object@denominator@type
typesEqual = unlist(lapply(object@numerator,
function(model, compType)
identical(model@type, compType),
compType=typeDenom))
if( any(!typesEqual)) return("Model types are not equal across models.")
classDenom = class(object@denominator)
typesEqual = unlist(lapply(object@numerator,
function(model, compType)
identical(class(model), compType),
compType=classDenom))
if( any(!typesEqual)) return("Model classes are not equal across models.")
# Check to see that Bayes factor data frame has required columns
if( !all(colnames(object@bayesFactor) %in% c("bf", "error", "time", "code")) )
return("Object does not have required columns (bf, error, time, code).")
return(TRUE)
})
#' @rdname recompute-methods
#' @aliases recompute,BFBayesFactor-method
setMethod("recompute", "BFBayesFactor", function(x, progress = getOption('BFprogress', interactive()), multicore = FALSE, callback = function(...) as.integer(0), ...){
modelList = c(x@numerator,x@denominator)
if(multicore){
callback = function(...) as.integer(0)
message("Note: Progress bars and callbacks are suppressed when running multicore.")
if( !suppressMessages( requireNamespace("doMC", quietly = TRUE) ) ){
stop("Required package (doMC) missing for multicore functionality.")
}
doMC::registerDoMC()
if(foreach::getDoParWorkers()==1){
warning("Multicore specified, but only using 1 core. Set options(cores) to something >1.")
}
bfs = foreach::"%dopar%"(
foreach::foreach(gIndex=modelList, .options.multicore=mcoptions),
compare(numerator = gIndex, data = x@data, ...)
)
}else{ # No multicore
checkCallback(callback,as.integer(0))
bfs = NULL
myCallback <- function(prgs){
frac <- (i - 1 + prgs/1000)/length(modelList)
ret <- callback(frac*1000)
return(as.integer(ret))
}
if(progress){
pb = txtProgressBar(min = 0, max = length(modelList), style = 3)
}else{
pb = NULL
}
for(i in 1:length(modelList)){
oneModel <- compare(numerator = modelList[[i]], data = x@data, progress=FALSE, callback=myCallback, ...)
if(inherits(pb,"txtProgressBar")) setTxtProgressBar(pb, i)
bfs = c(bfs,oneModel)
}
if(inherits(pb,"txtProgressBar")) close(pb)
checkCallback(callback,as.integer(1000))
}
joined = do.call("c", bfs)
numerators = joined[ 1:(length(joined)-1) ]
denominator = joined[ length(joined) ]
return(numerators / denominator)
})
#' @rdname BFBayesFactor-class
#' @name /,numeric,BFBayesFactor-method
#' @param e1 Numerator of the ratio
#' @param e2 Denominator of the ratio
setMethod('/', signature("numeric", "BFBayesFactor"), function(e1, e2){
if( (e1 == 1) & (length(e2)==1) ){
numer = e2@numerator[[1]]
denom = list(e2@denominator)
bf_df = e2@bayesFactor
rownames(bf_df) = denom[[1]]@shortName
bf_df$bf = -bf_df$bf
bfobj = BFBayesFactor(numerator=denom, denominator=numer,
bayesFactor=bf_df, data=e2@data)
return(bfobj)
}else if( e1 != 1 ){
stop("Dividend must be 1 (to take reciprocal).")
}else if( length(e2)>1 ){
allNum = as(e2,"list")
BFlist = BFBayesFactorList(lapply(allNum, function(num) 1 / num))
}
}
)
#' @rdname BFBayesFactor-class
#' @name /,BFBayesFactor,BFBayesFactor-method
setMethod('/', signature("BFBayesFactor", "BFBayesFactor"), function(e1, e2){
if( !(e1@denominator %same% e2@denominator) ) stop("Bayes factors have different denominator models; they cannot be compared.")
if( !identical(e1@data, e2@data) ) stop("Bayes factors were computed using different data; they cannot be compared.")
if( (length(e2)==1) ){
errorEst = sqrt(e1@bayesFactor$error^2 + e2@bayesFactor$error^2)
bfs = data.frame(bf=e1@bayesFactor$bf - e2@bayesFactor$bf,
error = errorEst,
time = date(),
code = randomString(length(e1)))
rownames(bfs) = rownames(e1@bayesFactor)
# when bayes factors were computed at the same time or for the same model,
# they must be exactly equal (no error)
sameModel <- sapply(e1@numerator, function(num, den) num %same% den, den = e2@numerator[[1]])
sameCode <- as.character(e1@bayesFactor$code) == as.character(e2@bayesFactor$code)
bfs[ sameModel | sameCode, "error" ] = 0
bfs[ sameModel | sameCode, "bf" ] = 0
newbf = BFBayesFactor(numerator=e1@numerator,
denominator=e2@numerator[[1]],
bayesFactor=bfs,
data = e1@data)
return(newbf)
}else{
allDenom = as(e2,"list")
BFlist = BFBayesFactorList(lapply(allDenom, function(denom, num) num / denom, num = e1))
return(BFlist)
}
}
)
setMethod('show', "BFBayesFactor", function(object){
cat("Bayes factor analysis\n--------------\n")
bfs = extractBF(object, logbf=TRUE)
bfs$bf = sapply(bfs$bf, expString)
indices = paste("[",1:nrow(bfs),"]",sep="")
# pad model names
nms = paste(indices,rownames(bfs),sep=" ")
maxwidth = max(nchar(nms))
nms = str_pad(nms,maxwidth,side="right",pad=" ")
# pad Bayes factors
maxwidth = max(nchar(bfs$bf))
bfString = str_pad(bfs$bf,maxwidth,side="right",pad=" ")
for(i in 1:nrow(bfs)){
cat(nms[i]," : ",bfString[i]," \u00B1",round(bfs$error[i]*100,2),"%\n",sep="")
}
cat("\nAgainst denominator:\n")
cat(" ",object@denominator@longName,"\n")
cat("---\nBayes factor type: ",class(object@denominator)[1],", ",object@denominator@type,"\n\n",sep="")
})
setMethod('summary', "BFBayesFactor", function(object){
show(object)
})
#' @rdname BFBayesFactor-class
#' @name [,BFBayesFactor,index,missing,missing-method
#' @param x BFBayesFactor object
#' @param i indices indicating elements to extract
#' @param j unused for BFBayesFactor objects
#' @param drop unused
#' @param ... further arguments passed to related methods
setMethod("[", signature(x = "BFBayesFactor", i = "index", j = "missing",
drop = "missing"),
function (x, i, j, ..., drop) {
if((na <- nargs()) == 2){
newbf = x
x@numerator = x@numerator[i, drop=FALSE]
x@bayesFactor = x@bayesFactor[i, ,drop=FALSE]
}else stop("invalid nargs()= ",na)
return(x)
})
#' @rdname extractBF-methods
#' @aliases extractBF,BFBayesFactor-method
setMethod("extractBF", "BFBayesFactor", function(x, logbf = FALSE, onlybf = FALSE){
x = x@bayesFactor
if(!logbf) x$bf = exp(x$bf)
if(onlybf) x = x$bf
return(x)
})
#' @rdname BFBayesFactor-class
#' @name t,BFBayesFactor-method
setMethod('t', "BFBayesFactor", function(x){
return(t.BFBayesFactor(x))
})
setAs("BFBayesFactor", "data.frame",
function( from, to ){
as.data.frame.BFBayesFactor(from)
})
setAs("BFBayesFactor" , "list",
function ( from , to ){
vec = vector(mode = "list", length = length(from) )
for(i in 1:length(from))
vec[[i]] = from[i]
return(vec)
})
setAs("BFBayesFactor", "vector",
function( from, to ){
as.vector.BFBayesFactor(from)
})
#' @rdname BFBayesFactor-class
#' @name which.max,BFBayesFactor-method
setMethod("which.max", "BFBayesFactor", function(x)
which.max.BFBayesFactor(x) )
#' @rdname BFBayesFactor-class
#' @name which.min,BFBayesFactor-method
setMethod("which.min", "BFBayesFactor", function(x)
which.min.BFBayesFactor(x) )
#' @rdname BFBayesFactor-class
#' @name is.na,BFBayesFactor-method
setMethod("is.na", "BFBayesFactor", function(x)
is.na.BFBayesFactor(x) )
#' @rdname BFBayesFactor-class
#' @name *,BFBayesFactor,BFodds-method
setMethod('*', signature("BFBayesFactor", "BFodds"), function(e1, e2){
return(e2 * e1)
}
)
######
# S3
######
##' This function coerces objects to the BFBayesFactor class
##'
##' Function to coerce objects to the BFBayesFactor class
##'
##' Currently, this function will only work with objects of class
##' \code{BFBayesFactorTop}, which are output from the functions \code{anovaBF}
##' and \code{regressionBF} when the \code{whichModels} argument is set to
##' \code{'top'}
##' @title Function to coerce objects to the BFBayesFactor class
##' @param object an object of appropriate class (for now, BFBayesFactorTop)
##' @return An object of class \code{BFBayesFactor}
##' @author Richard D. Morey (\email{richarddmorey@@gmail.com})
##' @export
##' @keywords misc
##' @seealso \code{\link{regressionBF}}, \code{anovaBF} whose output is
##' appropriate for use with this function when \code{whichModels='top'}
as.BFBayesFactor <- function(object)
UseMethod("as.BFBayesFactor")
is.na.BFBayesFactor <- function(x){
return(is.na(x@bayesFactor$bf))
}
names.BFBayesFactor <- function(x) {
num <- sapply(x@numerator, function(el) el@shortName)
den <- x@denominator@shortName
return(list(numerator=num,denominator=den))
}
length.BFBayesFactor <- function(x)
nrow(x@bayesFactor)
# See https://www-stat.stanford.edu/~jmc4/classInheritance.pdf
sort.BFBayesFactor <- function(x, decreasing = FALSE, ...){
ord = order(x@bayesFactor$bf, decreasing = decreasing)
return(x[ord])
}
max.BFBayesFactor <- function(..., na.rm=FALSE){
joinedbf = do.call('c',list(...))
el <- head(joinedbf, n=1)
return(el)
}
min.BFBayesFactor <- function(..., na.rm=FALSE){
joinedbf = do.call('c',list(...))
el <- tail(joinedbf, n=1)
return(el)
}
which.max.BFBayesFactor <- function(x){
index = which.max(x@bayesFactor$bf)
names(index) = rownames(x@bayesFactor)[index]
return(index)
}
which.min.BFBayesFactor <- function(x){
index = which.min(x@bayesFactor$bf)
names(index) = rownames(x@bayesFactor)[index]
return(index)
}
t.BFBayesFactor <- function(x){
1/x
}
head.BFBayesFactor <- function(x, n=6L, ...){
n = ifelse(n>length(x),length(x),n)
x = sort(x, decreasing=TRUE)
return(x[1:n])
}
tail.BFBayesFactor <- function(x, n=6L, ...){
n = ifelse(n>length(x),length(x),n)
x = sort(x)
return(x[n:1])}
as.data.frame.BFBayesFactor <- function(x, row.names = NULL, optional=FALSE,...){
df = x@bayesFactor
df$bf = exp(df$bf)
return(df)
}
as.vector.BFBayesFactor <- function(x, mode = "any"){
if( !(mode %in% c("any", "numeric"))) stop("Cannot coerce to mode ", mode)
v = exp(x@bayesFactor$bf)
names(v) = rownames(x@bayesFactor)
return(v)
}
c.BFBayesFactor <-
function(..., recursive = FALSE)
{
z = list(...)
if(length(z)==1) return(z[[1]])
correctClass = unlist(lapply(z, function(object) inherits(object,"BFBayesFactor")))
if(any(!correctClass)) stop("Cannot concatenate Bayes factor with non-Bayes factor.")
dataAndDenoms = lapply(z, function(object){list(den = object@denominator, dat = object@data)})
sameInfo = unlist(lapply(dataAndDenoms[-1],
function(el, cmp){
sameType = el$dat %com% cmp$dat
sameType = ifelse(length(sameType)>0,sameType,TRUE)
(el$den %same% cmp$den) & sameType
},
cmp=dataAndDenoms[[1]]))
if(any(!sameInfo)) stop("Cannot concatenate Bayes factors with different denominator models or data.")
numerators = unlist(lapply(z, function(object){object@numerator}),recursive=FALSE, use.names=FALSE)
bfs = lapply(z, function(object){object@bayesFactor})
df_rownames = unlist(lapply(z, function(object){rownames(object@bayesFactor)}))
df_rownames = make.unique(df_rownames, sep=" #")
bfs = do.call("rbind",bfs)
rownames(bfs) = df_rownames
bf = BFBayesFactor(numerator=numerators,
denominator=z[[1]]@denominator, bayesFactor=bfs,
data = z[[1]]@data)
}
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.