File: generalTestBF.R

package info (click to toggle)
r-cran-bayesfactor 0.9.12-4.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,492 kB
  • sloc: cpp: 1,555; sh: 16; makefile: 7
file content (145 lines) | stat: -rw-r--r-- 7,105 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
##' This function computes Bayes factors corresponding to restrictions on a full model.
##'
##' See the help for \code{\link{anovaBF}} and \code{\link{anovaBF}} or details.
##'
##' Models, priors, and methods of computation are provided in Rouder et al.
##' (2012) and Liang et al (2008).
##'
##' @title Function to compute Bayes factors for general designs
##' @param formula a formula containing the full model for the analysis
##'   (see Examples)
##' @param data a data frame containing data for all factors in the formula
##' @param whichRandom a character vector specifying which factors are random
##' @param whichModels which set of models to compare; see Details
##' @param neverExclude a character vector containing a regular expression (see
##' help for \link{regex} for details) that indicates which terms to always keep
##' in the analysis
##' @param iterations How many Monte Carlo simulations to generate, if relevant
##' @param progress if \code{TRUE}, show progress with a text progress bar
##' @param rscaleFixed prior scale for standardized, reduced fixed effects. A
##'   number of preset values can be given as strings; see Details.
##' @param rscaleRandom prior scale for standardized random effects
##' @param rscaleCont prior scale for standardized slopes
##' @param rscaleEffects A named vector of prior settings for individual factors,
##'   overriding rscaleFixed and rscaleRandom. Values are scales, names are factor names.
##' @param multicore if \code{TRUE} use multiple cores through the \code{doMC}
##'   package. Unavailable on Windows.
##' @param method approximation method, if needed. See \code{\link{nWayAOV}} for
##'   details.
##' @param noSample if \code{TRUE}, do not sample, instead returning NA.
##' @return An object of class \code{BFBayesFactor}, containing the computed
##'   model comparisons
##' @param callback callback function for third-party interfaces
##' @author Richard D. Morey (\email{richarddmorey@@gmail.com})
##' @export
##' @references
##'   Rouder, J. N., Morey, R. D., Speckman, P. L., Province, J. M., (2012)
##'   Default Bayes Factors for ANOVA Designs. Journal of Mathematical
##'   Psychology.  56.  p. 356-374.
##'
##'   Liang, F. and Paulo, R. and Molina, G. and Clyde, M. A. and
##'   Berger, J. O. (2008). Mixtures of g-priors for Bayesian Variable
##'   Selection. Journal of the American Statistical Association, 103, pp.
##'   410-423
##'
##' @note The function \code{generalTestBF} can compute Bayes factors for all
##'   restrictions of a full model against the null
##'   hypothesis that all effects are 0. The total number of tests
##'   computed -- if all tests are requested -- will be \eqn{2^K-1}{2^K - 1}
##'   for \eqn{K} factors or covariates.
##'   This number increases very quickly with the number of tested predictors. An option is included to
##'   prevent testing too many models: \code{options('BFMaxModels')}, which defaults to 50,000, is
##'   the maximum number of models that will be analyzed at once. This can
##'   be increased by increased using \code{\link{options}}.
##'
##'   It is possible to reduce the number of models tested by only testing the
##'   most complex model and every restriction that can be formed by removing
##'   one factor or interaction using the \code{whichModels} argument. See the
##'   help for \code{\link{anovaBF}} for details.
##'
##' @examples
##' ## Puzzles example: see ?puzzles and ?anovaBF
##' data(puzzles)
##' ## neverExclude argument makes sure that participant factor ID
##' ## is in all models
##' result = generalTestBF(RT ~ shape*color + ID, data = puzzles, whichRandom = "ID",
##' neverExclude="ID", progress=FALSE)
##' result
##'
##' @keywords htest
##' @seealso \code{\link{lmBF}}, for testing specific models, and
##'   \code{\link{regressionBF}} and \code{anovaBF} for other functions for
##'   testing multiple models simultaneously.
generalTestBF <-
  function(formula, data, whichRandom = NULL,
           whichModels = "withmain", neverExclude=NULL, iterations = 10000, progress = getOption('BFprogress', interactive()),
           rscaleFixed = "medium", rscaleRandom = "nuisance", rscaleCont="medium", rscaleEffects = NULL, multicore = FALSE, method="auto",
           noSample=FALSE, callback=function(...) as.integer(0))
  {
    data <- marshallTibble(data)

    checkFormula(formula, data, analysis = "lm")
    # pare whichRandom down to terms that appear in the formula
    whichRandom <- whichRandom[whichRandom %in% fmlaFactors(formula, data)[-1]]

    dataTypes <- createDataTypes(formula, whichRandom, data, analysis = "lm")

    models = enumerateGeneralModels(formula, whichModels, neverExclude,
                                    includeBottom = whichModels!="top",
                                    data = data)

    if(length(models)>getOption('BFMaxModels', 50000)) stop("Maximum number of models exceeded (",
                                                  length(models), " > ",getOption('BFMaxModels', 50000) ,"). ",
                                                  "The maximum can be increased by changing ",
                                                  "options('BFMaxModels').")

    if(multicore){
      message("Note: Progress bars and callbacks are suppressed when running multicore.")
      if(!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=models, .options.multicore=mcoptions),
        lmBF(gIndex,data = data, whichRandom = whichRandom,
             rscaleFixed = rscaleFixed, rscaleRandom = rscaleRandom,
             rscaleCont = rscaleCont, rscaleEffects = rscaleEffects, iterations = iterations, method=method,
             progress=FALSE,noSample=noSample)
        )
    }else{ # Single core
      checkCallback(callback,as.integer(0))
      bfs = NULL
      myCallback <- function(prgs){
        frac <- (i - 1 + prgs/1000)/length(models)
        ret <- callback(frac*1000)
        return(as.integer(ret))
      }
      if(progress){
        pb = txtProgressBar(min = 0, max = length(models), style = 3)
      }else{
        pb = NULL
      }
      for(i in 1:length(models)){
        oneModel <- lmBF(models[[i]],data = data, whichRandom = whichRandom,
          rscaleFixed = rscaleFixed, rscaleRandom = rscaleRandom,
          rscaleCont = rscaleCont, rscaleEffects = rscaleEffects, iterations = iterations,
          progress = FALSE, method = method,noSample=noSample,callback=myCallback)
        if(inherits(pb,"txtProgressBar")) setTxtProgressBar(pb, i)
        bfs = c(bfs,oneModel)
      }
      if(inherits(pb,"txtProgressBar")) close(pb)
      checkCallback(callback,as.integer(1000))
    }

    # combine all the Bayes factors into one BFBayesFactor object
    bfObj = do.call("c", bfs)

    if(whichModels=="top") bfObj = BFBayesFactorTop(bfObj)

    return(bfObj)
  }