├── .github ├── .gitignore ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── check-standard.yaml │ ├── pkgdown.yaml │ ├── test-coverage.yaml │ └── rhub.yaml ├── vignettes ├── .gitignore ├── Dukelogo.jpg └── custom.scss ├── revdep ├── failures.md ├── problems.md ├── data 2.sqlite ├── .gitignore ├── cran.md └── README.md ├── .covrignore ├── src ├── Makevars.win ├── Makevars ├── hypergeometric2F1.c ├── mem.c ├── dch1up.f ├── amcmc-funs.c ├── mtherr.c ├── E_ZS.c ├── hypergeometric1F1.c └── hg_approx_null_np.c ├── images ├── code.png ├── tar.png ├── top.png ├── zip.png └── pattern.png ├── tests ├── testthat.R └── testthat │ ├── test-summary.R │ ├── test-diagnostics.R │ ├── test-bayesreg.R │ ├── test-logit-BIC-coef.R │ ├── test-update.R │ ├── test-image.R │ ├── test-outliers.R │ ├── test-bas-FPS.R │ ├── test-plot.R │ ├── test-model_probabilities.R │ ├── test-family.R │ ├── test-bas-amcmc.R │ ├── test-model-priors.R │ ├── test-bas-lm-lowrank.R │ ├── test-special-functions.R │ ├── test-priorprobs.R │ └── test-coefficients.R ├── data ├── Hald.txt.gz ├── bodyfat.rda ├── climate.rda └── protein.txt.gz ├── inst ├── logo │ ├── logo.png │ └── logo.R └── figures │ ├── BASimg.png │ ├── logo.png │ └── BAS-image.png ├── man ├── figures │ ├── logo.png │ └── unnamed-chunk-3-1.png ├── Bernoulli.heredity.Rd ├── EB.local.Rd ├── uniform.Rd ├── g.prior.Rd ├── robust.Rd ├── hypergeometric1F1.Rd ├── protein.Rd ├── beta.prime.Rd ├── hyper.g.Rd ├── which.matrix.Rd ├── TG.Rd ├── testBF.prior.Rd ├── Jeffreys.Rd ├── beta.binomial.Rd ├── Hald.Rd ├── IC.prior.Rd ├── Bernoulli.Rd ├── CCH.Rd ├── print.bas.Rd ├── climate.Rd ├── tr.poisson.Rd ├── hyper.g.n.Rd ├── tCCH.Rd ├── EB.global.Rd ├── tr.power.prior.Rd ├── cv.summary.bas.Rd ├── list2matrix.which.Rd ├── intrinsic.Rd ├── list2matrix.Rd ├── variable.names.pred.bas.Rd ├── Bayes.outlier.Rd ├── hypergeometric2F1.Rd ├── tr.beta.binomial.Rd ├── summary.Rd ├── update.Rd ├── phi1.Rd ├── trCCH.Rd ├── diagnostics.Rd ├── plot.coef.Rd ├── plot.confint.Rd ├── force.heredity.bas.Rd ├── eplogprob.Rd ├── confint.pred.Rd ├── BAS.Rd ├── eplogprob.marg.Rd ├── confint.coef.Rd ├── bayesglm.fit.Rd ├── image.bas.Rd ├── plot.Rd └── fitted.Rd ├── README-fig └── unnamed-chunk-3-1.png ├── demo ├── 00Index ├── BAS.USCrime.R └── BAS.hald.R ├── R ├── FPS-estimators.R ├── hypergeometric1F1.R ├── cv_summary.R ├── BAS-package.R ├── diagnostics.R ├── hypergeometric2F1.R ├── outliers.R ├── update.R ├── EB_global.R ├── plot_coef.R └── summary.R ├── .htaccess ├── codecov.yml ├── .gitignore ├── BAS.Rproj ├── .travis.yml ├── .Rbuildignore ├── cran-comments.md ├── run_checks.R ├── NAMESPACE ├── SECURITY.md ├── _pkgdown.yml ├── DESCRIPTION └── CODE_OF_CONDUCT.md /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /revdep/failures.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /revdep/problems.md: -------------------------------------------------------------------------------- 1 | *Wow, no problems at all. :)* -------------------------------------------------------------------------------- /.covrignore: -------------------------------------------------------------------------------- 1 | src/mtherr.c 2 | src/hyp2f1.c 3 | src/hyp1F1.c 4 | -------------------------------------------------------------------------------- /src/Makevars.win: -------------------------------------------------------------------------------- 1 | PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) 2 | 3 | -------------------------------------------------------------------------------- /images/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/images/code.png -------------------------------------------------------------------------------- /images/tar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/images/tar.png -------------------------------------------------------------------------------- /images/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/images/top.png -------------------------------------------------------------------------------- /images/zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/images/zip.png -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(BAS) 3 | 4 | test_check("BAS") 5 | -------------------------------------------------------------------------------- /data/Hald.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/data/Hald.txt.gz -------------------------------------------------------------------------------- /data/bodyfat.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/data/bodyfat.rda -------------------------------------------------------------------------------- /data/climate.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/data/climate.rda -------------------------------------------------------------------------------- /images/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/images/pattern.png -------------------------------------------------------------------------------- /inst/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/inst/logo/logo.png -------------------------------------------------------------------------------- /data/protein.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/data/protein.txt.gz -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/man/figures/logo.png -------------------------------------------------------------------------------- /revdep/data 2.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/revdep/data 2.sqlite -------------------------------------------------------------------------------- /inst/figures/BASimg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/inst/figures/BASimg.png -------------------------------------------------------------------------------- /inst/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/inst/figures/logo.png -------------------------------------------------------------------------------- /vignettes/Dukelogo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/vignettes/Dukelogo.jpg -------------------------------------------------------------------------------- /inst/figures/BAS-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/inst/figures/BAS-image.png -------------------------------------------------------------------------------- /README-fig/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/README-fig/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /demo/00Index: -------------------------------------------------------------------------------- 1 | BAS.hald BMA using the hald data with 4 variables 2 | BAS.USCrime BMA using the UScrime data 3 | -------------------------------------------------------------------------------- /man/figures/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/merliseclyde/BAS/HEAD/man/figures/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /revdep/.gitignore: -------------------------------------------------------------------------------- 1 | checks 2 | library 3 | checks.noindex 4 | library.noindex 5 | cloud.noindex 6 | data.sqlite 7 | *.html 8 | -------------------------------------------------------------------------------- /src/Makevars: -------------------------------------------------------------------------------- 1 | # CXXFLAGS = -g -O0 2 | # PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) 3 | PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) 4 | VALGRIND_OPTS = --tool=memcheck --leak-check=full --dsymutil=yes 5 | -------------------------------------------------------------------------------- /revdep/cran.md: -------------------------------------------------------------------------------- 1 | ## revdepcheck results 2 | 3 | We checked 4 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. 4 | 5 | * We saw 0 new problems 6 | * We failed to check 0 packages 7 | 8 | -------------------------------------------------------------------------------- /src/hypergeometric2F1.c: -------------------------------------------------------------------------------- 1 | extern double hyp2f1(double, double, double, double); 2 | 3 | 4 | void hypergeometric2F1(double *a, double *b, double *c, double *x, double *y) 5 | { 6 | 7 | *y = hyp2f1(*a, *b, *c, *x); 8 | } 9 | 10 | 11 | -------------------------------------------------------------------------------- /R/FPS-estimators.R: -------------------------------------------------------------------------------- 1 | # FPS Estimators 2 | # 3 | compute_sample_probs_Bayes_HT = function(object) { 4 | models <- which.matrix(object$which, object$n.vars) 5 | probs <- object$probne0 6 | exp(models %*% log(probs) + (1 - models)%*% log(1 - probs)) 7 | } -------------------------------------------------------------------------------- /vignettes/custom.scss: -------------------------------------------------------------------------------- 1 | /*-- scss:defaults --*/ 2 | 3 | // fonts 4 | $presentation-heading-color: #00529B; 5 | $presentation-title-slide-text-align: "center"; 6 | $link-color: #75AADB; 7 | $code-block-font-size: 0.9em; 8 | 9 | /*-- scss:rules --*/ 10 | 11 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | # Extra Security Headers 2 | 3 | Header set X-XSS-Protection "1; mode=block" 4 | Header always append X-Frame-Options SAMEORIGIN 5 | Header set X-Content-Type-Options "nosniff" 6 | Header set Set-Cookie sess=123; path=/; SameSite=Strict 7 | 8 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | informational: true 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 1% 14 | informational: true 15 | -------------------------------------------------------------------------------- /tests/testthat/test-summary.R: -------------------------------------------------------------------------------- 1 | context("summary") 2 | test_that("summary.bas", { 3 | data(Hald) 4 | hald.bas <- bas.lm(Y ~ ., 5 | prior = "BIC", 6 | modelprior = uniform(), data = Hald 7 | ) 8 | expect_length(summary(hald.bas), 60) 9 | expect_null(print(hald.bas)) 10 | }) 11 | -------------------------------------------------------------------------------- /tests/testthat/test-diagnostics.R: -------------------------------------------------------------------------------- 1 | context("diagnostics") 2 | 3 | test_that("diagnostics.R", { 4 | data(Hald) 5 | hald_gprior <- bas.lm(Y ~ ., data=Hald, method='MCMC', MCMC.iterations = 10^6) 6 | expect_null(diagnostics(hald_gprior)) 7 | hald_gprior <- bas.lm(Y ~ ., data=Hald, method='MCMC+BAS', MCMC.iterations = 10^6) 8 | expect_error(diagnostics(hald_gprior)) 9 | }) 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | src/*.o 5 | src/*.so 6 | src/*.dll 7 | */*~ 8 | *~ 9 | BAS-github.Rproj 10 | .build.timestamp 11 | docs/* 12 | vignettes/BAS-vignette.R 13 | vignettes/BAS-vignette.html 14 | vignettes/BAS-vignette_files/* 15 | doc 16 | Meta 17 | docs 18 | tests/testthat/Rplots.pdf 19 | R/gordy.R 20 | inst/doc 21 | R/copyright.txt 22 | src/copyright.txt 23 | 24 | -------------------------------------------------------------------------------- /BAS.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | ProjectId: 85b1b751-a909-4ea5-bf96-0ecc5213e0d6 3 | 4 | RestoreWorkspace: Default 5 | SaveWorkspace: Default 6 | AlwaysSaveHistory: Default 7 | 8 | EnableCodeIndexing: Yes 9 | UseSpacesForTab: Yes 10 | NumSpacesForTab: 2 11 | Encoding: UTF-8 12 | 13 | RnwWeave: Sweave 14 | LaTeX: pdfLaTeX 15 | 16 | BuildType: Package 17 | PackageUseDevtools: Yes 18 | PackageInstallArgs: --no-multiarch --with-keep.source 19 | PackageCheckArgs: --as-cran 20 | PackageRoxygenize: rd,collate,namespace,vignette 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: r 2 | cache: packages 3 | r_check_args: '--as-cran' 4 | r_build_args: '--no-manual' 5 | #addons: 6 | # apt: 7 | # packages: 8 | # - valgrind 9 | env: 10 | # - VALGRIND_OPTS='--leak-check=full --track-origins=yes' 11 | global: 12 | - _R_CRAN_CHECK_INCOMING_=true 13 | - _R_CHECK_CRAN_INCOMING_USE_ASPELL_=true 14 | r: 15 | - devel 16 | - release 17 | 18 | os: linux 19 | dist: bionic 20 | 21 | compiler: gcc 22 | 23 | after_success: 24 | - Rscript -e 'covr::codecov()' 25 | 26 | -------------------------------------------------------------------------------- /tests/testthat/test-bayesreg.R: -------------------------------------------------------------------------------- 1 | context(" issue 96 rank deficient models and R2") 2 | # Issue #96 3 | test_that("rank and R2", { 4 | # generate data and get bas output 5 | n = 4 6 | X = cbind(matrix(1, n, n), diag(1, n, n), matrix(1, n, n) - diag(1, n, n)) 7 | y = rnorm(n) 8 | bas_out = bas.lm(y~X, data=data.frame(y, X)) 9 | cond = bas_out$R2[bas_out$rank < n & n <= bas_out$size] < 1 # should be > 1 10 | expect_equal(sum(cond), length(cond)) 11 | cond = bas_out$R2[bas_out$rank == n & n <= bas_out$size] == 1 12 | expect_equal(sum(cond), length(cond)) 13 | }) 14 | 15 | -------------------------------------------------------------------------------- /tests/testthat/test-logit-BIC-coef.R: -------------------------------------------------------------------------------- 1 | test_that("coef in logistic glm", { 2 | Nrep = 1000 3 | 4 | # We load dataset 5 | data("birthwt", package = "MASS") 6 | 7 | birthwt$race <- as.factor(birthwt$race) 8 | 9 | # bas.glm 10 | set.seed(1000000) 11 | birthwt.bas.glm <- bas.glm(low ~ . -bwt, data=birthwt, 12 | family=binomial(link = "logit"), 13 | method="MCMC", 14 | MCMC.iterations=Nrep, 15 | laplace=TRUE) 16 | expect_no_error(coef(birthwt.bas.glm)) 17 | }) 18 | -------------------------------------------------------------------------------- /tests/testthat/test-update.R: -------------------------------------------------------------------------------- 1 | context("update.bas") 2 | 3 | test_that("update bas.lm", { 4 | data(Hald) 5 | hald_bic <- bas.lm(Y ~ ., 6 | data = Hald, prior = "BIC", 7 | initprobs = "eplogp", method="deterministic") 8 | 9 | expect_error(update(hald_bic, newprior="g-prior")) 10 | 11 | hald_EBG <- bas.lm(Y ~ ., 12 | data = Hald, prior = "EB-global", 13 | initprobs = "eplogp", method="deterministic") 14 | hald_update <- update(hald_bic, newprior="EB-global") 15 | 16 | expect_equal(hald_EBG$postprobs, hald_update$postprobs) 17 | } 18 | ) -------------------------------------------------------------------------------- /tests/testthat/test-image.R: -------------------------------------------------------------------------------- 1 | context("image.bas") 2 | 3 | test_that("test image plots", { 4 | data("Hald") 5 | hald.ZSprior <- bas.lm(Y ~ ., data = Hald, prior = "JZS") 6 | expect_null(image(hald.ZSprior, drop.always.included = TRUE)) 7 | expect_null(image(hald.ZSprior, drop.always.included = FALSE)) 8 | expect_null(image(hald.ZSprior, rotate = FALSE)) 9 | expect_null(image(hald.ZSprior, prob = FALSE)) 10 | expect_null(image(hald.ZSprior, intensity = FALSE)) 11 | expect_null(image(hald.ZSprior, intensity = TRUE, color = "blackandwhite")) 12 | hald.ZSprior <- bas.lm(Y ~ ., data = Hald, include.always = Y ~ ., prior = "JZS") 13 | expect_error(image(hald.ZSprior, drop.always.included=TRUE)) 14 | }) 15 | -------------------------------------------------------------------------------- /tests/testthat/test-outliers.R: -------------------------------------------------------------------------------- 1 | context("outliers") 2 | 3 | test_that("outliers.R", { 4 | data("stackloss") 5 | stack_lm <- lm(stack.loss ~ ., data = stackloss) 6 | stack_outliers <- Bayes.outlier(stack_lm, k = 3) 7 | expect_null(plot(stack_outliers$prob.outlier, type = "h", 8 | ylab = "Posterior Probability")) 9 | # adjust for sample size for calculating prior prob that a 10 | # a case is an outlier 11 | stack_outliers <- Bayes.outlier(stack_lm, prior.prob = 0.95) 12 | #' # cases where posterior probability exceeds prior probability 13 | expect_length(which(stack_outliers$prob.outlier > 14 | stack_outliers$prior.prob),2) 15 | expect_error(stack_outliers <- Bayes.outlier(stack_lm)) 16 | }) 17 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve BAS! 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | `add R code here` 17 | 18 | **Expected behavior** 19 | A clear and concise description of what you expected to happen. 20 | 21 | **Screenshots** 22 | If applicable, add screenshots to help explain your problem. 23 | 24 | **Desktop (please complete the following information):** 25 | - OS: [e.g. OSX, Windows, Linux flavor] 26 | - R Version [e.g. 22] 27 | 28 | **Additional context** 29 | Add any other context about the problem here. 30 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^docs$ 2 | ^_pkgdown\.yml$ 3 | ^.*\.Rproj$ 4 | ^\.Rproj\.user$ 5 | .github 6 | .covrignore 7 | .travis.yml 8 | .build.timestamp 9 | ^README\.Rmd$ 10 | ^README-.*\.png$ 11 | params.json 12 | javascripts/ 13 | images/ 14 | stylesheets/ 15 | NAMESPACE-preRoxygen 16 | BAS-Ex.Rout.fail 17 | BAS-Ex.R 18 | run_checks.R 19 | R/gordy.R 20 | R/amc-cholreg-check.R 21 | _pkgdown.yml 22 | LICENSE 23 | CODE_OF_CONDUCT.md 24 | cran-comments.md 25 | ^CRAN-RELEASE$ 26 | ^codecov\.yml$ 27 | CONTRIBUTING.md 28 | .htaccess 29 | R/copyright.txt 30 | src/copyright.txt 31 | 32 | ^cran-comments\.md$ 33 | ^doc$ 34 | ^Meta$ 35 | ^\.github$ 36 | ^pkgdown$ 37 | ^CRAN-SUBMISSION$ 38 | ^SECURITY\.md$ 39 | ^revdep$ 40 | R/counting_models_hereditary_constraint.R 41 | src/const.c 42 | src/mconf.h 43 | src/mcmc.c 44 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for BAS! 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | ** Describe the new feature** 11 | A clear and concise description of what you would like to see added to BAS. 12 | 13 | **Is your feature request related to a problem? Please describe.** 14 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 15 | 16 | **Describe the solution you'd like** 17 | A clear and concise description of what you want to happen. 18 | 19 | **Describe alternatives you've considered** 20 | A clear and concise description of any alternative solutions that are related. 21 | 22 | **Additional context** 23 | Add any other context or screenshots about the feature request here. 24 | -------------------------------------------------------------------------------- /tests/testthat/test-bas-FPS.R: -------------------------------------------------------------------------------- 1 | context("bas.lm") 2 | 3 | skip() # FPS tests are flaky due to difference in calculations of small probabilities on different systems 4 | 5 | # FIXME: Remove the skips above when the underlying issue is resolved due to normalization of very small probabilities 6 | test_that("FPS enumerate", { 7 | data("Hald") 8 | 9 | set.seed(42) 10 | hald.bas = bas.lm(Y ~ ., 11 | prior = "BIC", method = "MCMC+BAS", 12 | burnin.iterations = 1000, n.models=2^4, 13 | modelprior = uniform(), data = Hald, 14 | FPS = "none") 15 | 16 | set.seed(42) 17 | hald.bas.bayes = bas.lm(Y ~ ., 18 | prior = "BIC", method = "MCMC+BAS", 19 | burnin.iterations = 1000, n.models=2^4, 20 | modelprior = uniform(), data = Hald, 21 | FPS = "Bayes_HT") 22 | 23 | expect_equal(hald.bas$postprobs, hald.bas.bayes$postprobs) 24 | }) -------------------------------------------------------------------------------- /tests/testthat/test-plot.R: -------------------------------------------------------------------------------- 1 | context("plot.bas") 2 | 3 | test_that("test basic BAS plots", { 4 | data(Hald) 5 | hald.gprior <- bas.lm(Y ~ ., data = Hald, prior = "g-prior", 6 | modelprior = beta.binomial(1, 1), 7 | initprobs = "eplogp") 8 | expect_null(plot(hald.gprior, drop.always.included=TRUE, ask = FALSE)) 9 | 10 | expect_error(plot(hald.gprior, which = 5)) 11 | hald.gprior <- bas.lm(Y ~ ., include.always = Y ~ X1 + X4, data = Hald, prior = "g-prior", 12 | modelprior = beta.binomial(1, 1), 13 | initprobs = "eplogp") 14 | 15 | expect_null(plot(hald.gprior, drop.always.included=TRUE, ask=FALSE)) 16 | 17 | hald.gprior <- bas.lm(Y ~ ., include.always = Y ~ . , data = Hald, prior = "g-prior", 18 | modelprior = beta.binomial(1, 1), 19 | initprobs = "eplogp") 20 | expect_error(plot(hald.gprior, drop.always.included=TRUE, ask=FALSE, which=4)) 21 | }) 22 | -------------------------------------------------------------------------------- /demo/BAS.USCrime.R: -------------------------------------------------------------------------------- 1 | require(MASS) 2 | library(MASS) 3 | data(UScrime) 4 | #UScrime[,-2] = log(UScrime[,-2]) 5 | crime.bic = bas.lm(log(y) ~ log(M) + So + log(Ed) + log(Po1) + log(Po2) 6 | + log(LF) + log(M.F) + log(Pop) + log(NW) + 7 | log(U1) + log(U2) + log(GDP) + log(Ineq) + log(Prob)+ 8 | log(Time), 9 | data=UScrime, n.models=2^15, prior="BIC", 10 | modelprior=beta.binomial(1,1), 11 | initprobs= "eplogp") 12 | summary(crime.bic) 13 | plot(crime.bic) 14 | image(crime.bic, subset=-1) 15 | 16 | 17 | # takes a while to run: 18 | # crime.coef = coefficients(crime.bic) 19 | # crime.coef 20 | # par(mfrow=c(3,2)) 21 | # plot(crime.coef, ask=FALSE) 22 | 23 | # see update 24 | #crime.aic = update(crime.bic, newprior="AIC") 25 | #crime.zs = update(crime.bic, newprior="ZS-null") 26 | 27 | #crime.EBG = EB.global.bma(crime.bic) 28 | # same as update(crime.bic, newprior="EB-global") 29 | #image(crime.EBG, subset=-1) 30 | 31 | -------------------------------------------------------------------------------- /demo/BAS.hald.R: -------------------------------------------------------------------------------- 1 | data(Hald) 2 | hald.gprior = bas.lm(Y~ ., data=Hald, prior="g-prior", alpha=13, 3 | modelprior=beta.binomial(1,1), 4 | initprobs="eplogp") 5 | 6 | hald.gprior 7 | plot(hald.gprior) 8 | summary(hald.gprior) 9 | image(hald.gprior, subset=-1, vlas=0) 10 | 11 | hald.coef = coefficients(hald.gprior) 12 | hald.coef 13 | plot(hald.coef) 14 | predict(hald.gprior, top=5, se.fit=TRUE) 15 | confint(predict(hald.gprior, Hald, estimator="BMA", se.fit=TRUE, top=5), parm="mean") 16 | predict(hald.gprior, estimator="MPM", se.fit=TRUE) 17 | confint(predict(hald.gprior, Hald, estimator="MPM", se.fit=TRUE), parm="mean") 18 | 19 | fitted(hald.gprior, estimator="HPM") 20 | hald.gprior = bas.lm(Y~ ., data=Hald, n.models=2^4, 21 | prior="g-prior", alpha=13, modelprior=uniform(), 22 | initprobs="eplogp") 23 | hald.EB = update(hald.gprior, newprior="EB-global") 24 | hald.bic = update(hald.gprior,newprior="BIC") 25 | hald.zs = update(hald.bic, newprior="ZS-null") 26 | -------------------------------------------------------------------------------- /man/Bernoulli.heredity.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_priors.R 3 | \name{Bernoulli.heredity} 4 | \alias{Bernoulli.heredity} 5 | \title{Independent Bernoulli prior on models that with constraints for 6 | model hierarchy induced by interactions} 7 | \usage{ 8 | Bernoulli.heredity(pi = 0.5, parents) 9 | } 10 | \arguments{ 11 | \item{pi}{Bernoulli probability that term is included} 12 | 13 | \item{parents}{matrix of terms and parents with indicators of which terms 14 | are parents for each term} 15 | } 16 | \description{ 17 | Independent Bernoulli prior on models that with constraints for 18 | model hierarchy induced by interactions 19 | } 20 | \note{ 21 | Not implemented yet for use with bas.lm or bas.glm 22 | } 23 | \seealso{ 24 | Other priors modelpriors: 25 | \code{\link{Bernoulli}()}, 26 | \code{\link{beta.binomial}()}, 27 | \code{\link{tr.beta.binomial}()}, 28 | \code{\link{tr.poisson}()}, 29 | \code{\link{tr.power.prior}()}, 30 | \code{\link{uniform}()} 31 | } 32 | \concept{priors modelpriors} 33 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | # Notes to CRAN 2 | 3 | ## Submission reason 4 | 5 | * This submission addresses CRAN Additional Issues under valgrind: unintialized values leading to conditional 6 | jumps or moves depending on unitialized values 7 | 8 | * Update is necessary before 1/15/2026 to maintain on CRAN 9 | 10 | 11 | ## Test environments 12 | 13 | - ubuntu R-devel with valgrind via docker 14 | - local OS X install, R 4.5.2 (arm64) 15 | - win-builder (r-release, r-devel) 16 | 17 | No issues identified via the docker valgrind checks and running of examples and unit tests per WRE usage of Valgrind 18 | 19 | ## R CMD check results for this submission 20 | 21 | * Mac, Windows, Ubuntu 22 | 0 error | 0 warnings | 0 notes 23 | 24 | 25 | ## Reverse Dependencies 26 | 27 | - ginormal 28 | - EMJMCMC 29 | - PEPBVS 30 | - FBMS 31 | 32 | ## revdepcheck results 33 | 34 | ## revdepcheck results 35 | 36 | We checked 4 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. 37 | 38 | * We saw 0 new problems 39 | * We failed to check 0 packages 40 | 41 | 42 | -------------------------------------------------------------------------------- /man/EB.local.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/beta_priors.R 3 | \name{EB.local} 4 | \alias{EB.local} 5 | \alias{EB} 6 | \title{Empirical Bayes Prior Distribution for Coefficients in BMA Model} 7 | \usage{ 8 | EB.local() 9 | } 10 | \value{ 11 | returns an object of class "prior", with the family and 12 | hyerparameters. 13 | } 14 | \description{ 15 | Creates an object representing the EB prior for BAS GLM. 16 | } 17 | \details{ 18 | Creates a structure used for \code{\link{bas.glm}}. 19 | } 20 | \examples{ 21 | EB.local() 22 | } 23 | \seealso{ 24 | \code{\link{CCH}} and \code{\link{bas.glm}} 25 | 26 | Other beta priors: 27 | \code{\link{CCH}()}, 28 | \code{\link{IC.prior}()}, 29 | \code{\link{Jeffreys}()}, 30 | \code{\link{TG}()}, 31 | \code{\link{beta.prime}()}, 32 | \code{\link{g.prior}()}, 33 | \code{\link{hyper.g}()}, 34 | \code{\link{hyper.g.n}()}, 35 | \code{\link{intrinsic}()}, 36 | \code{\link{robust}()}, 37 | \code{\link{tCCH}()}, 38 | \code{\link{testBF.prior}()} 39 | } 40 | \author{ 41 | Merlise Clyde 42 | } 43 | \concept{beta priors} 44 | -------------------------------------------------------------------------------- /man/uniform.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_priors.R 3 | \name{uniform} 4 | \alias{uniform} 5 | \alias{Uniform} 6 | \title{Uniform Prior Distribution for Models} 7 | \usage{ 8 | uniform() 9 | } 10 | \value{ 11 | returns an object of class "prior", with the family name Uniform. 12 | } 13 | \description{ 14 | Creates an object representing the prior distribution on models for BAS. 15 | } 16 | \details{ 17 | The Uniform prior distribution is a commonly used prior in BMA, and is a 18 | special case of the independent Bernoulli prior with probs=.5. The implied 19 | prior distribution on model size is binomial(p, .5). 20 | } 21 | \examples{ 22 | uniform() 23 | } 24 | \seealso{ 25 | \code{\link{bas.lm}}, 26 | \code{\link{beta.binomial}},\code{\link{Bernoulli}}, 27 | 28 | Other priors modelpriors: 29 | \code{\link{Bernoulli}()}, 30 | \code{\link{Bernoulli.heredity}()}, 31 | \code{\link{beta.binomial}()}, 32 | \code{\link{tr.beta.binomial}()}, 33 | \code{\link{tr.poisson}()}, 34 | \code{\link{tr.power.prior}()} 35 | } 36 | \author{ 37 | Merlise Clyde 38 | } 39 | \concept{priors modelpriors} 40 | -------------------------------------------------------------------------------- /run_checks.R: -------------------------------------------------------------------------------- 1 | # check on additional sites 2 | # 3 | devtools::check_win_devel() 4 | 5 | 6 | 3rhub::rhub_check(branch="devel", platforms = "valgrind") # if needed 7 | 8 | 9 | 10 | 11 | # first merge main devel in terminal 12 | # on devel 13 | git merge main 14 | # change to main 15 | git checkout main 16 | # merge changes from devel into main 17 | git merge devel 18 | 19 | 20 | # Check current CRAN check results 21 | usethis::use_release_issue() 22 | 23 | 24 | urlchecker::url_check() 25 | devtools::build_readme() 26 | devtools::check(remote = TRUE, manual = TRUE) 27 | 28 | devtools::install_github("r-lib/revdepcheck") 29 | 30 | revdepcheck::revdep_reset() 31 | revdepcheck::revdep_check(num_workers = 4) 32 | revdepcheck::revdep_report_cran() 33 | 34 | # check email for results 35 | devtools::check_win_devel() 36 | 37 | 38 | # check rhub. (see github actions to trigger rhub workflow 39 | rhub::rhub_check() 40 | rhub::rhub_check(branch="main", platforms = "gcc15") 41 | rhub::rhub_check(branch="main", platforms = "c23") 42 | 43 | 44 | # to submit to CRAN 45 | usethis::use_version('major') 46 | 47 | devtools::submit_cran() 48 | 49 | usethis::use_dev_version(push = TRUE) 50 | -------------------------------------------------------------------------------- /man/g.prior.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/beta_priors.R 3 | \name{g.prior} 4 | \alias{g.prior} 5 | \title{Families of G-Prior Distribution for Coefficients in BMA Models} 6 | \usage{ 7 | g.prior(g) 8 | } 9 | \arguments{ 10 | \item{g}{a scalar used in the covariance of Zellner's g-prior, Cov(beta) = 11 | sigma^2 g (X'X)^-1} 12 | } 13 | \value{ 14 | returns an object of class "prior", with the family and 15 | hyerparameters. 16 | } 17 | \description{ 18 | Creates an object representing the g-prior distribution on coefficients for 19 | BAS. 20 | } 21 | \details{ 22 | Creates a structure used for BAS. 23 | } 24 | \examples{ 25 | g.prior(100) 26 | } 27 | \seealso{ 28 | \code{\link{IC.prior}} 29 | 30 | Other beta priors: 31 | \code{\link{CCH}()}, 32 | \code{\link{EB.local}()}, 33 | \code{\link{IC.prior}()}, 34 | \code{\link{Jeffreys}()}, 35 | \code{\link{TG}()}, 36 | \code{\link{beta.prime}()}, 37 | \code{\link{hyper.g}()}, 38 | \code{\link{hyper.g.n}()}, 39 | \code{\link{intrinsic}()}, 40 | \code{\link{robust}()}, 41 | \code{\link{tCCH}()}, 42 | \code{\link{testBF.prior}()} 43 | } 44 | \author{ 45 | Merlise Clyde 46 | } 47 | \concept{beta priors} 48 | -------------------------------------------------------------------------------- /man/robust.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/beta_priors.R 3 | \name{robust} 4 | \alias{robust} 5 | \title{Robust-Prior Distribution for Coefficients in BMA Model} 6 | \usage{ 7 | robust(n = NULL) 8 | } 9 | \arguments{ 10 | \item{n}{the sample size.} 11 | } 12 | \value{ 13 | returns an object of class "prior", with the family and 14 | hyerparameters. 15 | } 16 | \description{ 17 | Creates an object representing the robust prior of Bayarri et al (2012) that 18 | is mixture of g-priors on coefficients for BAS. 19 | } 20 | \details{ 21 | Creates a prior structure used for \code{\link{bas.glm}}. 22 | } 23 | \examples{ 24 | robust(100) 25 | } 26 | \seealso{ 27 | \code{\link{CCH}} and\code{\link{bas.glm}} 28 | 29 | Other beta priors: 30 | \code{\link{CCH}()}, 31 | \code{\link{EB.local}()}, 32 | \code{\link{IC.prior}()}, 33 | \code{\link{Jeffreys}()}, 34 | \code{\link{TG}()}, 35 | \code{\link{beta.prime}()}, 36 | \code{\link{g.prior}()}, 37 | \code{\link{hyper.g}()}, 38 | \code{\link{hyper.g.n}()}, 39 | \code{\link{intrinsic}()}, 40 | \code{\link{tCCH}()}, 41 | \code{\link{testBF.prior}()} 42 | } 43 | \author{ 44 | Merlise Clyde 45 | } 46 | \concept{beta priors} 47 | -------------------------------------------------------------------------------- /src/mem.c: -------------------------------------------------------------------------------- 1 | /* Modified to be compatible with R memory allocation */ 2 | #include 3 | #include 4 | #include 5 | #include "bas.h" 6 | 7 | double *vecalloc(int nr) 8 | { 9 | double *x; 10 | x=(double *) R_alloc(nr,sizeof(double)); 11 | return x; 12 | } 13 | 14 | 15 | int *ivecalloc(int nr) 16 | { 17 | int *x; 18 | x= (int *) R_alloc( nr, sizeof(int)); 19 | return x; 20 | } 21 | 22 | 23 | 24 | 25 | unsigned char **cmatalloc(int nr, int nc) 26 | { 27 | int k; 28 | unsigned char **x; 29 | x = (unsigned char **) R_alloc(nr, sizeof(unsigned char *)); 30 | for (k=0;k 0. The hyper.g(alpha) is equivalent to CCH(alpha -2, 11 | 2, 0). Liang et al recommended values in the range 2 < alpha_h <= 3} 12 | } 13 | \value{ 14 | returns an object of class "prior", with the family and 15 | hyerparameters. 16 | } 17 | \description{ 18 | Creates an object representing the hyper-g mixture of g-priors on 19 | coefficients for BAS. 20 | } 21 | \details{ 22 | Creates a structure used for \code{\link{bas.glm}}. 23 | } 24 | \examples{ 25 | hyper.g(alpha = 3) 26 | } 27 | \seealso{ 28 | \code{\link{CCH}} \code{\link{bas.glm}} 29 | 30 | Other beta priors: 31 | \code{\link{CCH}()}, 32 | \code{\link{EB.local}()}, 33 | \code{\link{IC.prior}()}, 34 | \code{\link{Jeffreys}()}, 35 | \code{\link{TG}()}, 36 | \code{\link{beta.prime}()}, 37 | \code{\link{g.prior}()}, 38 | \code{\link{hyper.g.n}()}, 39 | \code{\link{intrinsic}()}, 40 | \code{\link{robust}()}, 41 | \code{\link{tCCH}()}, 42 | \code{\link{testBF.prior}()} 43 | } 44 | \author{ 45 | Merlise Clyde 46 | } 47 | \concept{beta priors} 48 | -------------------------------------------------------------------------------- /man/which.matrix.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/as_matrix.R 3 | \name{which.matrix} 4 | \alias{which.matrix} 5 | \title{Coerce a BAS list object of models into a matrix.} 6 | \usage{ 7 | which.matrix(which, n.vars) 8 | } 9 | \arguments{ 10 | \item{which}{a 'bas' model object \code{x$which}} 11 | 12 | \item{n.vars}{the total number of predictors, \code{x$n.vars}} 13 | } 14 | \value{ 15 | a matrix representation of \code{x$which}, with number of rows equal 16 | to the length of which.models or total number of models and number of 17 | columns \code{x$n.vars} 18 | } 19 | \description{ 20 | This function coerces the list object of models to a matrix and fill in the 21 | zeros to facilitate other computations. 22 | } 23 | \details{ 24 | \code{which.matrix} coerces 25 | \code{x$which} into a matrix. 26 | } 27 | \examples{ 28 | 29 | data(Hald) 30 | Hald.bic <- bas.lm(Y ~ ., data=Hald, prior="BIC", initprobs="eplogp") 31 | # matrix of model indicators 32 | models <- which.matrix(Hald.bic$which, Hald.bic$n.vars) 33 | 34 | } 35 | \seealso{ 36 | \code{\link{bas}} 37 | 38 | Other as.matrix methods: 39 | \code{\link{list2matrix.bas}()}, 40 | \code{\link{list2matrix.which}()} 41 | } 42 | \author{ 43 | Merlise Clyde \email{clyde@duke.edu} 44 | } 45 | \concept{as.matrix methods} 46 | \keyword{regression} 47 | -------------------------------------------------------------------------------- /man/TG.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/beta_priors.R 3 | \name{TG} 4 | \alias{TG} 5 | \title{Generalized g-Prior Distribution for Coefficients in BMA Models} 6 | \usage{ 7 | TG(alpha = 2) 8 | } 9 | \arguments{ 10 | \item{alpha}{a scalar > 0, recommended alpha=.5 (betaprime) or 1. alpha=2 11 | corresponds to the uniform prior on the shrinkage factor.} 12 | } 13 | \value{ 14 | returns an object of class "prior", with the family and 15 | hyerparameters. 16 | } 17 | \description{ 18 | Creates an object representing the Truncated Gamma (tCCH) mixture of 19 | g-priors on coefficients for BAS, where u = 1/(1+g) has a Gamma distribution 20 | supported on (0, 1]. 21 | } 22 | \details{ 23 | Creates a structure used for \code{\link{bas.glm}}. 24 | } 25 | \examples{ 26 | 27 | TG(alpha = 2) 28 | CCH(alpha = 2, beta = 100, s = 0) 29 | } 30 | \seealso{ 31 | \code{\link{CCH}} \code{\link{bas.glm}} 32 | 33 | Other beta priors: 34 | \code{\link{CCH}()}, 35 | \code{\link{EB.local}()}, 36 | \code{\link{IC.prior}()}, 37 | \code{\link{Jeffreys}()}, 38 | \code{\link{beta.prime}()}, 39 | \code{\link{g.prior}()}, 40 | \code{\link{hyper.g}()}, 41 | \code{\link{hyper.g.n}()}, 42 | \code{\link{intrinsic}()}, 43 | \code{\link{robust}()}, 44 | \code{\link{tCCH}()}, 45 | \code{\link{testBF.prior}()} 46 | } 47 | \author{ 48 | Merlise Clyde 49 | } 50 | \concept{beta priors} 51 | -------------------------------------------------------------------------------- /R/hypergeometric1F1.R: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | # This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | # License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | # 5 | #' Confluent hypergeometric1F1 function 6 | #' 7 | #' Compute the Confluent Hypergeometric function: 1F1(a,b,c,t) = 8 | #' Gamma(b)/(Gamma(b-a)Gamma(a)) Int_0^1 t^(a-1) (1 - t)^(b-a-1) exp(c t) dt 9 | #' 10 | #' 11 | #' @param a arbitrary 12 | #' @param b Must be greater 0 13 | #' @param c arbitrary 14 | #' @param laplace The default is to use the Cephes library; for large a or s 15 | #' this may return an NA, Inf or negative values,, in which case you should use 16 | #' the Laplace approximation. 17 | #' @param log if TRUE, return log(1F1) 18 | #' @author Merlise Clyde (\email{clyde@@stat.duke.edu}) 19 | #' @references Cephes library hyp1f1.c 20 | #' @keywords math 21 | #' @examples 22 | #' hypergeometric1F1(11.14756, 0.5, 0.00175097) 23 | #' 24 | #' 25 | #' @rdname hypergeometric1F1 26 | #' @family special functions 27 | #' @export 28 | hypergeometric1F1 = function(a,b,c, laplace=FALSE, log=TRUE) { 29 | 30 | n = length(a); 31 | out = rep(0, n); 32 | ans = .C(C_hypergeometric1F1, as.numeric(a), as.numeric(b), as.numeric(c), out=as.numeric(out), as.integer(n), 33 | as.integer(rep(laplace, n)))$out 34 | if (!log) ans = exp(ans) 35 | return(ans) 36 | } 37 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(coef,bas) 4 | S3method(confint,coef.bas) 5 | S3method(confint,pred.bas) 6 | S3method(fitted,bas) 7 | S3method(image,bas) 8 | S3method(plot,bas) 9 | S3method(plot,coef.bas) 10 | S3method(plot,confint.bas) 11 | S3method(predict,bas) 12 | S3method(predict,basglm) 13 | S3method(print,bas) 14 | S3method(print,coef.bas) 15 | S3method(summary,bas) 16 | S3method(update,bas) 17 | S3method(variable.names,pred.bas) 18 | export(Bayes.outlier) 19 | export(Bernoulli) 20 | export(Bernoulli.heredity) 21 | export(CCH) 22 | export(EB.global) 23 | export(EB.local) 24 | export(IC.prior) 25 | export(Jeffreys) 26 | export(TG) 27 | export(aic.prior) 28 | export(bas.glm) 29 | export(bas.lm) 30 | export(bayesglm.fit) 31 | export(beta.binomial) 32 | export(beta.prime) 33 | export(bic.prior) 34 | export(cv.summary.bas) 35 | export(diagnostics) 36 | export(eplogprob) 37 | export(eplogprob.marg) 38 | export(force.heredity.bas) 39 | export(g.prior) 40 | export(hyper.g) 41 | export(hyper.g.n) 42 | export(hypergeometric1F1) 43 | export(hypergeometric2F1) 44 | export(intrinsic) 45 | export(list2matrix.bas) 46 | export(list2matrix.which) 47 | export(phi1) 48 | export(robust) 49 | export(tCCH) 50 | export(testBF.prior) 51 | export(tr.beta.binomial) 52 | export(tr.poisson) 53 | export(tr.power.prior) 54 | export(trCCH) 55 | export(uniform) 56 | export(which.matrix) 57 | import(grDevices) 58 | import(graphics) 59 | import(stats) 60 | useDynLib(BAS, .registration=TRUE, .fixes="C_") 61 | -------------------------------------------------------------------------------- /man/testBF.prior.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/beta_priors.R 3 | \name{testBF.prior} 4 | \alias{testBF.prior} 5 | \title{Test based Bayes Factors for BMA Models} 6 | \usage{ 7 | testBF.prior(g) 8 | } 9 | \arguments{ 10 | \item{g}{a scalar used in the covariance of Zellner's g-prior, Cov(beta) = 11 | sigma^2 g (X'X)^-} 12 | } 13 | \value{ 14 | returns an object of class "prior", with the family and 15 | hyerparameters. 16 | } 17 | \description{ 18 | Creates an object representing the prior distribution on coefficients for 19 | BAS that corresponds to the test-based Bayes Factors. 20 | } 21 | \details{ 22 | Creates a prior object structure used for BAS in `bas.glm`. 23 | } 24 | \examples{ 25 | 26 | testBF.prior(100) 27 | library(MASS) 28 | data(Pima.tr) 29 | 30 | # use g = n 31 | bas.glm(type ~ ., 32 | data = Pima.tr, family = binomial(), 33 | betaprior = testBF.prior(nrow(Pima.tr)), 34 | modelprior = uniform(), method = "BAS" 35 | ) 36 | } 37 | \seealso{ 38 | \code{\link{g.prior}}, \code{\link{bas.glm}} 39 | 40 | Other beta priors: 41 | \code{\link{CCH}()}, 42 | \code{\link{EB.local}()}, 43 | \code{\link{IC.prior}()}, 44 | \code{\link{Jeffreys}()}, 45 | \code{\link{TG}()}, 46 | \code{\link{beta.prime}()}, 47 | \code{\link{g.prior}()}, 48 | \code{\link{hyper.g}()}, 49 | \code{\link{hyper.g.n}()}, 50 | \code{\link{intrinsic}()}, 51 | \code{\link{robust}()}, 52 | \code{\link{tCCH}()} 53 | } 54 | \author{ 55 | Merlise Clyde 56 | } 57 | \concept{beta priors} 58 | -------------------------------------------------------------------------------- /man/Jeffreys.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/beta_priors.R 3 | \name{Jeffreys} 4 | \alias{Jeffreys} 5 | \title{Jeffreys Prior Distribution for $g$ for Mixtures of g-Priors for 6 | Coefficients in BMA Models} 7 | \usage{ 8 | Jeffreys() 9 | } 10 | \value{ 11 | returns an object of class "prior", with the family and 12 | hyerparameters. 13 | } 14 | \description{ 15 | Creates an object representing the Jeffrey's Prior on g mixture of g-priors 16 | on coefficients for BAS. This is equivalent to a limiting version of the 17 | CCH(a, 2, 0) with a = 0 or they hyper-g(a = 2) and is an improper prior. As 18 | $g$ does not appear in the Null Model, Bayes Factors and model probabilities 19 | are not well-defined because of arbitrary normalizing constants, and for 20 | this reason the null model is excluded and the same constants are used 21 | across other models. 22 | } 23 | \details{ 24 | Creates a structure used for \code{\link{bas.glm}}. 25 | } 26 | \examples{ 27 | Jeffreys() 28 | } 29 | \seealso{ 30 | \code{\link{CCH}} \code{\link{bas.glm}} 31 | 32 | Other beta priors: 33 | \code{\link{CCH}()}, 34 | \code{\link{EB.local}()}, 35 | \code{\link{IC.prior}()}, 36 | \code{\link{TG}()}, 37 | \code{\link{beta.prime}()}, 38 | \code{\link{g.prior}()}, 39 | \code{\link{hyper.g}()}, 40 | \code{\link{hyper.g.n}()}, 41 | \code{\link{intrinsic}()}, 42 | \code{\link{robust}()}, 43 | \code{\link{tCCH}()}, 44 | \code{\link{testBF.prior}()} 45 | } 46 | \author{ 47 | Merlise Clyde 48 | } 49 | \concept{beta priors} 50 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Supported with security updates. 6 | 7 | | Version | Supported | 8 | | ------- | ------------------ | 9 | | 1.0.x | :white_check_mark: | 10 | | < 1.0 | :x: | 11 | 12 | ## Reporting a Vulnerability 13 | 14 | Please submit any vulnerability reports under [Github Issues](https://github.com/merliseclyde/BAS/issues) and maintainers will address as soon as possibl 15 | 16 | ## Expectations 17 | 18 | This package utilizes C/FORTRAN code for efficiency and allocates/frees memory using standard C library routines. 19 | The package is checked for memory leaks prior to releases to CRAN using 20 | ASAN/UBSBAN. The package is distributed via CRAN https://CRAN.R-project.org/package=BAS which reports additional checks. The development version may be installed from GitHub https://github.com/merliseclyde/BAS which is checked via github actions 21 | (users may check that the current version has a passing badge before installing) 22 | Bugs are reported via the Issue tracker and handled as soon as possible. 23 | (See link above) 24 | 25 | ## Assurance 26 | 27 | It is highly unlikely that malicious code would be added to the package. All submissions to CRAN require verification via the maintainer's email, which is protected via two factor authentication. Any pull requests for contributions on github are verified by the lead maintainer. Based on the Code of Conduct and Contributing Guidelines any modifications should include unit tests that cover the additional code blocks. -------------------------------------------------------------------------------- /man/beta.binomial.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_priors.R 3 | \name{beta.binomial} 4 | \alias{beta.binomial} 5 | \alias{Beta.Binomial} 6 | \title{Beta-Binomial Prior Distribution for Models} 7 | \usage{ 8 | beta.binomial(alpha = 1, beta = 1) 9 | } 10 | \arguments{ 11 | \item{alpha}{parameter in the beta prior distribution} 12 | 13 | \item{beta}{parameter in the beta prior distribution} 14 | } 15 | \value{ 16 | returns an object of class "prior", with the family and 17 | hyperparameters. 18 | } 19 | \description{ 20 | Creates an object representing the prior distribution on models for BAS. 21 | } 22 | \details{ 23 | The beta-binomial distribution on model size is obtained by assigning each 24 | variable inclusion indicator independent Bernoulli distributions with 25 | probability w, and then giving w a beta(alpha,beta) distribution. 26 | Marginalizing over w leads to the distribution on model size having the 27 | beta-binomial distribution. The default hyperparameters lead to a uniform 28 | distribution over model size. 29 | } 30 | \examples{ 31 | beta.binomial(1, 10) #' @family priors modelpriors 32 | } 33 | \seealso{ 34 | \code{\link{bas.lm}}, \code{\link{Bernoulli}},\code{\link{uniform}} 35 | 36 | Other priors modelpriors: 37 | \code{\link{Bernoulli}()}, 38 | \code{\link{Bernoulli.heredity}()}, 39 | \code{\link{tr.beta.binomial}()}, 40 | \code{\link{tr.poisson}()}, 41 | \code{\link{tr.power.prior}()}, 42 | \code{\link{uniform}()} 43 | } 44 | \author{ 45 | Merlise Clyde 46 | } 47 | \concept{priors modelpriors} 48 | -------------------------------------------------------------------------------- /man/Hald.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{Hald} 5 | \alias{Hald} 6 | \alias{hald} 7 | \title{Hald Data} 8 | \format{ 9 | \code{hald} is a dataframe with 13 observations and 5 variables 10 | (columns), 11 | 12 | Y: Heat evolved per gram of cement (in calories) X1: Amount of tricalcium 13 | aluminate X2: Amount of tricalcium silicate X3: Amount of tetracalcium 14 | alumino ferrite X4: Amount of dicalcium silicate 15 | } 16 | \source{ 17 | Wood, H., Steinour, H.H., and Starke, H.R. (1932). "Effect of 18 | Composition of Portland cement on Heat Evolved During Hardening", Industrial 19 | and Engineering Chemistry, 24, 1207-1214. 20 | } 21 | \description{ 22 | The Hald data have been used in many books and papers to illustrate variable 23 | selection. The data relate to an engineering application that was concerned 24 | with the effect of the composition of cement on heat evolved during 25 | hardening. The response variable \emph{Y} is the \emph{heat evolved} in a 26 | cement mix. The four explanatory variables are ingredients of the mix, X1: 27 | \emph{tricalcium aluminate}, X2: \emph{tricalcium silicate}, X3: 28 | \emph{tetracalcium alumino ferrite}, X4: \emph{dicalcium silicate}. An 29 | important feature of these data is that the variables X1 and X3 are highly 30 | correlated, as well as the variables X2 and X4. Thus we should expect any 31 | subset of (X1,X2,X3,X4) that includes one variable from highly correlated 32 | pair to do as any subset that also includes the other member. 33 | } 34 | \keyword{datasets} 35 | -------------------------------------------------------------------------------- /.github/workflows/check-standard.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, devel] 6 | pull_request: 7 | branches: [main, devel] 8 | 9 | name: R-CMD-check.yaml 10 | 11 | permissions: read-all 12 | 13 | jobs: 14 | R-CMD-check: 15 | runs-on: ${{ matrix.config.os }} 16 | 17 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 18 | 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | config: 23 | - {os: macos-latest, r: 'release'} 24 | - {os: windows-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'release'} 26 | - {os: ubuntu-latest, r: 'oldrel-1'} 27 | 28 | env: 29 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 30 | R_KEEP_PKG_SOURCE: yes 31 | 32 | steps: 33 | - uses: actions/checkout@v4 34 | 35 | - uses: r-lib/actions/setup-pandoc@v2 36 | 37 | - uses: r-lib/actions/setup-r@v2 38 | with: 39 | r-version: ${{ matrix.config.r }} 40 | http-user-agent: ${{ matrix.config.http-user-agent }} 41 | use-public-rspm: true 42 | 43 | - uses: r-lib/actions/setup-r-dependencies@v2 44 | with: 45 | extra-packages: any::rcmdcheck 46 | needs: check 47 | 48 | - uses: r-lib/actions/check-r-package@v2 49 | with: 50 | upload-snapshots: true 51 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' 52 | -------------------------------------------------------------------------------- /man/IC.prior.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/beta_priors.R 3 | \name{IC.prior} 4 | \alias{IC.prior} 5 | \alias{aic.prior} 6 | \alias{AIC.prior} 7 | \alias{bic.prior} 8 | \alias{BIC.prior} 9 | \title{Information Criterion Families of Prior Distribution for Coefficients in BMA 10 | Models} 11 | \usage{ 12 | IC.prior(penalty) 13 | } 14 | \arguments{ 15 | \item{penalty}{a scalar used in the penalized loglikelihood of the form 16 | penalty*dimension} 17 | } 18 | \value{ 19 | returns an object of class "prior", with the family and 20 | hyerparameters. 21 | } 22 | \description{ 23 | Creates an object representing the prior distribution on coefficients for 24 | BAS. 25 | } 26 | \details{ 27 | The log marginal likelihood is approximated as -2*(deviance + 28 | penalty*dimension). Allows alternatives to AIC (penalty = 2) and BIC 29 | (penalty = log(n)). For BIC, the argument may be missing, in which case the 30 | sample size is determined from the call to `bas.glm` and used to determine 31 | the penalty. 32 | } 33 | \examples{ 34 | IC.prior(2) 35 | aic.prior() 36 | bic.prior(100) 37 | } 38 | \seealso{ 39 | \code{\link{g.prior}} 40 | 41 | Other beta priors: 42 | \code{\link{CCH}()}, 43 | \code{\link{EB.local}()}, 44 | \code{\link{Jeffreys}()}, 45 | \code{\link{TG}()}, 46 | \code{\link{beta.prime}()}, 47 | \code{\link{g.prior}()}, 48 | \code{\link{hyper.g}()}, 49 | \code{\link{hyper.g.n}()}, 50 | \code{\link{intrinsic}()}, 51 | \code{\link{robust}()}, 52 | \code{\link{tCCH}()}, 53 | \code{\link{testBF.prior}()} 54 | } 55 | \author{ 56 | Merlise Clyde 57 | } 58 | \concept{beta priors} 59 | -------------------------------------------------------------------------------- /man/Bernoulli.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_priors.R 3 | \name{Bernoulli} 4 | \alias{Bernoulli} 5 | \alias{bernoulli} 6 | \title{Independent Bernoulli Prior Distribution for Models} 7 | \usage{ 8 | Bernoulli(probs = 0.5) 9 | } 10 | \arguments{ 11 | \item{probs}{a scalar or vector of prior inclusion probabilities. If a 12 | scalar, the values is replicated for all variables ans a 1 is added for the 13 | intercept. BAS checks to see if the length is equal to the dimension of the 14 | parameter vector for the full model and adds a 1 to include the intercept.} 15 | } 16 | \value{ 17 | returns an object of class "prior", with the family and 18 | hyperparameters. 19 | } 20 | \description{ 21 | Creates an object representing the prior distribution on models for BAS. 22 | } 23 | \details{ 24 | The independent Bernoulli prior distribution is a commonly used prior in 25 | BMA, with the Uniform distribution a special case with probs=.5. If all 26 | indicator variables have a independent Bernoulli distributions with common 27 | probability probs, the distribution on model size binomial(p, probs) 28 | distribution. 29 | } 30 | \examples{ 31 | Bernoulli(.9) 32 | } 33 | \seealso{ 34 | \code{\link{bas.lm}}, 35 | \code{\link{beta.binomial}},\code{\link{uniform} } 36 | 37 | Other priors modelpriors: 38 | \code{\link{Bernoulli.heredity}()}, 39 | \code{\link{beta.binomial}()}, 40 | \code{\link{tr.beta.binomial}()}, 41 | \code{\link{tr.poisson}()}, 42 | \code{\link{tr.power.prior}()}, 43 | \code{\link{uniform}()} 44 | } 45 | \author{ 46 | Merlise Clyde 47 | } 48 | \concept{priors modelpriors} 49 | -------------------------------------------------------------------------------- /man/CCH.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/beta_priors.R 3 | \name{CCH} 4 | \alias{CCH} 5 | \title{Generalized g-Prior Distribution for Coefficients in BMA Models} 6 | \usage{ 7 | CCH(alpha, beta, s = 0) 8 | } 9 | \arguments{ 10 | \item{alpha}{a scalar > 0, recommended alpha=.5 (betaprime) or 1 for CCH. 11 | The hyper.g(alpha) is equivalent to CCH(alpha -2, 2, 0). Liang et al 12 | recommended values in the range 2 < alpha_h <= 4} 13 | 14 | \item{beta}{a scalar > 0. The value is not updated by the data; beta should 15 | be a function of n for consistency under the null model. The hyper-g 16 | corresponds to b = 2} 17 | 18 | \item{s}{a scalar, recommended s=0} 19 | } 20 | \value{ 21 | returns an object of class "prior", with the family and 22 | hyperparameters. 23 | } 24 | \description{ 25 | Creates an object representing the CCH mixture of g-priors on coefficients 26 | for BAS . 27 | } 28 | \details{ 29 | Creates a structure used for \code{\link{bas.glm}}. 30 | } 31 | \examples{ 32 | CCH(alpha = .5, beta = 100, s = 0) 33 | } 34 | \seealso{ 35 | \code{\link{IC.prior}}, \code{\link{bic.prior}}, 36 | \code{\link{bas.glm}} 37 | 38 | Other beta priors: 39 | \code{\link{EB.local}()}, 40 | \code{\link{IC.prior}()}, 41 | \code{\link{Jeffreys}()}, 42 | \code{\link{TG}()}, 43 | \code{\link{beta.prime}()}, 44 | \code{\link{g.prior}()}, 45 | \code{\link{hyper.g}()}, 46 | \code{\link{hyper.g.n}()}, 47 | \code{\link{intrinsic}()}, 48 | \code{\link{robust}()}, 49 | \code{\link{tCCH}()}, 50 | \code{\link{testBF.prior}()} 51 | } 52 | \author{ 53 | Merlise A Clyde 54 | } 55 | \concept{beta priors} 56 | -------------------------------------------------------------------------------- /man/print.bas.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/summary.R 3 | \name{print.bas} 4 | \alias{print.bas} 5 | \alias{print} 6 | \title{Print a Summary of Bayesian Model Averaging objects from BAS} 7 | \usage{ 8 | \method{print}{bas}(x, digits = max(3L, getOption("digits") - 3L), ...) 9 | } 10 | \arguments{ 11 | \item{x}{object of class 'bas'} 12 | 13 | \item{digits}{optional number specifying the number of digits to display} 14 | 15 | \item{...}{other parameters to be passed to \code{print.default}} 16 | } 17 | \description{ 18 | \code{summary} and \code{print} methods for Bayesian model averaging objects 19 | created by \code{bas} Bayesian Adaptive Sampling 20 | } 21 | \details{ 22 | The print methods display a view similar to \code{print.lm} . The summary 23 | methods display a view specific to Bayesian model averaging giving the top 5 24 | highest probability models represented by their inclusion indicators. 25 | Summaries of the models include the Bayes Factor (BF) of each model to the 26 | model with the largest marginal likelihood, the posterior probability of the 27 | models, R2, dim (which includes the intercept) and the log of the marginal 28 | likelihood. 29 | } 30 | \examples{ 31 | 32 | library(MASS) 33 | data(UScrime) 34 | UScrime[, -2] <- log(UScrime[, -2]) 35 | crime.bic <- bas.lm(y ~ ., data = UScrime, n.models = 2^15, prior = "BIC", initprobs = "eplogp") 36 | print(crime.bic) 37 | summary(crime.bic) 38 | } 39 | \seealso{ 40 | \code{\link{coef.bas}} 41 | } 42 | \author{ 43 | Merlise Clyde \email{clyde@stat.duke.edu} 44 | } 45 | \keyword{print} 46 | \keyword{regression} 47 | -------------------------------------------------------------------------------- /man/climate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data.R 3 | \docType{data} 4 | \name{climate} 5 | \alias{climate} 6 | \title{Climate Data} 7 | \format{ 8 | Scientists are interested in the Earth's temperature change since the last 9 | glacial maximum, about 20,000 years ago. The first study to estimate the 10 | temperature change was published in 1980, and estimated a change of -1.5 degrees 11 | C, +/- 1.2 degrees C in tropical sea surface temperatures. 12 | The negative value means that the Earth was colder then than now. 13 | Since 1980 there have been many other studies. 14 | \code{climate} is a dataset with 63 measurements on 5 variables: 15 | \describe{\item{\emph{deltaT}}{ the response variables, which is the change in temperature 16 | in degrees Celsius;} 17 | \item{\emph{sdev}}{a standard deviation for the calculated \emph{deltaT};} 18 | \item{\emph{proxy}}{a number 1-8 reflecting which type of measurement system was used to derive 19 | deltaT. Some proxies can be used over land, others over water. 20 | The proxies are coded as\cr 21 | 1 "Mg/Ca" \cr 22 | 2 "alkenone" \cr 23 | 3 "Faunal" \cr 24 | 4 "Sr/Ca" \cr 25 | 5 "del 180" \cr 26 | 6 "Ice Core" \cr 27 | 7 "Pollen" \cr 28 | 8 "Noble Gas" \cr 29 | } 30 | \item{\emph{T/M}}{, an indicator of whether it was a terrestrial or marine study (T/M), 31 | which is coded as 0 for Terrestrial, 1 for Marine;} 32 | \item{ \emph{latitude}}{the latitude where the data were collected.}} 33 | } 34 | \source{ 35 | Data provided originally by Michael Lavine 36 | } 37 | \description{ 38 | Climate Data 39 | } 40 | -------------------------------------------------------------------------------- /man/tr.poisson.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_priors.R 3 | \name{tr.poisson} 4 | \alias{tr.poisson} 5 | \alias{tr.Poisson} 6 | \title{Truncated Poisson Prior Distribution for Models} 7 | \usage{ 8 | tr.poisson(lambda, trunc) 9 | } 10 | \arguments{ 11 | \item{lambda}{parameter in the Poisson distribution representing expected 12 | model size with infinite predictors} 13 | 14 | \item{trunc}{parameter that determines truncation in the distribution i.e. 15 | P(M; lambda, trunc) = 0 if M > trunc} 16 | } 17 | \value{ 18 | returns an object of class "prior", with the family and 19 | hyperparameters. 20 | } 21 | \description{ 22 | Creates an object representing the prior distribution on models for BAS 23 | using a truncated Poisson Distribution on the Model Size 24 | } 25 | \details{ 26 | The Poisson prior distribution on model size is obtained by assigning each 27 | variable inclusion indicator independent Bernoulli distributions with 28 | probability w, and then taking a limit as p goes to infinity and w goes to 29 | zero, such that p*w converges to lambda. The Truncated version assigns zero 30 | probability to all models of size M > trunc. 31 | } 32 | \examples{ 33 | tr.poisson(10, 50) 34 | } 35 | \seealso{ 36 | \code{\link{bas.lm}}, \code{\link{Bernoulli}},\code{\link{uniform}} 37 | 38 | Other priors modelpriors: 39 | \code{\link{Bernoulli}()}, 40 | \code{\link{Bernoulli.heredity}()}, 41 | \code{\link{beta.binomial}()}, 42 | \code{\link{tr.beta.binomial}()}, 43 | \code{\link{tr.power.prior}()}, 44 | \code{\link{uniform}()} 45 | } 46 | \author{ 47 | Merlise Clyde 48 | } 49 | \concept{priors modelpriors} 50 | -------------------------------------------------------------------------------- /man/hyper.g.n.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/beta_priors.R 3 | \name{hyper.g.n} 4 | \alias{hyper.g.n} 5 | \title{Generalized hyper-g/n Prior Distribution for g for mixtures of g-priors on 6 | Coefficients in BMA Models} 7 | \usage{ 8 | hyper.g.n(alpha = 3, n = NULL) 9 | } 10 | \arguments{ 11 | \item{alpha}{a scalar > 0, recommended 2 < alpha <= 3} 12 | 13 | \item{n}{The sample size; if NULL, the value derived from the data in the 14 | call to `bas.glm` will be used.} 15 | } 16 | \value{ 17 | returns an object of class "prior", with the family and 18 | hyerparameters. 19 | } 20 | \description{ 21 | Creates an object representing the hyper-g/n mixture of g-priors on 22 | coefficients for BAS. This is a special case of the tCCH prior 23 | } 24 | \details{ 25 | Creates a structure used for \code{\link{bas.glm}}. This is a special case 26 | of the \code{\link{tCCH}}, where \code{hyper.g.n(alpha=3, n)} is equivalent 27 | to \code{ tCCH(alpha=1, beta=2, s=0, r=1.5, v = 1, theta=1/n) } 28 | } 29 | \examples{ 30 | n <- 500 31 | hyper.g.n(alpha = 3, n = n) 32 | } 33 | \seealso{ 34 | \code{\link{tCCH}}, \code{\link{robust}}, \code{\link{hyper.g}}, 35 | \code{\link{CCH}}\code{\link{bas.glm}} 36 | 37 | Other beta priors: 38 | \code{\link{CCH}()}, 39 | \code{\link{EB.local}()}, 40 | \code{\link{IC.prior}()}, 41 | \code{\link{Jeffreys}()}, 42 | \code{\link{TG}()}, 43 | \code{\link{beta.prime}()}, 44 | \code{\link{g.prior}()}, 45 | \code{\link{hyper.g}()}, 46 | \code{\link{intrinsic}()}, 47 | \code{\link{robust}()}, 48 | \code{\link{tCCH}()}, 49 | \code{\link{testBF.prior}()} 50 | } 51 | \author{ 52 | Merlise Clyde 53 | } 54 | \concept{beta priors} 55 | -------------------------------------------------------------------------------- /tests/testthat/test-model_probabilities.R: -------------------------------------------------------------------------------- 1 | test_that("truncated priors normalization", { 2 | # Poisson 3 | # a function for log(1-exp(-x)) 4 | # based on Martin M\"{a}chler's work (https://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf) 5 | log1mexp = function(x, x0=log(2)) ifelse(x 0, recommended alpha=.5 (betaprime) or 1.} 11 | 12 | \item{beta}{a scalar > 0. The value is not updated by the data; beta should 13 | be a function of n for consistency under the null model.} 14 | 15 | \item{s}{a scalar, recommended s=0 a priori} 16 | 17 | \item{r}{r arbitrary; in the hyper-g-n prior sets r = (alpha + 2)} 18 | 19 | \item{v}{0 < v} 20 | 21 | \item{theta}{theta > 1} 22 | } 23 | \value{ 24 | returns an object of class "prior", with the family and 25 | hyerparameters. 26 | } 27 | \description{ 28 | Creates an object representing the tCCH mixture of g-priors on coefficients 29 | for BAS. 30 | } 31 | \details{ 32 | Creates a structure used for \code{\link{bas.glm}}. 33 | } 34 | \examples{ 35 | n <- 500 36 | tCCH(alpha = 1, beta = 2, s = 0, r = 1.5, v = 1, theta = 1 / n) 37 | } 38 | \seealso{ 39 | \code{\link{CCH}}, \code{\link{robust}}, \code{\link{hyper.g}}, 40 | \code{\link{hyper.g.n}}\code{\link{bas.glm}} 41 | 42 | Other beta priors: 43 | \code{\link{CCH}()}, 44 | \code{\link{EB.local}()}, 45 | \code{\link{IC.prior}()}, 46 | \code{\link{Jeffreys}()}, 47 | \code{\link{TG}()}, 48 | \code{\link{beta.prime}()}, 49 | \code{\link{g.prior}()}, 50 | \code{\link{hyper.g}()}, 51 | \code{\link{hyper.g.n}()}, 52 | \code{\link{intrinsic}()}, 53 | \code{\link{robust}()}, 54 | \code{\link{testBF.prior}()} 55 | } 56 | \author{ 57 | Merlise Clyde 58 | } 59 | \concept{beta priors} 60 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown.yml 13 | 14 | permissions: read-all 15 | 16 | jobs: 17 | pkgdown: 18 | runs-on: ubuntu-latest 19 | # Only restrict concurrency for non-PR jobs 20 | concurrency: 21 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 22 | env: 23 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 24 | permissions: 25 | contents: write 26 | steps: 27 | - uses: actions/checkout@v4 28 | 29 | - uses: r-lib/actions/setup-pandoc@v2 30 | 31 | - uses: quarto-dev/quarto-actions/setup@v2 32 | 33 | - uses: r-lib/actions/setup-r@v2 34 | with: 35 | use-public-rspm: true 36 | 37 | - uses: r-lib/actions/setup-r-dependencies@v2 38 | with: 39 | extra-packages: any::pkgdown, any::purrr, any::quarto, local::. 40 | needs: website 41 | 42 | - uses: r-lib/actions/setup-tinytex@v2 43 | 44 | 45 | 46 | - name: Build site 47 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 48 | shell: Rscript {0} 49 | 50 | - name: Deploy to GitHub pages 🚀 51 | if: github.event_name != 'pull_request' 52 | uses: JamesIves/github-pages-deploy-action@v4.4.1 53 | with: 54 | clean: false 55 | branch: gh-pages 56 | folder: docs 57 | -------------------------------------------------------------------------------- /man/EB.global.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/EB_global.R 3 | \name{EB.global} 4 | \alias{EB.global} 5 | \alias{EB.global.bas} 6 | \title{Find the global Empirical Bayes estimates for BMA} 7 | \usage{ 8 | EB.global(object, tol = 0.1, g.0 = NULL, max.iterations = 100) 9 | } 10 | \arguments{ 11 | \item{object}{A 'bas' object created by \code{\link{bas}}} 12 | 13 | \item{tol}{tolerance for estimating g} 14 | 15 | \item{g.0}{initial value for g} 16 | 17 | \item{max.iterations}{Maximum number of iterations for the EM algorithm} 18 | } 19 | \value{ 20 | An object of class 'bas' using Zellner's g prior with an estimate of 21 | g based on all models 22 | } 23 | \description{ 24 | Finds the global Empirical Bayes estimates of g in Zellner's g-prior and 25 | model probabilities 26 | } 27 | \details{ 28 | Uses the EM algorithm in Liang et al to estimate the type II MLE of g in 29 | Zellner's g prior 30 | } 31 | \examples{ 32 | 33 | library(MASS) 34 | data(UScrime) 35 | UScrime[,-2] = log(UScrime[,-2]) 36 | # EB local uses a different g within each model 37 | crime.EBL = bas.lm(y ~ ., data=UScrime, n.models=2^15, 38 | prior="EB-local", initprobs= "eplogp") 39 | # use a common (global) estimate of g 40 | crime.EBG = EB.global(crime.EBL) 41 | 42 | 43 | } 44 | \references{ 45 | Liang, F., Paulo, R., Molina, G., Clyde, M. and Berger, J.O. 46 | (2008) Mixtures of g-priors for Bayesian Variable Selection. Journal of the 47 | American Statistical Association. 103:410-423. \cr 48 | \doi{10.1198/016214507000001337} 49 | } 50 | \seealso{ 51 | \code{\link{bas}}, \code{\link{update}} 52 | } 53 | \author{ 54 | Merlise Clyde \email{clyde@stat.duke.edu} 55 | } 56 | \concept{coef priors} 57 | \keyword{regression} 58 | -------------------------------------------------------------------------------- /man/tr.power.prior.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_priors.R 3 | \name{tr.power.prior} 4 | \alias{tr.power.prior} 5 | \alias{tr.Power.Prior} 6 | \title{Truncated Power Prior Distribution for Models} 7 | \usage{ 8 | tr.power.prior(kappa = 2, trunc) 9 | } 10 | \arguments{ 11 | \item{kappa}{parameter in the prior distribution that controls sparsity} 12 | 13 | \item{trunc}{parameter that determines truncation in the distribution i.e. 14 | P(gamma; alpha, beta, trunc) = 0 if |gamma| > trunc.} 15 | } 16 | \value{ 17 | returns an object of class "prior", with the family and 18 | hyperparameters. 19 | } 20 | \description{ 21 | Creates an object representing the prior distribution on models for BAS 22 | using a truncated Distribution on the Model Size where the probability of 23 | gamma proportional to p^-kappa |gamma| where gamma is the vector of model indicators 24 | and |gamma| is the model size. 25 | } 26 | \details{ 27 | The Truncated version 28 | assigns zero probability to all models of size > trunc. 29 | } 30 | \examples{ 31 | 32 | tr.power.prior(2, 8) 33 | library(MASS) 34 | data(UScrime) 35 | UScrime[, -2] <- log(UScrime[, -2]) 36 | crime.bic <- bas.lm(y ~ ., 37 | data = UScrime, n.models = 2^15, prior = "BIC", 38 | modelprior = tr.power.prior(2, 8), 39 | initprobs = "eplogp" 40 | ) 41 | } 42 | \seealso{ 43 | \code{\link{bas.lm}}, \code{\link{Bernoulli}},\code{\link{uniform}} 44 | 45 | Other priors modelpriors: 46 | \code{\link{Bernoulli}()}, 47 | \code{\link{Bernoulli.heredity}()}, 48 | \code{\link{beta.binomial}()}, 49 | \code{\link{tr.beta.binomial}()}, 50 | \code{\link{tr.poisson}()}, 51 | \code{\link{uniform}()} 52 | } 53 | \author{ 54 | Merlise Clyde 55 | } 56 | \concept{priors modelpriors} 57 | -------------------------------------------------------------------------------- /tests/testthat/test-family.R: -------------------------------------------------------------------------------- 1 | context("bas.glm") 2 | 3 | # issue #92 4 | # 5 | test_that("family links", { 6 | data(Pima.tr, package="MASS") 7 | expect_error(bas.glm(type ~ ., 8 | data = Pima.tr, method = "BAS", 9 | betaprior = bic.prior(), family = binomial(link = "inverse"), 10 | modelprior = uniform()) 11 | ) 12 | data(crabs, package = "glmbb") 13 | expect_error(crabs.bas <- bas.glm(satell ~ color * spine * width + weight, 14 | data = crabs, 15 | family = poisson(link="logit"), 16 | betaprior = EB.local(), modelprior = uniform(), 17 | method = "MCMC", n.models = 1024, MCMC.iterations = 1000 18 | )) 19 | expect_error(crabs.bas <- bas.glm(satell ~ color * spine * width + weight, 20 | data = crabs, 21 | family = poisson(link="identity"), 22 | betaprior = EB.local(), modelprior = uniform(), 23 | method = "MCMC", n.models = 1024, MCMC.iterations = 1000 24 | )) 25 | data(wafer, package="faraway") 26 | expect_error(bas.glm(formula = resist ~ ., include.always = ~ ., 27 | betaprior = bic.prior() , 28 | family = Gamma(link = "identity"), 29 | data = wafer)) 30 | expect_error(bas.glm(formula = resist ~ ., include.always = ~ ., 31 | betaprior = bic.prior() , 32 | family = gaussian(link = "identity"), 33 | data = wafer)) 34 | }) 35 | -------------------------------------------------------------------------------- /man/cv.summary.bas.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cv_summary.R 3 | \name{cv.summary.bas} 4 | \alias{cv.summary.bas} 5 | \title{Summaries for Out of Sample Prediction} 6 | \usage{ 7 | cv.summary.bas(pred, ytrue, score = "squared-error") 8 | } 9 | \arguments{ 10 | \item{pred}{fitted or predicted value from the output from 11 | \code{\link{predict.bas}}} 12 | 13 | \item{ytrue}{vector of left out response values} 14 | 15 | \item{score}{function used to summarize error rate. Either "squared-error", 16 | or "miss-class"} 17 | } 18 | \value{ 19 | For squared error, the average prediction error for the Bayesian 20 | estimator error = sqrt(sum(ytrue - yhat)^2/npred) while for binary data the 21 | misclassification rate is more appropriate. 22 | } 23 | \description{ 24 | Compute average prediction error from out of sample predictions 25 | } 26 | \examples{ 27 | 28 | \dontrun{ 29 | library(foreign) 30 | cognitive <- read.dta("https://www.stat.columbia.edu/~gelman/arm/examples/child.iq/kidiq.dta") 31 | cognitive$mom_work <- as.numeric(cognitive$mom_work > 1) 32 | cognitive$mom_hs <- as.numeric(cognitive$mom_hs > 0) 33 | colnames(cognitive) <- c("kid_score", "hs", "iq", "work", "age") 34 | 35 | set.seed(42) 36 | n <- nrow(cognitive) 37 | test <- sample(1:n, size = round(.20 * n), replace = FALSE) 38 | testdata <- cognitive[test, ] 39 | traindata <- cognitive[-test, ] 40 | cog_train <- bas.lm(kid_score ~ ., prior = "BIC", modelprior = uniform(), data = traindata) 41 | yhat <- predict(cog_train, newdata = testdata, estimator = "BMA", se = F) 42 | cv.summary.bas(yhat$fit, testdata$kid_score) 43 | } 44 | } 45 | \seealso{ 46 | \code{\link{predict.bas}} 47 | } 48 | \author{ 49 | Merlise Clyde \email{clyde@duke.edu} 50 | } 51 | \keyword{regression} 52 | -------------------------------------------------------------------------------- /revdep/README.md: -------------------------------------------------------------------------------- 1 | # Platform 2 | 3 | |field |value | 4 | |:--------|:--------------------------------------------------------------------------------------------------| 5 | |version |R version 4.5.2 (2025-10-31) | 6 | |os |macOS Sequoia 15.7.3 | 7 | |system |aarch64, darwin20 | 8 | |ui |RStudio | 9 | |language |(EN) | 10 | |collate |en_US.UTF-8 | 11 | |ctype |en_US.UTF-8 | 12 | |tz |America/New_York | 13 | |date |2025-12-18 | 14 | |rstudio |2025.09.2+418 Cucumberleaf Sunflower (desktop) | 15 | |pandoc |3.6.3 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/aarch64/ (via rmarkdown) | 16 | |quarto |1.6.32 @ /usr/local/bin/quarto | 17 | 18 | # Dependencies 19 | 20 | |package |old |new |Δ | 21 | |:-------|:-----|:-----|:--| 22 | |BAS |2.0.0 |2.0.0 |NA | 23 | 24 | # Revdeps 25 | 26 | -------------------------------------------------------------------------------- /tests/testthat/test-bas-amcmc.R: -------------------------------------------------------------------------------- 1 | context("AMCMC bas.lm") 2 | 3 | test_that("AMCMC VS MCMC with no adaptation", { 4 | data(Hald) 5 | set.seed(42) 6 | hald.mcmc = bas.lm(Y ~ ., prior = "ZS-null", modelprior = uniform(), 7 | data = Hald, method = "MCMC", burnin.iteration = 200, MCMC.iterations = 0) 8 | set.seed(42) 9 | hald.amcmc = bas.lm(Y ~ ., prior = "ZS-null", modelprior = uniform(), 10 | data = Hald, method = "AMCMC", burnin.iteration = 200, MCMC.iterations = 0, 11 | GROW = FALSE) 12 | expect_equal(hald.amcmc$postprobs.MCMC, hald.mcmc$postprobs.MCMC) 13 | expect_equal(hald.amcmc$postprobs.MCMC, hald.mcmc$postprobs.MCMC) 14 | expect_equal(hald.amcmc$n.models, hald.mcmc$n.models) 15 | expect_equal(hald.amcmc$logmarg, hald.mcmc$logmarg) 16 | expect_equal(hald.amcmc$freq, hald.mcmc$freq) 17 | 18 | }) 19 | 20 | # Issue #91 remove calls to SETLENGTH by adding GROWABLE vectors 21 | test_that("AMCMC VS MCMC with no adaptation", { 22 | data(Hald) 23 | set.seed(42) 24 | hald.mcmc = bas.lm(Y ~ ., prior = "ZS-null", modelprior = uniform(), 25 | data = Hald, method = "MCMC", burnin.iteration = 200, MCMC.iterations = 0) 26 | set.seed(42) 27 | hald.amcmc = bas.lm(Y ~ ., prior = "ZS-null", modelprior = uniform(), 28 | data = Hald, method = "AMCMC", burnin.iteration = 200, MCMC.iterations = 0, 29 | GROW = TRUE) 30 | expect_equal(hald.amcmc$postprobs.MCMC, hald.mcmc$postprobs.MCMC) 31 | expect_equal(hald.amcmc$postprobs.MCMC, hald.mcmc$postprobs.MCMC) 32 | expect_equal(hald.amcmc$n.models, hald.mcmc$n.models) 33 | expect_equal(hald.amcmc$logmarg, hald.mcmc$logmarg) 34 | expect_equal(hald.amcmc$freq, hald.mcmc$freq) 35 | 36 | }) 37 | -------------------------------------------------------------------------------- /man/list2matrix.which.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/as_matrix.R 3 | \name{list2matrix.which} 4 | \alias{list2matrix.which} 5 | \title{Coerce a BAS list object into a matrix.} 6 | \usage{ 7 | list2matrix.which(x, which.models = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{a 'bas' object} 11 | 12 | \item{which.models}{a vector of indices use to extract a subset} 13 | } 14 | \value{ 15 | a matrix representation of \code{x$what}, with number of rows equal 16 | to the length of which.models or total number of models and number of 17 | columns \code{x$n.vars} 18 | } 19 | \description{ 20 | Models, coefficients, and standard errors in objects of class 'bas' are 21 | represented as a list of lists to reduce storage by omitting the zero 22 | entries. These functions coerce the list object to a matrix and fill in the 23 | zeros to facilitate other computations. 24 | } 25 | \details{ 26 | \code{list2matrix.bas(x, which)} is equivalent to 27 | \code{list2matrix.which(x)}, however, the latter uses sapply rather than a 28 | loop. 29 | \code{list2matrix.which} and \code{which.matrix} both coerce 30 | \code{x$which} into a matrix. 31 | } 32 | \examples{ 33 | 34 | data(Hald) 35 | Hald.bic <- bas.lm(Y ~ ., data=Hald, prior="BIC", initprobs="eplogp") 36 | coef <- list2matrix.bas(Hald.bic, "mle") # extract all ols coefficients 37 | se <- list2matrix.bas(Hald.bic, "mle.se") 38 | models <- list2matrix.which(Hald.bic) #matrix of model indicators 39 | models <- which.matrix(Hald.bic$which, Hald.bic$n.vars) #matrix of model indicators 40 | 41 | } 42 | \seealso{ 43 | \code{\link{bas}} 44 | 45 | Other as.matrix methods: 46 | \code{\link{list2matrix.bas}()}, 47 | \code{\link{which.matrix}()} 48 | } 49 | \author{ 50 | Merlise Clyde \email{clyde@duke.edu} 51 | } 52 | \concept{as.matrix methods} 53 | \keyword{regression} 54 | -------------------------------------------------------------------------------- /man/intrinsic.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/beta_priors.R 3 | \name{intrinsic} 4 | \alias{intrinsic} 5 | \title{Intrinsic Prior Distribution for Coefficients in BMA Models} 6 | \usage{ 7 | intrinsic(n = NULL) 8 | } 9 | \arguments{ 10 | \item{n}{the sample size; if NULL, the value derived from the data in the 11 | call to `bas.glm` will be used.} 12 | } 13 | \value{ 14 | returns an object of class "prior", with the family "intrinsic" of 15 | class "TCCH" and hyperparameters alpha = 1, beta = 1, s = 0, r = 1, n = n 16 | for the tCCH prior where theta in the tCCH prior is determined by the model 17 | size and sample size. 18 | } 19 | \description{ 20 | Creates an object representing the intrinsic prior on g, a special case of 21 | the tCCH mixture of g-priors on coefficients for BAS. 22 | } 23 | \details{ 24 | Creates a structure used for \code{\link{bas.glm}}. 25 | } 26 | \examples{ 27 | n <- 500 28 | tCCH(alpha = 1, beta = 2, s = 0, r = 1.5, v = 1, theta = 1 / n) 29 | } 30 | \references{ 31 | Womack, A., Novelo,L.L., Casella, G. (2014). "Inference From 32 | Intrinsic Bayes' Procedures Under Model Selection and Uncertainty". Journal 33 | of the American Statistical Association. 109:1040-1053. 34 | \doi{10.1080/01621459.2014.880348} 35 | } 36 | \seealso{ 37 | \code{\link{tCCH}}, \code{\link{robust}}, \code{\link{hyper.g}}, 38 | \code{\link{hyper.g.n}}\code{\link{bas.glm}} 39 | 40 | Other beta priors: 41 | \code{\link{CCH}()}, 42 | \code{\link{EB.local}()}, 43 | \code{\link{IC.prior}()}, 44 | \code{\link{Jeffreys}()}, 45 | \code{\link{TG}()}, 46 | \code{\link{beta.prime}()}, 47 | \code{\link{g.prior}()}, 48 | \code{\link{hyper.g}()}, 49 | \code{\link{hyper.g.n}()}, 50 | \code{\link{robust}()}, 51 | \code{\link{tCCH}()}, 52 | \code{\link{testBF.prior}()} 53 | } 54 | \author{ 55 | Merlise A Clyde 56 | } 57 | \concept{beta priors} 58 | -------------------------------------------------------------------------------- /man/list2matrix.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/as_matrix.R 3 | \name{list2matrix.bas} 4 | \alias{list2matrix.bas} 5 | \alias{list2matrix} 6 | \title{Coerce a BAS list object into a matrix.} 7 | \usage{ 8 | list2matrix.bas(x, what, which.models = NULL) 9 | } 10 | \arguments{ 11 | \item{x}{a 'bas' object} 12 | 13 | \item{what}{name of bas list to coerce} 14 | 15 | \item{which.models}{a vector of indices use to extract a subset} 16 | } 17 | \value{ 18 | a matrix representation of \code{x$what}, with number of rows equal 19 | to the length of which.models or total number of models and number of 20 | columns \code{x$n.vars} 21 | } 22 | \description{ 23 | Models, coefficients, and standard errors in objects of class 'bas' are 24 | represented as a list of lists to reduce storage by omitting the zero 25 | entries. These functions coerce the list object to a matrix and fill in the 26 | zeros to facilitate other computations. 27 | } 28 | \details{ 29 | \code{list2matrix.bas(x, which)} is equivalent to 30 | \code{list2matrix.which(x)}, however, the latter uses sapply rather than a 31 | loop. 32 | \code{list2matrix.which} and \code{which.matrix} both coerce 33 | \code{x$which} into a matrix. 34 | } 35 | \examples{ 36 | 37 | data(Hald) 38 | hald.bic <- bas.lm(Y ~ ., data=Hald, prior="BIC", 39 | initprobs= "eplogp") 40 | coef <- list2matrix.bas(hald.bic, "mle") # extract all coefficients 41 | se <- list2matrix.bas(hald.bic, "mle.se") 42 | models <- list2matrix.which(hald.bic) #matrix of model indicators 43 | models <- which.matrix(hald.bic$which, hald.bic$n.vars) #matrix of model indicators 44 | 45 | } 46 | \seealso{ 47 | \code{\link{bas}} 48 | 49 | Other as.matrix methods: 50 | \code{\link{list2matrix.which}()}, 51 | \code{\link{which.matrix}()} 52 | } 53 | \author{ 54 | Merlise Clyde \email{clyde@duke.edu} 55 | } 56 | \concept{as.matrix methods} 57 | \keyword{regression} 58 | -------------------------------------------------------------------------------- /man/variable.names.pred.bas.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/predict.R 3 | \name{variable.names.pred.bas} 4 | \alias{variable.names.pred.bas} 5 | \alias{variable.names} 6 | \title{Extract the variable names for a model from a BAS prediction object} 7 | \usage{ 8 | \method{variable.names}{pred.bas}(object, ...) 9 | } 10 | \arguments{ 11 | \item{object}{a BAS object created by \code{predict} from a BAS 12 | `bas.lm` or `bas.glm` object} 13 | 14 | \item{...}{other arguments to pass on} 15 | } 16 | \value{ 17 | a character vector with the names of the variables 18 | included in the selected model; in the case of 'BMA' this will 19 | be all variables 20 | } 21 | \description{ 22 | S3 method for class 'pred.bas'. Simple utility 23 | function to extract the variable names. Used to print names 24 | for the selected models using estimators for 'HPM', 'MPM' or 'BPM". 25 | for the selected model created by \code{predict} for BAS 26 | objects. 27 | } 28 | \examples{ 29 | data(Hald) 30 | hald.gprior = bas.lm(Y~ ., data=Hald, prior="ZS-null", modelprior=uniform()) 31 | hald.bpm = predict(hald.gprior, newdata=Hald[1,], 32 | se.fit=TRUE, 33 | estimator="BPM") 34 | variable.names(hald.bpm) 35 | } 36 | \seealso{ 37 | \code{\link{predict.bas}} 38 | 39 | Other predict methods: 40 | \code{\link{fitted.bas}()}, 41 | \code{\link{predict.bas}()}, 42 | \code{\link{predict.basglm}()} 43 | 44 | Other bas methods: 45 | \code{\link{BAS}}, 46 | \code{\link{bas.lm}()}, 47 | \code{\link{coef.bas}()}, 48 | \code{\link{confint.coef.bas}()}, 49 | \code{\link{confint.pred.bas}()}, 50 | \code{\link{diagnostics}()}, 51 | \code{\link{fitted.bas}()}, 52 | \code{\link{force.heredity.bas}()}, 53 | \code{\link{image.bas}()}, 54 | \code{\link{plot.confint.bas}()}, 55 | \code{\link{predict.bas}()}, 56 | \code{\link{predict.basglm}()}, 57 | \code{\link{summary.bas}()}, 58 | \code{\link{update.bas}()} 59 | } 60 | \concept{bas methods} 61 | \concept{predict methods} 62 | -------------------------------------------------------------------------------- /man/Bayes.outlier.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/outliers.R 3 | \name{Bayes.outlier} 4 | \alias{Bayes.outlier} 5 | \title{Bayesian Outlier Detection} 6 | \usage{ 7 | Bayes.outlier(lmobj, k, prior.prob) 8 | } 9 | \arguments{ 10 | \item{lmobj}{An object of class `lm`} 11 | 12 | \item{k}{number of standard deviations used in calculating 13 | probability of an individual case being an outlier, 14 | P(|error| > k sigma | data)} 15 | 16 | \item{prior.prob}{The prior probability of there being no 17 | outliers in the sample of size n} 18 | } 19 | \value{ 20 | Returns a list of three items: 21 | \item{e}{residuals} 22 | \item{hat}{leverage values} 23 | \item{prob.outlier}{posterior probabilities of a point being an outlier} 24 | \item{prior.prob}{prior probability of a point being an outlier} 25 | } 26 | \description{ 27 | Calculate the posterior probability that the absolute value of 28 | error exceeds more than k standard deviations 29 | P(|epsilon_j| > k sigma | data) 30 | under the model Y = X B + epsilon, 31 | with epsilon ~ N(0, sigma^2 I) 32 | based on the paper 33 | by Chaloner & Brant Biometrika (1988). Either k or the prior 34 | probability of there being no outliers must be provided. 35 | This only uses the reference prior p(B, sigma) = 1; 36 | other priors and model averaging to come. 37 | } 38 | \examples{ 39 | data("stackloss") 40 | stack.lm <- lm(stack.loss ~ ., data = stackloss) 41 | stack.outliers <- Bayes.outlier(stack.lm, k = 3) 42 | plot(stack.outliers$prob.outlier, type = "h", ylab = "Posterior Probability") 43 | # adjust for sample size for calculating prior prob that a 44 | # a case is an outlier 45 | stack.outliers <- Bayes.outlier(stack.lm, prior.prob = 0.95) 46 | # cases where posterior probability exceeds prior probability 47 | which(stack.outliers$prob.outlier > stack.outliers$prior.prob) 48 | } 49 | \references{ 50 | Chaloner & Brant (1988) 51 | A Bayesian Approach to Outlier Detection and Residual Analysis 52 | Biometrika (1988) 75, 651-659 53 | } 54 | -------------------------------------------------------------------------------- /man/hypergeometric2F1.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/hypergeometric2F1.R 3 | \name{hypergeometric2F1} 4 | \alias{hypergeometric2F1} 5 | \title{Gaussian hypergeometric2F1 function} 6 | \usage{ 7 | hypergeometric2F1(a, b, c, z, method = "Cephes", log = TRUE) 8 | } 9 | \arguments{ 10 | \item{a}{arbitrary} 11 | 12 | \item{b}{Must be greater 0} 13 | 14 | \item{c}{Must be greater than b if |z| < 1, and c > b + a if z = 1} 15 | 16 | \item{z}{|z| <= 1} 17 | 18 | \item{method}{The default is to use the Cephes library routine. This 19 | sometimes is unstable for large a or z near one returning Inf or negative 20 | values. In this case, try method="Laplace", which use a Laplace 21 | approximation for tau = exp(t/(1-t)).} 22 | 23 | \item{log}{if TRUE, return log(2F1)} 24 | } 25 | \value{ 26 | if log=T returns the log of the 2F1 function; otherwise the 2F1 27 | function. 28 | } 29 | \description{ 30 | Compute the Gaussian Hypergeometric2F1 function: 2F1(a,b,c,z) = Gamma(b-c) 31 | Int_0^1 t^(b-1) (1 - t)^(c -b -1) (1 - t z)^(-a) dt 32 | } 33 | \details{ 34 | The default is to use the routine hyp2f1.c from the Cephes library. If that 35 | return a negative value or Inf, one should try method="Laplace" which is 36 | based on the Laplace approximation as described in Liang et al JASA 2008. 37 | This is used in the hyper-g prior to calculate marginal likelihoods. 38 | } 39 | \examples{ 40 | hypergeometric2F1(12, 1, 2, .65) 41 | } 42 | \references{ 43 | Cephes library hyp2f1.c 44 | 45 | Liang, F., Paulo, R., Molina, G., Clyde, M. and Berger, J.O. (2005) Mixtures 46 | of g-priors for Bayesian Variable Selection. Journal of the American 47 | Statistical Association. 103:410-423. \cr 48 | \doi{10.1198/016214507000001337} 49 | } 50 | \seealso{ 51 | Other special functions: 52 | \code{\link{hypergeometric1F1}()}, 53 | \code{\link{phi1}()}, 54 | \code{\link{trCCH}()} 55 | } 56 | \author{ 57 | Merlise Clyde (\email{clyde@duke.edu}) 58 | } 59 | \concept{special functions} 60 | \keyword{math} 61 | -------------------------------------------------------------------------------- /man/tr.beta.binomial.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/model_priors.R 3 | \name{tr.beta.binomial} 4 | \alias{tr.beta.binomial} 5 | \alias{tr.Beta.Binomial} 6 | \title{Truncated Beta-Binomial Prior Distribution for Models} 7 | \usage{ 8 | tr.beta.binomial(alpha = 1, beta = 1, trunc) 9 | } 10 | \arguments{ 11 | \item{alpha}{parameter in the beta prior distribution} 12 | 13 | \item{beta}{parameter in the beta prior distribution} 14 | 15 | \item{trunc}{parameter that determines truncation in the distribution i.e. 16 | P(M; alpha, beta, trunc) = 0 if M > trunc.} 17 | } 18 | \value{ 19 | returns an object of class "prior", with the family and 20 | hyperparameters. 21 | } 22 | \description{ 23 | Creates an object representing the prior distribution on models for BAS 24 | using a truncated Beta-Binomial Distribution on the Model Size 25 | } 26 | \details{ 27 | The beta-binomial distribution on model size is obtained by assigning each 28 | variable inclusion indicator independent Bernoulli distributions with 29 | probability w, and then giving w a beta(alpha,beta) distribution. 30 | Marginalizing over w leads to the number of included 31 | predictors having a beta-binomial distribution. The default hyperparameters 32 | lead to a uniform distribution over model size. The Truncated version 33 | assigns zero probability to all models of size > trunc. 34 | } 35 | \examples{ 36 | 37 | tr.beta.binomial(1, 10, 5) 38 | library(MASS) 39 | data(UScrime) 40 | UScrime[, -2] <- log(UScrime[, -2]) 41 | crime.bic <- bas.lm(y ~ ., 42 | data = UScrime, n.models = 2^15, prior = "BIC", 43 | modelprior = tr.beta.binomial(1, 1, 8), 44 | initprobs = "eplogp" 45 | ) 46 | } 47 | \seealso{ 48 | \code{\link{bas.lm}}, \code{\link{Bernoulli}},\code{\link{uniform}} 49 | 50 | Other priors modelpriors: 51 | \code{\link{Bernoulli}()}, 52 | \code{\link{Bernoulli.heredity}()}, 53 | \code{\link{beta.binomial}()}, 54 | \code{\link{tr.poisson}()}, 55 | \code{\link{tr.power.prior}()}, 56 | \code{\link{uniform}()} 57 | } 58 | \author{ 59 | Merlise Clyde 60 | } 61 | \concept{priors modelpriors} 62 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master, devel] 6 | pull_request: 7 | 8 | name: test-coverage.yaml 9 | 10 | permissions: read-all 11 | 12 | jobs: 13 | test-coverage: 14 | runs-on: ubuntu-latest 15 | env: 16 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - uses: r-lib/actions/setup-r@v2 22 | with: 23 | use-public-rspm: true 24 | 25 | - uses: r-lib/actions/setup-r-dependencies@v2 26 | with: 27 | extra-packages: any::covr, any::xml2 28 | needs: coverage 29 | 30 | - name: Test coverage 31 | run: | 32 | cov <- covr::package_coverage( 33 | quiet = FALSE, 34 | clean = FALSE, 35 | install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") 36 | ) 37 | covr::to_cobertura(cov) 38 | shell: Rscript {0} 39 | 40 | - uses: codecov/codecov-action@f1b7348826d750ac29741abc9d1623d8da5dcd4f 41 | with: 42 | # Fail if error if not on PR, or if on PR and token is given 43 | fail_ci_if_error: ${{ github.event_name != 'pull_request' || secrets.CODECOV_TOKEN }} 44 | file: ./cobertura.xml 45 | plugin: noop 46 | disable_search: true 47 | token: ${{ secrets.CODECOV_TOKEN }} 48 | 49 | - name: Show testthat output 50 | if: always() 51 | run: | 52 | ## -------------------------------------------------------------------- 53 | find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true 54 | shell: bash 55 | 56 | - name: Upload test results 57 | if: failure() 58 | uses: actions/upload-artifact@v4 59 | with: 60 | name: coverage-test-failures 61 | path: ${{ runner.temp }}/package 62 | -------------------------------------------------------------------------------- /man/summary.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/summary.R 3 | \name{summary.bas} 4 | \alias{summary.bas} 5 | \alias{summary} 6 | \title{Summaries of Bayesian Model Averaging objects from BAS} 7 | \usage{ 8 | \method{summary}{bas}(object, n.models = 5, ...) 9 | } 10 | \arguments{ 11 | \item{object}{object of class 'bas'} 12 | 13 | \item{n.models}{optional number specifying the number of best models to 14 | display in summary} 15 | 16 | \item{...}{other parameters to be passed to \code{summary.default}} 17 | } 18 | \description{ 19 | \code{summary} and \code{print} methods for Bayesian model averaging objects 20 | created by \code{bas} Bayesian Adaptive Sampling 21 | } 22 | \details{ 23 | The print methods display a view similar to \code{print.lm} . The summary 24 | methods display a view specific to Bayesian model averaging giving the top 5 25 | highest probability models represented by their inclusion indicators. 26 | Summaries of the models include the Bayes Factor (BF) of each model to the 27 | model with the largest marginal likelihood, the posterior probability of the 28 | models, R2, dim (which includes the intercept) and the log of the marginal 29 | likelihood. 30 | } 31 | \examples{ 32 | data(UScrime, package = "MASS") 33 | UScrime[, -2] <- log(UScrime[, -2]) 34 | crime.bic <- bas.lm(y ~ ., data = UScrime, n.models = 2^15, prior = "BIC", initprobs = "eplogp") 35 | print(crime.bic) 36 | summary(crime.bic) 37 | } 38 | \seealso{ 39 | \code{\link{coef.bas}} 40 | 41 | Other bas methods: 42 | \code{\link{BAS}}, 43 | \code{\link{bas.lm}()}, 44 | \code{\link{coef.bas}()}, 45 | \code{\link{confint.coef.bas}()}, 46 | \code{\link{confint.pred.bas}()}, 47 | \code{\link{diagnostics}()}, 48 | \code{\link{fitted.bas}()}, 49 | \code{\link{force.heredity.bas}()}, 50 | \code{\link{image.bas}()}, 51 | \code{\link{plot.confint.bas}()}, 52 | \code{\link{predict.bas}()}, 53 | \code{\link{predict.basglm}()}, 54 | \code{\link{update.bas}()}, 55 | \code{\link{variable.names.pred.bas}()} 56 | } 57 | \author{ 58 | Merlise Clyde \email{clyde@duke.edu} 59 | } 60 | \concept{bas methods} 61 | \keyword{print} 62 | \keyword{regression} 63 | -------------------------------------------------------------------------------- /tests/testthat/test-model-priors.R: -------------------------------------------------------------------------------- 1 | context("model priors") 2 | 3 | test_that("bernoulli", { 4 | data(Hald) 5 | hald_unif <- bas.lm(Y ~ ., 6 | data = Hald, prior = "g-prior", 7 | modelprior = uniform() 8 | ) 9 | hald_ber <- bas.lm(Y ~ ., 10 | data = Hald, prior = "g-prior", 11 | modelprior = Bernoulli(probs = .5) 12 | ) 13 | expect_equal(hald_unif$probne0, hald_ber$probne0) 14 | hald_ber1 <- bas.lm(Y ~ ., 15 | data = Hald, prior = "g-prior", 16 | modelprior = Bernoulli(probs = .4) 17 | ) 18 | hald_ber2 <- bas.lm(Y ~ X1 + X2 + X3 + X4, 19 | data = Hald, prior = "g-prior", 20 | modelprior = Bernoulli(probs = rep(.4, 4)) 21 | ) 22 | expect_equal(hald_ber1$probne0, hald_ber2$probne0) 23 | }) 24 | 25 | test_that("truncated prior", { 26 | hald_tr_power <- bas.lm(Y ~ ., 27 | data = Hald, prior = "g-prior", 28 | modelprior = tr.power.prior(kappa=2, 2)) 29 | expect_equal(1, sum(hald_tr_power$postprobs)) 30 | expect_no_error(expect_equal(0, sum(hald_tr_power$postprobs <= 0.0))) 31 | 32 | }) 33 | 34 | test_that("Bernoulli hereditary prior", { 35 | expect_error(bas.lm(Y ~ ., 36 | data = Hald, prior = "g-prior", 37 | modelprior = Bernoulli.heredity(.5, NULL)) 38 | ) 39 | }) 40 | 41 | test_that("Always include changes model-prior", { 42 | 43 | res <- bas.lm(Y ~ ., data = Hald, modelprior = beta.binomial(1, 1), 44 | include.always = ~ 1 + X1 + X2) 45 | ord <- order(lengths(res$which)) 46 | expect_equal( 47 | object = res$priorprobs[ord], 48 | expected = c(0.333333333333333, 0.166666666666667, 0.166666666666667, 0.333333333333333) 49 | ) 50 | }) 51 | 52 | test_that("Check if model-prior is of class prior", { 53 | 54 | expect_error(bas.lm(Y ~ ., data = Hald, modelprior = c(.25, .25, .25, .25), 55 | include.always = ~ 1 + X1 + X2)) 56 | 57 | expect_error(bas.glm(Y ~ ., data = Hald, modelprior = c(.25, .25, .25, .25), 58 | include.always = ~ 1 + X1 + X2, family=poisson())) 59 | }) 60 | -------------------------------------------------------------------------------- /src/dch1up.f: -------------------------------------------------------------------------------- 1 | c Copyright (C) 2008, 2009 VZLU Prague, a.s., Czech Republic 2 | c 3 | c Author: Jaroslav Hajek 4 | c 5 | c This file is part of qrupdate. 6 | c 7 | c qrupdate is free software; you can redistribute it and/or modify 8 | c it under the terms of the GNU General Public License as published by 9 | c the Free Software Foundation; either version 3 of the License, or 10 | c (at your option) any later version. 11 | c 12 | c This program is distributed in the hope that it will be useful, 13 | c but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | c GNU General Public License for more details. 16 | c 17 | c You should have received a copy of the GNU General Public License 18 | c along with this software; see the file COPYING. If not, see 19 | c . 20 | c 21 | subroutine dch1up(n,R,ldr,u,w) 22 | c purpose: given an upper triangular matrix R that is a Cholesky 23 | c factor of a symmetric positive definite matrix A, i.e. 24 | c A = R'*R, this subroutine updates R -> R1 so that 25 | c R1'*R1 = A + u*u' 26 | c (real version) 27 | c arguments: 28 | c n (in) the order of matrix R 29 | c R (io) on entry, the upper triangular matrix R 30 | c on exit, the updated matrix R1 31 | c ldr (in) leading dimension of R. ldr >= n. 32 | c u (io) the vector determining the rank-1 update 33 | c on exit, u contains the rotation sines 34 | c used to transform R to R1. 35 | c w (out) cosine parts of rotations. 36 | c 37 | integer n,ldr 38 | double precision R(ldr,*),u(*) 39 | double precision w(*) 40 | external dlartg 41 | double precision rr,ui,t 42 | integer i,j 43 | 44 | do i = 1,n 45 | c apply stored rotations, column-wise 46 | ui = u(i) 47 | do j = 1,i-1 48 | t = w(j)*R(j,i) + u(j)*ui 49 | ui = w(j)*ui - u(j)*R(j,i) 50 | R(j,i) = t 51 | end do 52 | c generate next rotation 53 | call dlartg(R(i,i),ui,w(i),u(i),rr) 54 | R(i,i) = rr 55 | end do 56 | end subroutine 57 | 58 | -------------------------------------------------------------------------------- /man/update.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/update.R 3 | \name{update.bas} 4 | \alias{update.bas} 5 | \alias{update} 6 | \title{Update BAS object using a new prior} 7 | \usage{ 8 | \method{update}{bas}(object, newprior, alpha = NULL, ...) 9 | } 10 | \arguments{ 11 | \item{object}{BMA object to update} 12 | 13 | \item{newprior}{Update posterior model probabilities, probne0, shrinkage, 14 | logmarg, etc, using prior based on newprior. See \code{\link{bas}} for 15 | available methods} 16 | 17 | \item{alpha}{optional new value of hyperparameter in prior for method} 18 | 19 | \item{...}{optional arguments} 20 | } 21 | \value{ 22 | A new object of class BMA 23 | } 24 | \description{ 25 | Update a BMA object using a new prior distribution on the coefficients. 26 | } 27 | \details{ 28 | Recomputes the marginal likelihoods for the new methods for models already 29 | sampled in current object. 30 | } 31 | \examples{ 32 | 33 | \donttest{ 34 | library(MASS) 35 | data(UScrime) 36 | UScrime[,-2] <- log(UScrime[,-2]) 37 | crime.bic <- bas.lm(y ~ ., data=UScrime, n.models=2^10, prior="BIC",initprobs= "eplogp") 38 | crime.ebg <- update(crime.bic, newprior="EB-global") 39 | crime.zs <- update(crime.bic, newprior="ZS-null") 40 | } 41 | 42 | } 43 | \references{ 44 | Clyde, M. Ghosh, J. and Littman, M. (2010) Bayesian Adaptive 45 | Sampling for Variable Selection and Model Averaging. Journal of 46 | Computational Graphics and Statistics. 20:80-101 \cr 47 | \doi{10.1198/jcgs.2010.09049} 48 | } 49 | \seealso{ 50 | \code{\link{bas}} for available methods and choices of alpha 51 | 52 | Other bas methods: 53 | \code{\link{BAS}}, 54 | \code{\link{bas.lm}()}, 55 | \code{\link{coef.bas}()}, 56 | \code{\link{confint.coef.bas}()}, 57 | \code{\link{confint.pred.bas}()}, 58 | \code{\link{diagnostics}()}, 59 | \code{\link{fitted.bas}()}, 60 | \code{\link{force.heredity.bas}()}, 61 | \code{\link{image.bas}()}, 62 | \code{\link{plot.confint.bas}()}, 63 | \code{\link{predict.bas}()}, 64 | \code{\link{predict.basglm}()}, 65 | \code{\link{summary.bas}()}, 66 | \code{\link{variable.names.pred.bas}()} 67 | } 68 | \author{ 69 | Merlise Clyde \email{clyde@stat.duke.edu} 70 | } 71 | \concept{bas methods} 72 | \keyword{regression} 73 | -------------------------------------------------------------------------------- /man/phi1.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cch.R 3 | \name{phi1} 4 | \alias{phi1} 5 | \title{Compound Confluent hypergeometric function of two variables} 6 | \usage{ 7 | phi1(a, b, c, x, y, log = FALSE) 8 | } 9 | \arguments{ 10 | \item{a}{a > 0} 11 | 12 | \item{b}{arbitrary} 13 | 14 | \item{c}{c > 0} 15 | 16 | \item{x}{x > 0} 17 | 18 | \item{y}{y > 0} 19 | 20 | \item{log}{logical indicating whether to return phi1 on the log scale} 21 | } 22 | \description{ 23 | Compute the Confluent Hypergeometric function of two variables, also know as 24 | a Horn hypergeometric function or Humbert's hypergeometric used in Gordy 25 | (1998) with integral representation: 26 | } 27 | \details{ 28 | phi_1(a,b,c,x,y) = [(Gamma(c)/Gamma(a) Gamma(a-c))] Int_0^1 29 | t^(a-1) (1 - t)^(c-a-1) (1 - yt)^(-b) exp(x t) dt 30 | \url{https://en.wikipedia.org/wiki/Humbert_series} Note that Gordy's 31 | arguments for x and y are reversed in the reference above. 32 | 33 | The original `phi1` function in `BAS` was based on `C` code provided by 34 | Gordy. This function returns NA's 35 | when x is greater than `log(.Machine$double.xmax)/2`. A more 36 | stable method for calculating the `phi1` function using R's `integrate` 37 | was suggested by Daniel Heemann and is now an option whenever $x$ is too 38 | large. For calculating Bayes factors that use the `phi1` function we 39 | recommend using the `log=TRUE` option to compute log Bayes factors. 40 | } 41 | \examples{ 42 | 43 | # special cases 44 | # phi1(a, b, c, x=0, y) is the same as 2F1(b, a; c, y) 45 | phi1(1, 2, 1.5, 0, 1 / 100, log=FALSE) 46 | hypergeometric2F1(2, 1, 1.5, 1 / 100, log = FALSE) 47 | 48 | # phi1(a,0,c,x,y) is the same as 1F1(a,c,x) 49 | phi1(1, 0, 1.5, 3, 1 / 100) 50 | hypergeometric1F1(1, 1.5, 3, log = FALSE) 51 | 52 | # use direct integration 53 | phi1(1, 2, 1.5, 1000, 0, log=TRUE) 54 | } 55 | \references{ 56 | Gordy 1998 57 | } 58 | \seealso{ 59 | Other special functions: 60 | \code{\link{hypergeometric1F1}()}, 61 | \code{\link{hypergeometric2F1}()}, 62 | \code{\link{trCCH}()} 63 | } 64 | \author{ 65 | Merlise Clyde (\email{clyde@duke.edu}) 66 | 67 | Daniel Heemann (\email{df.heemann@gmail.com}) 68 | } 69 | \concept{special functions} 70 | \keyword{math} 71 | -------------------------------------------------------------------------------- /man/trCCH.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cch.R 3 | \name{trCCH} 4 | \alias{trCCH} 5 | \alias{trunc.CCH} 6 | \title{Truncated Compound Confluent Hypergeometric function} 7 | \usage{ 8 | trCCH(a, b, r, s, v, k, log = FALSE) 9 | } 10 | \arguments{ 11 | \item{a}{a > 0} 12 | 13 | \item{b}{b > 0} 14 | 15 | \item{r}{r >= 0} 16 | 17 | \item{s}{arbitrary} 18 | 19 | \item{v}{0 < v} 20 | 21 | \item{k}{arbitrary} 22 | 23 | \item{log}{logical indicating whether to return values on the log scale; 24 | useful for Bayes Factor calculations} 25 | } 26 | \description{ 27 | Compute the Truncated Confluent Hypergeometric function from Li and Clyde 28 | (2018) which is the normalizing constant in the tcch density of Gordy 29 | (1998) with integral representation: 30 | } 31 | \details{ 32 | tr.cch(a,b,r,s,v,k) = Int_0^1/v 33 | u^(a-1) (1 - vu)^(b -1) (k + (1 - k)vu)^(-r) exp(-s u) du 34 | 35 | This uses a more 36 | stable method for calculating the normalizing constant using R's `integrate` 37 | function rather than the version in Gordy 1998. For calculating Bayes factors 38 | that use the `trCCH` function we 39 | recommend using the `log=TRUE` option to compute log Bayes factors. 40 | } 41 | \examples{ 42 | 43 | # special cases 44 | # trCCH(a, b, r, s=0, v = 1, k) is the same as 45 | # 2F1(a, r, a + b, 1 - 1/k)*beta(a, b)/k^r 46 | 47 | k = 10; a = 1.5; b = 2; r = 2; 48 | trCCH(a, b, r, s=0, v = 1, k=k) *k^r/beta(a,b) 49 | hypergeometric2F1(a, r, a + b, 1 - 1/k, log = FALSE) 50 | 51 | # trCCH(a,b,0,s,1,1) is the same as 52 | # beta(a, b) 1F1(a, a + b, -s, log=FALSE) 53 | s = 3; r = 0; v = 1; k = 1 54 | beta(a, b)*hypergeometric1F1(a, a+b, -s, log = FALSE) 55 | trCCH(a, b, r, s, v, k) 56 | 57 | # Equivalence with the Phi1 function 58 | a = 1.5; b = 3; k = 1.25; s = 400; r = 2; v = 1; 59 | 60 | phi1(a, r, a + b, -s, 1 - 1/k, log=FALSE)*(k^-r)*gamma(a)*gamma(b)/gamma(a+b) 61 | trCCH(a,b,r,s,v,k) 62 | } 63 | \references{ 64 | Gordy 1998 Li & Clyde 2018 65 | } 66 | \seealso{ 67 | Other special functions: 68 | \code{\link{hypergeometric1F1}()}, 69 | \code{\link{hypergeometric2F1}()}, 70 | \code{\link{phi1}()} 71 | } 72 | \author{ 73 | Merlise Clyde (\email{clyde@duke.edu}) 74 | } 75 | \concept{special functions} 76 | \keyword{math} 77 | -------------------------------------------------------------------------------- /man/diagnostics.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/diagnostics.R 3 | \name{diagnostics} 4 | \alias{diagnostics} 5 | \title{BAS MCMC diagnostic plot} 6 | \usage{ 7 | diagnostics(obj, type = c("pip", "model"), ...) 8 | } 9 | \arguments{ 10 | \item{obj}{an object created by bas.lm or bas.glm} 11 | 12 | \item{type}{type of diagnostic plot. If "pip" the marginal inclusion 13 | probabilities are used, while if "model", plot posterior model probabilities} 14 | 15 | \item{...}{additional graphics parameters to be passed to plot} 16 | } 17 | \value{ 18 | a plot with of the marginal inclusion probabilities (pip) estimated 19 | by MCMC and renormalized marginal likelihoods times prior probabilities or 20 | model probabilities. 21 | } 22 | \description{ 23 | Function to help assess convergence of MCMC sampling for bas objects. 24 | } 25 | \details{ 26 | BAS calculates posterior model probabilities in two ways when method="MCMC". 27 | The first is using the relative Monte Carlo frequencies of sampled models. 28 | The second is to renormalize the marginal likelihood times prior 29 | probabilities over the sampled models. If the Markov chain has converged, 30 | these two quantities should be the same and fall on a 1-1 line. If not, 31 | running longer may be required. If the chain has not converged, the Monte 32 | Carlo frequencies may have less bias, although may exhibit more 33 | variability on repeated runs. 34 | } 35 | \examples{ 36 | 37 | library(MASS) 38 | data(UScrime) 39 | UScrime[, -2] <- log(UScrime[, -2]) 40 | crime.ZS <- bas.lm(y ~ ., 41 | data = UScrime, 42 | prior = "ZS-null", 43 | modelprior = uniform(), 44 | method = "MCMC", 45 | MCMC.iter = 1000 46 | ) # short run for the example 47 | diagnostics(crime.ZS) 48 | } 49 | \seealso{ 50 | Other bas methods: 51 | \code{\link{BAS}}, 52 | \code{\link{bas.lm}()}, 53 | \code{\link{coef.bas}()}, 54 | \code{\link{confint.coef.bas}()}, 55 | \code{\link{confint.pred.bas}()}, 56 | \code{\link{fitted.bas}()}, 57 | \code{\link{force.heredity.bas}()}, 58 | \code{\link{image.bas}()}, 59 | \code{\link{plot.confint.bas}()}, 60 | \code{\link{predict.bas}()}, 61 | \code{\link{predict.basglm}()}, 62 | \code{\link{summary.bas}()}, 63 | \code{\link{update.bas}()}, 64 | \code{\link{variable.names.pred.bas}()} 65 | } 66 | \author{ 67 | Merlise Clyde (\email{clyde@duke.edu}) 68 | } 69 | \concept{bas methods} 70 | -------------------------------------------------------------------------------- /man/plot.coef.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot_coef.R 3 | \name{plot.coef.bas} 4 | \alias{plot.coef.bas} 5 | \title{Plots the posterior distributions of coefficients derived from Bayesian 6 | model averaging} 7 | \usage{ 8 | \method{plot}{coef.bas}(x, e = 1e-04, subset = 1:x$n.vars, ask = TRUE, ...) 9 | } 10 | \arguments{ 11 | \item{x}{object of class coef.bas} 12 | 13 | \item{e}{optional numeric value specifying the range over which the 14 | distributions are to be graphed.} 15 | 16 | \item{subset}{optional numerical vector specifying which variables to graph 17 | (including the intercept)} 18 | 19 | \item{ask}{Prompt for next plot} 20 | 21 | \item{...}{other parameters to be passed to \code{plot} and \code{lines}} 22 | } 23 | \description{ 24 | Displays plots of the posterior distributions of the coefficients generated 25 | by Bayesian model averaging over linear regression. 26 | } 27 | \details{ 28 | Produces plots of the posterior distributions of the coefficients under 29 | model averaging. The posterior probability that the coefficient is zero is 30 | represented by a solid line at zero, with height equal to the probability. 31 | The nonzero part of the distribution is scaled so that the maximum height is 32 | equal to the probability that the coefficient is nonzero. 33 | 34 | The parameter \code{e} specifies the range over which the distributions are 35 | to be graphed by specifying the tail probabilities that dictate the range to 36 | plot over. 37 | } 38 | \note{ 39 | For mixtures of g-priors, uncertainty in g is not incorporated at this 40 | time, thus results are approximate 41 | } 42 | \examples{ 43 | 44 | \dontrun{library(MASS) 45 | data(UScrime) 46 | UScrime[,-2] <- log(UScrime[,-2]) 47 | crime_bic <- bas.lm(y ~ ., data=UScrime, n.models=2^15, prior="BIC") 48 | plot(coefficients(crime_bic), ask=TRUE) 49 | } 50 | 51 | } 52 | \references{ 53 | Hoeting, J.A., Raftery, A.E. and Madigan, D. (1996). A method 54 | for simultaneous variable selection and outlier identification in linear 55 | regression. Computational Statistics and Data Analysis, 22, 251-270. 56 | } 57 | \seealso{ 58 | \code{ \link{coef.bas}} 59 | 60 | Other bas plots: 61 | \code{\link{image.bas}()}, 62 | \code{\link{plot.bas}()} 63 | } 64 | \author{ 65 | based on function \code{plot.bic} by Ian Painter in package BMA; 66 | adapted for 'bas' class by Merlise Clyde \email{clyde@stat.duke.edu} 67 | } 68 | \concept{bas plots} 69 | \keyword{regression} 70 | -------------------------------------------------------------------------------- /R/cv_summary.R: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | # This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | # License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | # 5 | #' Summaries for Out of Sample Prediction 6 | #' 7 | #' Compute average prediction error from out of sample predictions 8 | #' 9 | #' 10 | #' @param pred fitted or predicted value from the output from 11 | #' \code{\link{predict.bas}} 12 | #' @param ytrue vector of left out response values 13 | #' @param score function used to summarize error rate. Either "squared-error", 14 | #' or "miss-class" 15 | #' @return For squared error, the average prediction error for the Bayesian 16 | #' estimator error = sqrt(sum(ytrue - yhat)^2/npred) while for binary data the 17 | #' misclassification rate is more appropriate. 18 | #' @author Merlise Clyde \email{clyde@duke.edu} 19 | #' @seealso \code{\link{predict.bas}} 20 | #' @keywords regression 21 | #' @examples 22 | #' 23 | #' \dontrun{ 24 | #' library(foreign) 25 | #' cognitive <- read.dta("https://www.stat.columbia.edu/~gelman/arm/examples/child.iq/kidiq.dta") 26 | #' cognitive$mom_work <- as.numeric(cognitive$mom_work > 1) 27 | #' cognitive$mom_hs <- as.numeric(cognitive$mom_hs > 0) 28 | #' colnames(cognitive) <- c("kid_score", "hs", "iq", "work", "age") 29 | #' 30 | #' set.seed(42) 31 | #' n <- nrow(cognitive) 32 | #' test <- sample(1:n, size = round(.20 * n), replace = FALSE) 33 | #' testdata <- cognitive[test, ] 34 | #' traindata <- cognitive[-test, ] 35 | #' cog_train <- bas.lm(kid_score ~ ., prior = "BIC", modelprior = uniform(), data = traindata) 36 | #' yhat <- predict(cog_train, newdata = testdata, estimator = "BMA", se = F) 37 | #' cv.summary.bas(yhat$fit, testdata$kid_score) 38 | #' } 39 | #' @rdname cv.summary.bas 40 | #' @export 41 | cv.summary.bas <- function(pred, ytrue, score = "squared-error") { 42 | if (length(pred) != length(ytrue)) { 43 | stop("predicted values and observed values are not the same length") 44 | } 45 | 46 | if (!(score %in% c("squared-error", "miss-class"))) { 47 | stop(paste( 48 | "score ", score, 49 | "not implemented; please check spelling" 50 | )) 51 | } 52 | if (score == "miss-class") { 53 | pred.class <- ifelse(pred < .5, 0, 1) 54 | confusion <- table(pred.class, ytrue) 55 | error <- (sum(confusion) - sum(diag(confusion))) / sum(confusion) 56 | } 57 | else { 58 | error <- sqrt(sum((pred - ytrue)^2) / length(ytrue)) 59 | } 60 | return(error) 61 | } 62 | -------------------------------------------------------------------------------- /man/plot.confint.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/confint.R 3 | \name{plot.confint.bas} 4 | \alias{plot.confint.bas} 5 | \title{Plot Bayesian Confidence Intervals} 6 | \usage{ 7 | \method{plot}{confint.bas}(x, horizontal = FALSE, ...) 8 | } 9 | \arguments{ 10 | \item{x}{the output from \code{\link{confint.coef.bas}} or 11 | \code{\link{confint.pred.bas}} containing credible intervals and estimates.} 12 | 13 | \item{horizontal}{orientation of the plot} 14 | 15 | \item{...}{optional graphical arguments to pass on to plot} 16 | } 17 | \value{ 18 | A plot of the credible intervals. 19 | } 20 | \description{ 21 | Function takes the the output of functions that return credible intervals 22 | from BAS objects, and creates a plot of the posterior mean with segments 23 | representing the credible interval. %% ~~ A concise (1-5 lines) description 24 | of what the function does. ~~ 25 | } 26 | \details{ 27 | This function takes the HPD intervals or credible intervals created by 28 | \code{\link{confint.coef.bas}} or \code{\link{confint.pred.bas}} from BAS 29 | objects, and creates a plot of the posterior mean with segments representing 30 | the credible interval. BAS tries to return HPD intervals, and under model 31 | averaging these may not be symmetric. %% ~~ If necessary, more details than 32 | the description above ~~ 33 | } 34 | \examples{ 35 | 36 | data(Hald) 37 | hald.ZS = bas.lm(Y ~ ., data=Hald, prior="ZS-null", modelprior=uniform()) 38 | hald.coef = confint(coef(hald.ZS), parm=2:5) 39 | plot(hald.coef) 40 | plot(hald.coef, horizontal=TRUE) 41 | plot(confint(predict(hald.ZS, se.fit=TRUE), parm="mean")) 42 | 43 | } 44 | \seealso{ 45 | \code{\link{confint.coef.bas}}, \code{\link{confint.pred.bas}}, 46 | \code{\link{coef.bas}}, \code{\link{predict.bas}}, \code{link{bas.lm}} 47 | 48 | Other bas methods: 49 | \code{\link{BAS}}, 50 | \code{\link{bas.lm}()}, 51 | \code{\link{coef.bas}()}, 52 | \code{\link{confint.coef.bas}()}, 53 | \code{\link{confint.pred.bas}()}, 54 | \code{\link{diagnostics}()}, 55 | \code{\link{fitted.bas}()}, 56 | \code{\link{force.heredity.bas}()}, 57 | \code{\link{image.bas}()}, 58 | \code{\link{predict.bas}()}, 59 | \code{\link{predict.basglm}()}, 60 | \code{\link{summary.bas}()}, 61 | \code{\link{update.bas}()}, 62 | \code{\link{variable.names.pred.bas}()} 63 | 64 | Other CI methods: 65 | \code{\link{confint.coef.bas}()}, 66 | \code{\link{confint.pred.bas}()} 67 | } 68 | \author{ 69 | Merlise A Clyde 70 | } 71 | \concept{CI methods} 72 | \concept{bas methods} 73 | \keyword{bayesian} 74 | \keyword{regression} 75 | -------------------------------------------------------------------------------- /tests/testthat/test-bas-lm-lowrank.R: -------------------------------------------------------------------------------- 1 | # the following does not throw a warning on a m1MAC github issue #62 skipping 2 | # test pending package archival until able to debug on M1mac 3 | 4 | test_that("check non-full rank", { 5 | loc <- system.file("testdata", package = "BAS") 6 | d <- read.csv(paste(loc, "JASP-testdata.csv", sep = "/")) 7 | 8 | fullModelFormula <- as.formula("contNormal ~ contGamma * contExpon + contGamma * contcor1 + contExpon * contcor1") 9 | 10 | 11 | expect_error(eplogprob(lm(fullModelFormula, data = d))) 12 | 13 | basObj.eplogp <- bas.lm(fullModelFormula, 14 | data = d, 15 | alpha = 0.125316, initprobs = "marg-eplogp", 16 | prior = "JZS", method = "deterministic", pivot = TRUE, 17 | modelprior = uniform(), 18 | weights = facFifty, force.heredity = FALSE 19 | ) 20 | basObj.det <- bas.lm(fullModelFormula, 21 | data = d, 22 | alpha = 0.125316, 23 | modelprior = uniform(), 24 | prior = "JZS", method = "deterministic", pivot = TRUE, 25 | weights = facFifty, force.heredity = FALSE 26 | ) 27 | basObj <- bas.lm(fullModelFormula, 28 | data = d, 29 | alpha = 0.125316, modelprior = uniform(), 30 | prior = "JZS", method = "BAS", pivot = TRUE, 31 | weights = facFifty, force.heredity = FALSE 32 | ) 33 | expect_equal(0, sum(is.na(basObj.det$postprobs))) 34 | expect_equal(basObj.eplogp$probne0, basObj.det$probne0) 35 | expect_equal(basObj.det$probne0, basObj$probne0) 36 | expect_equal(basObj.eplogp$probne0, basObj$probne0) 37 | 38 | basObj.EBL <- bas.lm(fullModelFormula, 39 | data = d, 40 | alpha = 0.125316, initprobs = "marg-eplogp", 41 | prior = "EB-local", method = "deterministic", pivot = TRUE, 42 | modelprior = uniform(), 43 | weights = facFifty, force.heredity = FALSE 44 | ) 45 | basObj.up <- update(basObj.eplogp, newprior = "EB-local") 46 | expect_equal(basObj.EBL$postprobs, basObj.up$postprobs, 47 | tolerance=.001) 48 | 49 | skip_on_cran() 50 | skip_on_os("mac", arch="aarch64") 51 | expect_warning(bas.lm(fullModelFormula, 52 | data = d, 53 | alpha = 0.125316, 54 | prior = "JZS", 55 | weights = facFifty, force.heredity = FALSE, pivot = FALSE)) 56 | }) 57 | -------------------------------------------------------------------------------- /man/force.heredity.bas.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/interactions.R 3 | \name{force.heredity.bas} 4 | \alias{force.heredity.bas} 5 | \title{Post processing function to force constraints on interaction inclusion bas BMA objects} 6 | \usage{ 7 | force.heredity.bas(object, prior.prob = 0.5) 8 | } 9 | \arguments{ 10 | \item{object}{a bas linear model or generalized linear model object} 11 | 12 | \item{prior.prob}{prior probability that a term is included conditional on parents being included} 13 | } 14 | \value{ 15 | a bas object with updated models, coefficients and summaries obtained removing all models with zero prior and posterior probabilities. 16 | } 17 | \description{ 18 | This function takes the output of a bas object and allows higher 19 | order interactions to be included only if their parent 20 | lower order interactions terms are in the model, by 21 | assigning zero prior probability, and hence posterior 22 | probability, to models that do not include their respective 23 | parents. 24 | } 25 | \note{ 26 | Currently prior probabilities are computed using conditional Bernoulli distributions, i.e. P(gamma_j = 1 | Parents(gamma_j) = 1) = prior.prob. This is not very efficient for models with a large number of levels. Future updates will force this at the time of sampling. 27 | } 28 | \examples{ 29 | 30 | data("chickwts") 31 | bas.chk <- bas.lm(weight ~ feed, data = chickwts) 32 | # summary(bas.chk) # 2^5 = 32 models 33 | bas.chk.int <- force.heredity.bas(bas.chk) 34 | # summary(bas.chk.int) # two models now 35 | 36 | 37 | data(Hald) 38 | bas.hald <- bas.lm(Y ~ .^2, data = Hald) 39 | bas.hald.int <- force.heredity.bas(bas.hald) 40 | image(bas.hald.int) 41 | 42 | image(bas.hald.int) 43 | 44 | # two-way interactions 45 | data(ToothGrowth) 46 | ToothGrowth$dose <- factor(ToothGrowth$dose) 47 | levels(ToothGrowth$dose) <- c("Low", "Medium", "High") 48 | TG.bas <- bas.lm(len ~ supp * dose, data = ToothGrowth, modelprior = uniform()) 49 | TG.bas.int <- force.heredity.bas(TG.bas) 50 | image(TG.bas.int) 51 | } 52 | \seealso{ 53 | Other bas methods: 54 | \code{\link{BAS}}, 55 | \code{\link{bas.lm}()}, 56 | \code{\link{coef.bas}()}, 57 | \code{\link{confint.coef.bas}()}, 58 | \code{\link{confint.pred.bas}()}, 59 | \code{\link{diagnostics}()}, 60 | \code{\link{fitted.bas}()}, 61 | \code{\link{image.bas}()}, 62 | \code{\link{plot.confint.bas}()}, 63 | \code{\link{predict.bas}()}, 64 | \code{\link{predict.basglm}()}, 65 | \code{\link{summary.bas}()}, 66 | \code{\link{update.bas}()}, 67 | \code{\link{variable.names.pred.bas}()} 68 | } 69 | \author{ 70 | Merlise A Clyde 71 | } 72 | \concept{bas methods} 73 | \keyword{regression} 74 | -------------------------------------------------------------------------------- /man/eplogprob.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/eplogprob.R 3 | \name{eplogprob} 4 | \alias{eplogprob} 5 | \title{eplogprob - Compute approximate marginal inclusion probabilities from 6 | pvalues} 7 | \usage{ 8 | eplogprob(lm.obj, thresh = 0.5, max = 0.99, int = TRUE) 9 | } 10 | \arguments{ 11 | \item{lm.obj}{a linear model object} 12 | 13 | \item{thresh}{the value of the inclusion probability when if the p-value > 14 | 1/exp(1), where the lower bound approximation is not valid.} 15 | 16 | \item{max}{maximum value of the inclusion probability; used for the 17 | \code{bas.lm} function to keep initial inclusion probabilities away from 1.} 18 | 19 | \item{int}{If the Intercept is included in the linear model, set the 20 | marginal inclusion probability corresponding to the intercept to 1} 21 | } 22 | \value{ 23 | \code{eplogprob} returns a vector of marginal posterior inclusion 24 | probabilities for each of the variables in the linear model. If int = TRUE, 25 | then the inclusion probability for the intercept is set to 1. If the model 26 | is not full rank, variables that are linearly dependent base on the QR 27 | factorization will have NA for their p-values. In bas.lm, where the 28 | probabilities are used for sampling, the inclusion probability is set to 0. 29 | } 30 | \description{ 31 | \code{eplogprob} calculates approximate marginal posterior inclusion 32 | probabilities from p-values computed from a linear model using a lower bound 33 | approximation to Bayes factors. Used to obtain initial inclusion 34 | probabilities for sampling using Bayesian Adaptive Sampling \code{bas.lm} 35 | } 36 | \details{ 37 | Sellke, Bayarri and Berger (2001) provide a simple calibration of p-values 38 | 39 | BF(p) = -e p log(p) 40 | 41 | which provide a lower bound to a Bayes factor for comparing H0: beta = 0 42 | versus H1: beta not equal to 0, when the p-value p is less than 1/e. Using 43 | equal prior odds on the hypotheses H0 and H1, the approximate marginal 44 | posterior inclusion probability 45 | 46 | p(beta != 0 | data ) = 1/(1 + BF(p)) 47 | 48 | When p > 1/e, we set the marginal inclusion probability to 0.5 or the value 49 | given by \code{thresh}. 50 | } 51 | \examples{ 52 | 53 | library(MASS) 54 | data(UScrime) 55 | UScrime[,-2] = log(UScrime[,-2]) 56 | eplogprob(lm(y ~ ., data=UScrime)) 57 | 58 | 59 | } 60 | \references{ 61 | Sellke, Thomas, Bayarri, M. J., and Berger, James O. (2001), 62 | ``Calibration of p-values for testing precise null hypotheses'', The 63 | American Statistician, 55, 62-71. 64 | } 65 | \seealso{ 66 | \code{\link{bas}} 67 | } 68 | \author{ 69 | Merlise Clyde \email{clyde@stat.duke.edu} 70 | } 71 | \keyword{regression} 72 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | url: http://merliseclyde.github.io/BAS/ 2 | development: 3 | mode: auto 4 | template: 5 | bootstrap: 5 6 | bootswatch: cosmo 7 | docsearch: 8 | api_key: 94a8229a313e5475acdeffd26558ce98 9 | index_name: bas 10 | authors: 11 | Merlise Clyde: 12 | href: https://merliseclyde.github.io/personal-website/ 13 | navbar: 14 | title: "BAS" 15 | left: 16 | - text: "Vignettes" 17 | href: articles/index.html 18 | - text: "Functions" 19 | href: reference/index.html 20 | - text: "News" 21 | href: news/index.html 22 | right: 23 | - icon: fa-twitter 24 | href: https://twitter.com/merliseclyde 25 | - icon: fa-github 26 | href: https://github.com/merliseclyde/BAS 27 | reference: 28 | - title: "model fitting" 29 | desc: Functions associated with inference and selection 30 | for Bayesian Linear and Generalized Linear Models 31 | contents: 32 | - '`bas.glm`' 33 | - '`bas.lm`' 34 | - '`bayesglm.fit`' 35 | - '`coef.bas`' 36 | - '`confint.coef.bas`' 37 | - '`confint.pred.bas`' 38 | - '`cv.summary.bas`' 39 | - '`diagnostics`' 40 | - '`eplogprob`' 41 | - '`eplogprob.marg`' 42 | - '`fitted.bas`' 43 | - '`force.heredity.bas`' 44 | - '`image.bas`' 45 | - '`plot.bas`' 46 | - '`plot.coef.bas`' 47 | - '`plot.confint.bas`' 48 | - '`predict.bas`' 49 | - '`predict.basglm`' 50 | - '`print.bas`' 51 | - '`summary.bas`' 52 | - '`update.bas`' 53 | - '`variable.names`' 54 | - title: "coefficient priors" 55 | desc: ~ 56 | contents: 57 | - '`beta.prime`' 58 | - '`CCH`' 59 | - '`EB.global`' 60 | - '`EB.local`' 61 | - '`g.prior`' 62 | - '`hyper.g`' 63 | - '`hyper.g.n`' 64 | - '`IC.prior`' 65 | - '`intrinsic`' 66 | - '`Jeffreys`' 67 | - '`robust`' 68 | - '`tCCH`' 69 | - '`TG`' 70 | - '`testBF.prior`' 71 | 72 | - title: "model priors" 73 | desc: ~ 74 | contents: 75 | - '`Bernoulli`' 76 | - '`Bernoulli.heredity`' 77 | - '`beta.binomial`' 78 | - '`tr.beta.binomial`' 79 | - '`tr.poisson`' 80 | - '`tr.power.prior`' 81 | - '`uniform`' 82 | - title: "special functions" 83 | desc: ~ 84 | contents: 85 | - '`hypergeometric1F1`' 86 | - '`hypergeometric2F1`' 87 | - '`phi1`' 88 | - title: "utility functions" 89 | desc: ~ 90 | contents: 91 | - '`Bayes.outlier`' 92 | - '`list2matrix.bas`' 93 | - '`list2matrix.which`' 94 | - '`which.matrix`' 95 | - title: "data sets" 96 | desc: ~ 97 | contents: 98 | - '`Hald`' 99 | - '`bodyfat`' 100 | - '`protein`' 101 | - title: "all functions" 102 | desc: ~ 103 | contents: 104 | - starts_with("*") 105 | -------------------------------------------------------------------------------- /R/BAS-package.R: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | # This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | # License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | #' _PACKAGE 5 | #' @name BAS 6 | #' 7 | #' @title BAS: Bayesian Model Averaging using Bayesian Adaptive Sampling 8 | #' 9 | #' @description Implementation of Bayesian Model Averaging in linear models using stochastic or 10 | #' deterministic sampling without replacement from posterior distributions. 11 | #' Prior distributions on coefficients are of the form of Zellner's g-prior or 12 | #' mixtures of g-priors. Options include the Zellner-Siow Cauchy Priors, the 13 | #' Liang et al hyper-g priors, Local and Global Empirical Bayes estimates of g, 14 | #' and other default model selection criteria such as AIC and BIC. Sampling 15 | #' probabilities may be updated based on the sampled models. 16 | #' 17 | #' 18 | #' @author Merlise Clyde, \cr Maintainer: Merlise Clyde 19 | #' @seealso \code{\link{bas.lm}} \code{\link{bas.glm}} 20 | # 21 | #' @examples 22 | #' data("Hald") 23 | #' hald.gprior = bas.lm(Y ~ ., data=Hald, alpha=13, prior="g-prior") 24 | #' 25 | #' # more complete demos 26 | #' 27 | #' demo(BAS.hald) 28 | #' \dontrun{ 29 | #' demo(BAS.USCrime) 30 | #' } 31 | #' 32 | #' @references Clyde, M. Ghosh, J. and Littman, M. (2010) Bayesian Adaptive 33 | #' Sampling for Variable Selection and Model Averaging. Journal of 34 | #' Computational Graphics and Statistics. 20:80-101 \cr 35 | #' \doi{10.1198/jcgs.2010.09049} 36 | #' 37 | #' Clyde, M. and George, E. I. (2004) Model uncertainty. Statist. Sci., 19, 38 | #' 81-94. \cr \doi{10.1214/088342304000000035} 39 | #' 40 | #' Clyde, M. (1999) Bayesian Model Averaging and Model Search Strategies (with 41 | #' discussion). In Bayesian Statistics 6. J.M. Bernardo, A.P. Dawid, J.O. 42 | #' Berger, and A.F.M. Smith eds. Oxford University Press, pages 157-185. 43 | #' 44 | #' Li, Y. and Clyde, M. (2018) Mixtures of g-priors in Generalized Linear 45 | #' Models. Journal of the American Statistical Association, 113:524, 1828-1845 \doi{10.1080/01621459.2018.1469992} 46 | #' 47 | #' Liang, F., Paulo, R., Molina, G., Clyde, M. and Berger, J.O. (2008) Mixtures 48 | #' of g-priors for Bayesian Variable Selection. Journal of the American 49 | #' Statistical Association. 103:410-423. \cr 50 | #' 51 | #' \doi{10.1198/016214507000001337} 52 | #' 53 | #' @keywords package regression 54 | #' @import stats 55 | #' @import graphics 56 | #' @import grDevices 57 | #' 58 | #' @useDynLib BAS, .registration=TRUE, .fixes="C_" 59 | #' @family bas methods 60 | #' 61 | NULL 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /man/confint.pred.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/confint.R 3 | \name{confint.pred.bas} 4 | \alias{confint.pred.bas} 5 | \title{Compute Credible (Bayesian Confidence) Intervals for a BAS predict object} 6 | \usage{ 7 | \method{confint}{pred.bas}(object, parm, level = 0.95, nsim = 10000, ...) 8 | } 9 | \arguments{ 10 | \item{object}{an object created by \code{\link{predict.bas}}} 11 | 12 | \item{parm}{character variable, "mean" or "pred". If missing parm='pred'.} 13 | 14 | \item{level}{the nominal level of the (point-wise) credible interval} 15 | 16 | \item{nsim}{number of Monte Carlo simulations for sampling methods with BMA} 17 | 18 | \item{...}{optional arguments to pass on to next function call; none at this 19 | time.} 20 | } 21 | \value{ 22 | a matrix with lower and upper level * 100 percent credible intervals 23 | for either the mean of the regression function or predicted values. %% 24 | } 25 | \description{ 26 | Compute credible intervals for in-sample or out of sample prediction or for 27 | the regression function 28 | } 29 | \details{ 30 | This constructs approximate 95 percent Highest Posterior Density intervals 31 | for 'pred.bas' objects. If the estimator is based on model selection, the 32 | intervals use a Student t distribution using the estimate of g. If the 33 | estimator is based on BMA, then nsim draws from the mixture of Student t 34 | distributions are obtained with the HPD interval obtained from the Monte 35 | Carlo draws. %% ~~ If necessary, more details than the description above ~~ 36 | } 37 | \examples{ 38 | 39 | data("Hald") 40 | hald.gprior = bas.lm(Y~ ., data=Hald, alpha=13, prior="g-prior") 41 | hald.pred = predict(hald.gprior, estimator="BPM", predict=FALSE, se.fit=TRUE) 42 | confint(hald.pred, parm="mean") 43 | confint(hald.pred) #default 44 | hald.pred = predict(hald.gprior, estimator="BMA", predict=FALSE, se.fit=TRUE) 45 | confint(hald.pred) 46 | 47 | 48 | } 49 | \seealso{ 50 | \code{\link{predict.bas}} 51 | 52 | Other bas methods: 53 | \code{\link{BAS}}, 54 | \code{\link{bas.lm}()}, 55 | \code{\link{coef.bas}()}, 56 | \code{\link{confint.coef.bas}()}, 57 | \code{\link{diagnostics}()}, 58 | \code{\link{fitted.bas}()}, 59 | \code{\link{force.heredity.bas}()}, 60 | \code{\link{image.bas}()}, 61 | \code{\link{plot.confint.bas}()}, 62 | \code{\link{predict.bas}()}, 63 | \code{\link{predict.basglm}()}, 64 | \code{\link{summary.bas}()}, 65 | \code{\link{update.bas}()}, 66 | \code{\link{variable.names.pred.bas}()} 67 | 68 | Other CI methods: 69 | \code{\link{confint.coef.bas}()}, 70 | \code{\link{plot.confint.bas}()} 71 | } 72 | \author{ 73 | Merlise A Clyde 74 | } 75 | \concept{CI methods} 76 | \concept{bas methods} 77 | \keyword{regression} 78 | -------------------------------------------------------------------------------- /man/BAS.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/BAS-package.R 3 | \name{BAS} 4 | \alias{BAS} 5 | \title{BAS: Bayesian Model Averaging using Bayesian Adaptive Sampling} 6 | \description{ 7 | Implementation of Bayesian Model Averaging in linear models using stochastic or 8 | deterministic sampling without replacement from posterior distributions. 9 | Prior distributions on coefficients are of the form of Zellner's g-prior or 10 | mixtures of g-priors. Options include the Zellner-Siow Cauchy Priors, the 11 | Liang et al hyper-g priors, Local and Global Empirical Bayes estimates of g, 12 | and other default model selection criteria such as AIC and BIC. Sampling 13 | probabilities may be updated based on the sampled models. 14 | } 15 | \details{ 16 | _PACKAGE 17 | } 18 | \examples{ 19 | data("Hald") 20 | hald.gprior = bas.lm(Y ~ ., data=Hald, alpha=13, prior="g-prior") 21 | 22 | # more complete demos 23 | 24 | demo(BAS.hald) 25 | \dontrun{ 26 | demo(BAS.USCrime) 27 | } 28 | 29 | } 30 | \references{ 31 | Clyde, M. Ghosh, J. and Littman, M. (2010) Bayesian Adaptive 32 | Sampling for Variable Selection and Model Averaging. Journal of 33 | Computational Graphics and Statistics. 20:80-101 \cr 34 | \doi{10.1198/jcgs.2010.09049} 35 | 36 | Clyde, M. and George, E. I. (2004) Model uncertainty. Statist. Sci., 19, 37 | 81-94. \cr \doi{10.1214/088342304000000035} 38 | 39 | Clyde, M. (1999) Bayesian Model Averaging and Model Search Strategies (with 40 | discussion). In Bayesian Statistics 6. J.M. Bernardo, A.P. Dawid, J.O. 41 | Berger, and A.F.M. Smith eds. Oxford University Press, pages 157-185. 42 | 43 | Li, Y. and Clyde, M. (2018) Mixtures of g-priors in Generalized Linear 44 | Models. Journal of the American Statistical Association, 113:524, 1828-1845 \doi{10.1080/01621459.2018.1469992} 45 | 46 | Liang, F., Paulo, R., Molina, G., Clyde, M. and Berger, J.O. (2008) Mixtures 47 | of g-priors for Bayesian Variable Selection. Journal of the American 48 | Statistical Association. 103:410-423. \cr 49 | 50 | \doi{10.1198/016214507000001337} 51 | } 52 | \seealso{ 53 | \code{\link{bas.lm}} \code{\link{bas.glm}} 54 | 55 | Other bas methods: 56 | \code{\link{bas.lm}()}, 57 | \code{\link{coef.bas}()}, 58 | \code{\link{confint.coef.bas}()}, 59 | \code{\link{confint.pred.bas}()}, 60 | \code{\link{diagnostics}()}, 61 | \code{\link{fitted.bas}()}, 62 | \code{\link{force.heredity.bas}()}, 63 | \code{\link{image.bas}()}, 64 | \code{\link{plot.confint.bas}()}, 65 | \code{\link{predict.bas}()}, 66 | \code{\link{predict.basglm}()}, 67 | \code{\link{summary.bas}()}, 68 | \code{\link{update.bas}()}, 69 | \code{\link{variable.names.pred.bas}()} 70 | } 71 | \author{ 72 | Merlise Clyde, \cr Maintainer: Merlise Clyde 73 | } 74 | \concept{bas methods} 75 | \keyword{package} 76 | \keyword{regression} 77 | -------------------------------------------------------------------------------- /man/eplogprob.marg.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/eplogprob.R 3 | \name{eplogprob.marg} 4 | \alias{eplogprob.marg} 5 | \title{eplogprob.marg - Compute approximate marginal inclusion probabilities from 6 | pvalues} 7 | \usage{ 8 | eplogprob.marg(Y, X, thresh = 0.5, max = 0.99, int = TRUE) 9 | } 10 | \arguments{ 11 | \item{Y}{response variable} 12 | 13 | \item{X}{design matrix with a column of ones for the intercept} 14 | 15 | \item{thresh}{the value of the inclusion probability when if the p-value > 16 | 1/exp(1), where the lower bound approximation is not valid.} 17 | 18 | \item{max}{maximum value of the inclusion probability; used for the 19 | \code{bas.lm} function to keep initial inclusion probabilities away from 1.} 20 | 21 | \item{int}{If the Intercept is included in the linear model, set the 22 | marginal inclusion probability corresponding to the intercept to 1} 23 | } 24 | \value{ 25 | \code{eplogprob.prob} returns a vector of marginal posterior 26 | inclusion probabilities for each of the variables in the linear model. If 27 | int = TRUE, then the inclusion probability for the intercept is set to 1. 28 | } 29 | \description{ 30 | \code{eplogprob.marg} calculates approximate marginal posterior inclusion 31 | probabilities from p-values computed from a series of simple linear 32 | regression models using a lower bound approximation to Bayes factors. Used 33 | to order variables and if appropriate obtain initial inclusion probabilities 34 | for sampling using Bayesian Adaptive Sampling \code{bas.lm} 35 | } 36 | \details{ 37 | Sellke, Bayarri and Berger (2001) provide a simple calibration of p-values 38 | 39 | BF(p) = -e p log(p) 40 | 41 | which provide a lower bound to a Bayes factor for comparing H0: beta = 0 42 | versus H1: beta not equal to 0, when the p-value p is less than 1/e. Using 43 | equal prior odds on the hypotheses H0 and H1, the approximate marginal 44 | posterior inclusion probability 45 | 46 | p(beta != 0 | data ) = 1/(1 + BF(p)) 47 | 48 | When p > 1/e, we set the marginal inclusion probability to 0.5 or the value 49 | given by \code{thresh}. For the eplogprob.marg the marginal p-values are 50 | obtained using statistics from the p simple linear regressions 51 | 52 | P(F > (n-2) R2/(1 - R2)) where F ~ F(1, n-2) where R2 is the square of the 53 | correlation coefficient between y and X_j. 54 | } 55 | \examples{ 56 | 57 | library(MASS) 58 | data(UScrime) 59 | UScrime[,-2] = log(UScrime[,-2]) 60 | eplogprob(lm(y ~ ., data=UScrime)) 61 | } 62 | \references{ 63 | Sellke, Thomas, Bayarri, M. J., and Berger, James O. (2001), 64 | ``Calibration of p-values for testing precise null hypotheses'', The 65 | American Statistician, 55, 62-71. 66 | } 67 | \seealso{ 68 | \code{\link{bas}} 69 | } 70 | \author{ 71 | Merlise Clyde \email{clyde@stat.duke.edu} 72 | } 73 | \keyword{regression} 74 | -------------------------------------------------------------------------------- /man/confint.coef.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/confint.R 3 | \name{confint.coef.bas} 4 | \alias{confint.coef.bas} 5 | \alias{confint} 6 | \title{Compute Credible Intervals for BAS regression coefficients from BAS objects} 7 | \usage{ 8 | \method{confint}{coef.bas}(object, parm, level = 0.95, nsim = 10000, ...) 9 | } 10 | \arguments{ 11 | \item{object}{a coef.bas object} 12 | 13 | \item{parm}{a specification of which parameters are to be given credible 14 | intervals, either a vector of numbers or a vector of names. If missing, all 15 | parameters are considered.} 16 | 17 | \item{level}{the probability coverage required} 18 | 19 | \item{nsim}{number of Monte Carlo draws from the posterior distribution. 20 | Used when number of models is greater than 1.} 21 | 22 | \item{...}{other arguments to passed; none currently} 23 | } 24 | \value{ 25 | A matrix (or vector) with columns giving lower and upper HPD 26 | credible limits for each parameter. These will be labeled as 1-level)/2 and 27 | 1 - (1-level)/2 in percent (by default 2.5 and 97.5). 28 | } 29 | \description{ 30 | Uses Monte Carlo simulations using posterior means and standard deviations 31 | of coefficients to generate draws from the posterior distributions and 32 | returns highest posterior density (HPD) credible intervals. If the number 33 | of models equals one, then use the t distribution to find intervals. These 34 | currently condition on the estimate of $g$. %% ~~ If necessary, more details 35 | than the description above ~~ 36 | } 37 | \note{ 38 | For mixture of g-priors these are approximate. This uses Monte Carlo 39 | sampling so results may be subject to Monte Carlo variation and larger values 40 | of nsim may be needed to reduce variability. %% ~~further notes~~ 41 | } 42 | \examples{ 43 | 44 | 45 | data("Hald") 46 | hald_gprior <- bas.lm(Y~ ., data=Hald, alpha=13, 47 | prior="g-prior") 48 | coef_hald <- coef(hald_gprior) 49 | confint(coef_hald) 50 | confint(coef_hald, approx=FALSE, nsim=5000) 51 | # extract just the coefficient of X4 52 | confint(coef_hald, parm="X4") 53 | 54 | 55 | } 56 | \seealso{ 57 | Other CI methods: 58 | \code{\link{confint.pred.bas}()}, 59 | \code{\link{plot.confint.bas}()} 60 | 61 | Other bas methods: 62 | \code{\link{BAS}}, 63 | \code{\link{bas.lm}()}, 64 | \code{\link{coef.bas}()}, 65 | \code{\link{confint.pred.bas}()}, 66 | \code{\link{diagnostics}()}, 67 | \code{\link{fitted.bas}()}, 68 | \code{\link{force.heredity.bas}()}, 69 | \code{\link{image.bas}()}, 70 | \code{\link{plot.confint.bas}()}, 71 | \code{\link{predict.bas}()}, 72 | \code{\link{predict.basglm}()}, 73 | \code{\link{summary.bas}()}, 74 | \code{\link{update.bas}()}, 75 | \code{\link{variable.names.pred.bas}()} 76 | } 77 | \author{ 78 | Merlise A Clyde 79 | } 80 | \concept{CI methods} 81 | \concept{bas methods} 82 | \keyword{regression} 83 | -------------------------------------------------------------------------------- /src/amcmc-funs.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | // This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | // License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | // SPDX-License-Identifier: GPL-3.0 5 | // 6 | // AMC Helper functions 7 | 8 | #include "bas.h" 9 | 10 | void update_Cov(double *Cov, double *priorCov, double *SSgam, double *marg_probs, 11 | double lambda, int n, int m, int print) { 12 | double alpha, one=1.0; 13 | int matsize=n*n, inc=1, i,j,info=1; 14 | 15 | memcpy(Cov, SSgam, sizeof(double)*matsize); 16 | if (print == 1) { 17 | Rprintf("SS: %d iterations\n", m); 18 | 19 | for (j=0; j < n; j++ ){ 20 | Rprintf("%d %f ", j, marg_probs[j]); 21 | for(i = 0; i < n; i++){ 22 | Rprintf("%f ", Cov[i*n + j]);} 23 | Rprintf("\n"); 24 | } 25 | } 26 | alpha = -(double) m; 27 | // Compute SSgam - m prob prob^T = SS_n 28 | F77_NAME(dsyr)("U", &n, &alpha, &marg_probs[0], &inc, &Cov[0], &n FCONE); 29 | // Add priorSS to observed SS = SS_0 + SS_n 30 | F77_NAME(daxpy)(&matsize, &one, &priorCov[0], &inc, &Cov[0], &inc); 31 | 32 | alpha = 1.0/((double) m + lambda - (double) n - 1.0); 33 | // divide SS_0 + SS by (m + lambda - n - 1) to get posterior expectation of Sigma 34 | F77_NAME(dscal)(&matsize, &alpha, &Cov[0], &inc); 35 | 36 | if (print == 1) { 37 | Rprintf("Cov:\n"); 38 | 39 | for (j=0; j < n; j++ ){ 40 | for(i = 0; i < n; i++){ 41 | Rprintf("%f ", Cov[i*n + j]);} 42 | Rprintf("\n"); 43 | } 44 | } 45 | // compute the cholesky of Cov = U^T U 46 | F77_NAME(dpotrf)("U", &n, &Cov[0], &n, &info FCONE); 47 | // compute the inverse of Cholesky factor U.inv. 48 | F77_NAME(dtrtri)("U","N", &n, &Cov[0], &n, &info FCONE FCONE); 49 | // verified correct 3/15/2024 50 | if (print == 1) { 51 | Rprintf("inverse of Chol(Cov(SSgam)):\n"); 52 | for (j=0; j < n; j++ ){ 53 | for(i = 0; i < n; i++){ 54 | Rprintf("%f ", Cov[i*n + j]);} 55 | Rprintf("\n"); 56 | } 57 | } 58 | } 59 | 60 | 61 | double cond_prob(double *model, int j, int n, double *mean, double *u_inv , double delta) { 62 | double prob; 63 | int i; 64 | 65 | // betas = I - diag(U^{-1}) U^-T 66 | // Note that elements of u_inv is U^{-T} due to FORTRAN column order 67 | // E[Y] = betas (Ybar) 68 | // E[Y_j | Y_= 1.0) prob = 1.0 - delta; 78 | // Rprintf("%f \n", prob); 79 | return(prob); 80 | } 81 | -------------------------------------------------------------------------------- /R/diagnostics.R: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | # This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | # License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | # 5 | #' BAS MCMC diagnostic plot 6 | #' 7 | #' Function to help assess convergence of MCMC sampling for bas objects. 8 | #' 9 | #' BAS calculates posterior model probabilities in two ways when method="MCMC". 10 | #' The first is using the relative Monte Carlo frequencies of sampled models. 11 | #' The second is to renormalize the marginal likelihood times prior 12 | #' probabilities over the sampled models. If the Markov chain has converged, 13 | #' these two quantities should be the same and fall on a 1-1 line. If not, 14 | #' running longer may be required. If the chain has not converged, the Monte 15 | #' Carlo frequencies may have less bias, although may exhibit more 16 | #' variability on repeated runs. 17 | #' 18 | #' @param obj an object created by bas.lm or bas.glm 19 | #' @param type type of diagnostic plot. If "pip" the marginal inclusion 20 | #' probabilities are used, while if "model", plot posterior model probabilities 21 | #' @param ... additional graphics parameters to be passed to plot 22 | #' @return a plot with of the marginal inclusion probabilities (pip) estimated 23 | #' by MCMC and renormalized marginal likelihoods times prior probabilities or 24 | #' model probabilities. 25 | #' @author Merlise Clyde (\email{clyde@duke.edu}) 26 | #' @examples 27 | #' 28 | #' library(MASS) 29 | #' data(UScrime) 30 | #' UScrime[, -2] <- log(UScrime[, -2]) 31 | #' crime.ZS <- bas.lm(y ~ ., 32 | #' data = UScrime, 33 | #' prior = "ZS-null", 34 | #' modelprior = uniform(), 35 | #' method = "MCMC", 36 | #' MCMC.iter = 1000 37 | #' ) # short run for the example 38 | #' diagnostics(crime.ZS) 39 | #' @family bas methods 40 | #' @export 41 | diagnostics <- function(obj, type = c("pip", "model"), ...) { 42 | if (obj$call$method == "MCMC") { 43 | for (i in 1:length(type)) { 44 | if (type[i] == "pip") { 45 | plot(obj$probne0.RN, obj$probne0.MCMC, 46 | xlab = "pip (renormalized)", 47 | ylab = "pip (MCMC)", xlim = c(0, 1), ylim = c(0, 1), 48 | main = "Convergence Plot: Posterior Inclusion Probabilities", 49 | ... 50 | ) 51 | abline(0, 1) 52 | } 53 | else { 54 | ax.lim <- range(pretty(c(obj$postprobs.RN, obj$postprobs.MCMC))) 55 | plot(obj$postprobs.RN, obj$postprobs.MCMC, 56 | xlab = "p(M | Y) (renormalized)", 57 | ylab = "p(M | Y) (MCMC)", xlim = ax.lim, ylim = ax.lim, 58 | main = "Convergence Plot: Posterior Model Probabilities", 59 | ... 60 | ) 61 | abline(0, 1) 62 | } 63 | } 64 | } 65 | else { 66 | stop("Diagnostic plots are only availble using method='MCMC' 67 | for sampling with bas. Please rerun.") 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /R/hypergeometric2F1.R: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | # This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | # License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | # 5 | #' Gaussian hypergeometric2F1 function 6 | #' 7 | #' Compute the Gaussian Hypergeometric2F1 function: 2F1(a,b,c,z) = Gamma(b-c) 8 | #' Int_0^1 t^(b-1) (1 - t)^(c -b -1) (1 - t z)^(-a) dt 9 | #' 10 | #' The default is to use the routine hyp2f1.c from the Cephes library. If that 11 | #' return a negative value or Inf, one should try method="Laplace" which is 12 | #' based on the Laplace approximation as described in Liang et al JASA 2008. 13 | #' This is used in the hyper-g prior to calculate marginal likelihoods. 14 | #' 15 | #' @param a arbitrary 16 | #' @param b Must be greater 0 17 | #' @param c Must be greater than b if |z| < 1, and c > b + a if z = 1 18 | #' @param z |z| <= 1 19 | #' @param method The default is to use the Cephes library routine. This 20 | #' sometimes is unstable for large a or z near one returning Inf or negative 21 | #' values. In this case, try method="Laplace", which use a Laplace 22 | #' approximation for tau = exp(t/(1-t)). 23 | #' @param log if TRUE, return log(2F1) 24 | #' @return if log=T returns the log of the 2F1 function; otherwise the 2F1 25 | #' function. 26 | #' @author Merlise Clyde (\email{clyde@@duke.edu}) 27 | #' @references Cephes library hyp2f1.c 28 | #' 29 | #' Liang, F., Paulo, R., Molina, G., Clyde, M. and Berger, J.O. (2005) Mixtures 30 | #' of g-priors for Bayesian Variable Selection. Journal of the American 31 | #' Statistical Association. 103:410-423. \cr 32 | #' \doi{10.1198/016214507000001337} 33 | #' @keywords math 34 | #' @examples 35 | #' hypergeometric2F1(12, 1, 2, .65) 36 | #' @rdname hypergeometric2F1 37 | #' @family special functions 38 | #' @export 39 | hypergeometric2F1 <- function(a, b, c, z, method = "Cephes", log = TRUE) { 40 | out <- 1.0 41 | if (c < b | b < 0) { 42 | warning("Must have c > b > 0 in 2F1 function for integral to converge") 43 | return(Inf) 44 | } 45 | if (abs(z) > 1) { 46 | warning("integral in 2F1 diverges") 47 | return(Inf) 48 | } 49 | if (z == 1.0 & c - b - a <= 0) { 50 | ans <- Inf 51 | } else { 52 | if (method == "Laplace") { 53 | ans <- .C(C_logHyperGauss2F1, as.numeric(a), as.numeric(b), as.numeric(c), as.numeric(z), 54 | out = as.numeric(out))$out 55 | if (!log) ans <- exp(ans) 56 | } 57 | else { 58 | ans <- .C(C_hypergeometric2F1, as.numeric(a), as.numeric(b), as.numeric(c), as.numeric(z), 59 | out = as.numeric(out))$out 60 | if (is.na(ans)) { 61 | warning("2F1 from Cephes routine returned NaN; try Laplace approximation") 62 | return(NA) 63 | } 64 | else { 65 | if (ans < 0) { 66 | warning("2F1 from Cephes library is negative; try Laplace approximation") # nocov 67 | } 68 | if (log) ans <- log(ans) 69 | } 70 | } 71 | } 72 | return(ans) 73 | } 74 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: BAS 2 | Version: 2.0.1 3 | Title: Bayesian Variable Selection and Model Averaging using Bayesian Adaptive Sampling 4 | Authors@R: c(person("Merlise", "Clyde", email="clyde@duke.edu", 5 | role=c("aut","cre", "cph"), 6 | comment=c("ORCID=0000-0002-3595-1872") 7 | ), 8 | person("Michael", "Littman", role="ctb"), 9 | person("Joyee", "Ghosh", role="ctb"), 10 | person("Yingbo", "Li", role="ctb"), 11 | person("Betsy", "Bersson", role="ctb"), 12 | person("Don", "van de Bergh", role="ctb"), 13 | person("Quanli", "Wang", role="ctb")) 14 | Depends: 15 | R (>= 3.0) 16 | Imports: 17 | stats, 18 | graphics, 19 | utils, 20 | grDevices 21 | Suggests: 22 | MASS, 23 | knitr, 24 | ggplot2, 25 | GGally, 26 | rmarkdown, 27 | roxygen2, 28 | dplyr, 29 | glmbb, 30 | testthat, 31 | covr, 32 | faraway 33 | Description: Package for Bayesian Variable Selection and Model Averaging 34 | in linear models and generalized linear models using stochastic or 35 | deterministic sampling without replacement from posterior 36 | distributions. Prior distributions on coefficients are 37 | from Zellner's g-prior or mixtures of g-priors 38 | corresponding to the Zellner-Siow Cauchy Priors or the 39 | mixture of g-priors from Liang et al (2008) 40 | 41 | for linear models or mixtures of g-priors from Li and Clyde 42 | (2019) in generalized linear models. 43 | Other model selection criteria include AIC, BIC and Empirical Bayes 44 | estimates of g. Sampling probabilities may be updated based on the sampled 45 | models using sampling w/out replacement or an efficient MCMC algorithm which 46 | samples models using a tree structure of the model space 47 | as an efficient hash table. See Clyde, Ghosh and Littman (2010) 48 | for details on the sampling algorithms. 49 | Uniform priors over all models or beta-binomial prior distributions on 50 | model size are allowed, and for large p truncated priors on the model 51 | space may be used to enforce sampling models that are full rank. 52 | The user may force variables to always be included in addition to imposing 53 | constraints that higher order interactions are included only if their 54 | parents are included in the model. 55 | This material is based upon work supported by the National Science 56 | Foundation under Division of Mathematical Sciences grant 1106891. 57 | Any opinions, findings, and 58 | conclusions or recommendations expressed in this material are those of 59 | the author(s) and do not necessarily reflect the views of the 60 | National Science Foundation. 61 | License: GPL (>= 3) 62 | URL: https://merliseclyde.github.io/BAS/, https://github.com/merliseclyde/BAS 63 | BugReports: https://github.com/merliseclyde/BAS/issues 64 | Repository: CRAN 65 | NeedsCompilation: yes 66 | ByteCompile: yes 67 | VignetteBuilder: knitr 68 | Encoding: UTF-8 69 | RoxygenNote: 7.3.3 70 | -------------------------------------------------------------------------------- /tests/testthat/test-special-functions.R: -------------------------------------------------------------------------------- 1 | context("special functions") 2 | 3 | test_that("phi1", { 4 | expect_equal( 5 | phi1(1, 2, 1.5, 0, 1 / 100), 6 | hypergeometric2F1(2, 1, 1.5, 1 / 100, log = FALSE) 7 | ) 8 | expect_equal( 9 | phi1(1, 0, 1.5, 3, 1 / 100, log=FALSE), 10 | hypergeometric1F1(1, 1.5, 3, log = FALSE) 11 | ) 12 | expect_error(phi1(c(1, 1), c(2, 2), c(1.5, 1.5), c(3, 3), c(.1))) 13 | expect_equal(TRUE, is.finite(phi1(1, 2, 1.5, 1000, 1/100, log=TRUE))) # Issue #55 14 | expect_equal(FALSE, is.finite(phi1(1, 2, 1.5, 1000, 1/100, log=FALSE))) 15 | expect_length( 16 | phi1(c(1, 1), c(2, 2), c(1.5, 1.5), c(3, 3), c(.1, .1)), 17 | 2 18 | ) 19 | }) 20 | 21 | test_that("2F1", { 22 | expect_warning(hypergeometric2F1(1,0,-1, .5)) 23 | expect_warning(hypergeometric2F1(1,1,.5, .5)) 24 | expect_warning(hypergeometric2F1(1,1,1.5, 1.5)) 25 | expect_warning(hypergeometric2F1(1,1,1.5, -1.5)) 26 | expect_warning(hypergeometric1F1(-1, 2, 3, -.5)) 27 | expect_warning(hypergeometric1F1(1, -2, 3, 0.5)) 28 | expect_warning(hypergeometric2F1(10000,1,.5, .99995)) 29 | expect_equal(Inf, hypergeometric2F1(1,1,2, 1.0)) 30 | expect_equal(TRUE, hypergeometric2F1(1,1,5, 1.0, 31 | method="Laplace", 32 | log=FALSE)>0) 33 | expect_warning(hypergeometric2F1(3,1,1000, .999)) 34 | eps = .Machine$double.eps 35 | c = 3 36 | expect_no_error(hypergeometric2F1(1, c - eps, c, .5)) 37 | expect_no_error(hypergeometric2F1(c-eps, 2, c, .5)) 38 | c = -3 39 | expect_warning(hypergeometric2F1(1, c - eps, c, .5)) 40 | expect_warning(hypergeometric2F1(c-eps, 2, c, .5)) 41 | expect_no_error(hypergeometric2F1(1, 2, 4, .75)) 42 | 43 | }) 44 | 45 | 46 | 47 | #' 48 | 49 | test_that("tcch", { 50 | k = 10; a = 2; b = 3; r = 2; 51 | expect_equal( 52 | # trCCH(a, b, r, s=0, v = 1, k) is the same as 53 | # 2F1(a, r, a + b, 1 - 1/k)*beta(a, b)/k^r 54 | trCCH(a, b, r, s=0, v = 1, k=k) *k^r/beta(a,b), 55 | hypergeometric2F1(a, r, a + b, 1 - 1/k, log = FALSE) 56 | ) 57 | expect_equal( 58 | # trCCH(a, b, r, s=0, v = 1, k) is the same as 59 | # 2F1(a, r, a + b, 1 - 1/k)*beta(a, b)/k^r 60 | trCCH(a, b, r, s=0, v = 1, k=k, log=TRUE) +log(k)*r - lbeta(a,b), 61 | hypergeometric2F1(a, r, a + b, 1 - 1/k, log = TRUE) 62 | ) 63 | s = 3; r = 0; v = 1; k = 10 64 | # beta(a, b)*hypergeometric1F1(a, a+b, -s, log = FALSE) is the same as 65 | # trCCH(a, b, r, s, v, k) 66 | expect_equal( 67 | beta(a, b)*hypergeometric1F1(a, a+b, -s, log = FALSE) , 68 | trCCH(a, b, r, s, v, k) 69 | ) 70 | a = 1.5; b = 3; k = 1.25; s = 40; r = 2; v = 1; k = 1.25 71 | expect_equal( 72 | phi1(a, r, a + b, -s, 1 - 1/k, log=FALSE)*(k^-r)*gamma(a)*gamma(b)/gamma(a+b), 73 | trCCH(a,b,r,s,v,k), tolerance = .00001 74 | ) 75 | expect_error(trCCH(c(1, 1), c(2, 2), c(1.5, 1.5), c(1, 1), c(1), c(1))) 76 | s = 10000 77 | expect_equal(TRUE, is.finite(trCCH(a,b,r,s,v,k, log=TRUE))) # Issue #55 78 | expect_equal(TRUE, is.finite(trCCH(a,b,r,s,v,k, log=FALSE))) 79 | expect_length(trCCH(c(1, 1), c(2, 2), c(1.5, 1.5), c(1, 1), c(1,1), c(1,1)), 80 | 2 81 | ) 82 | }) 83 | -------------------------------------------------------------------------------- /man/bayesglm.fit.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bayesglm_fit.R 3 | \name{bayesglm.fit} 4 | \alias{bayesglm.fit} 5 | \title{Fitting Generalized Linear Models and Bayesian marginal likelihood 6 | evaluation} 7 | \usage{ 8 | bayesglm.fit( 9 | x, 10 | y, 11 | weights = rep(1, nobs), 12 | start = NULL, 13 | etastart = NULL, 14 | mustart = NULL, 15 | offset = rep(0, nobs), 16 | family = binomial(), 17 | coefprior = bic.prior(nobs), 18 | control = glm.control(), 19 | intercept = TRUE 20 | ) 21 | } 22 | \arguments{ 23 | \item{x}{design matrix} 24 | 25 | \item{y}{response} 26 | 27 | \item{weights}{optional vector of weights to be used in the fitting process. 28 | Should be NULL or a numeric vector.} 29 | 30 | \item{start}{starting value for coefficients in the linear predictor} 31 | 32 | \item{etastart}{starting values for the linear predictor} 33 | 34 | \item{mustart}{starting values for the vectors of means} 35 | 36 | \item{offset}{a priori known component to be included in the linear 37 | predictor} 38 | 39 | \item{family}{a description of the error distribution and link function for 40 | exponential family; currently only binomial(), poisson(), and Gamma() with canonical 41 | links are implemented.} 42 | 43 | \item{coefprior}{function specifying prior distribution on coefficients with 44 | optional hyperparameters leading to marginal likelihood calculations; 45 | options include \code{bic.prior()},\code{ aic.prior()}, and 46 | \code{ic.prior()}} 47 | 48 | \item{control}{a list of parameters that control convergence in the fitting 49 | process. See the documentation for \code{glm.control()}} 50 | 51 | \item{intercept}{should an intercept be included in the null model?} 52 | } 53 | \value{ 54 | \item{coefficients}{MLEs} \item{se}{Standard errors of coefficients 55 | based on the sqrt of the diagonal of the inverse information matrix} 56 | \item{mu}{fitted mean} \item{rank}{numeric rank of the fitted linear model} 57 | \item{deviance}{minus twice the log likelihood evaluated at the MLEs} 58 | \item{g}{value of g in g-priors} \item{shrinkage}{shrinkage factor for 59 | coefficients in linear predictor} \item{RegSS}{quadratic form 60 | beta'I(beta)beta used in shrinkage} \item{logmarglik}{the log marginal or 61 | integrated log likelihood (up to a constant)} 62 | } 63 | \description{ 64 | A version of glm.fit rewritten in C; also returns marginal likelihoods for 65 | Bayesian model comparison 66 | } 67 | \details{ 68 | C version of glm-fit. For different prior choices returns, marginal 69 | likelihood of model using a Laplace approximation. 70 | } 71 | \examples{ 72 | data(Pima.tr, package="MASS") 73 | Y <- as.numeric(Pima.tr$type) - 1 74 | X <- cbind(1, as.matrix(Pima.tr[,1:7])) 75 | out <- bayesglm.fit(X, Y, family=binomial(),coefprior=bic.prior(n=length(Y))) 76 | out$coef 77 | out$se 78 | # using built in function 79 | glm(type ~ ., family=binomial(), data=Pima.tr) 80 | 81 | } 82 | \references{ 83 | \code{\link{glm}} 84 | } 85 | \seealso{ 86 | \code{\link{bic.prior}} 87 | } 88 | \author{ 89 | Merlise Clyde translated the \code{\link{glm.fit}} from R base into 90 | C using the .Call interface 91 | } 92 | \keyword{GLM} 93 | \keyword{regression} 94 | -------------------------------------------------------------------------------- /tests/testthat/test-priorprobs.R: -------------------------------------------------------------------------------- 1 | # issue #87 Prior inclusions probabilities appear incorrect for a Bernoulli(.2) 2 | # prior when always including one other predictor 3 | 4 | 5 | test_that("bernoulli prior and include.always", { 6 | 7 | # helper function to compute prior inclusion probabilities 8 | compute_prior_inclusion_probs <- function(fit) { 9 | 10 | modelProbs <- fit$priorprobs/sum(fit$priorprobs) 11 | priorProbs <- as.vector(t(modelProbs)%*% which.matrix(fit$which, fit$n.vars)) 12 | names(priorProbs) <- fit$namesx 13 | 14 | return(priorProbs) 15 | } 16 | 17 | # some basic data 18 | n <- 100 19 | p <- 6 20 | x <- matrix(rnorm(n*p), n, p) 21 | beta <- rnorm(p) 22 | y <- x %*% beta + rnorm(n) 23 | 24 | data <- data.frame(y, x) 25 | colnames(data) <- c("y", letters[1:p]) 26 | 27 | 28 | fit1 <- bas.lm( 29 | formula = y ~ ., 30 | data = data, 31 | prior = "hyper-g-laplace", 32 | alpha = 3, 33 | modelprior = Bernoulli(.2), 34 | n.models = NULL, 35 | method = "BAS", 36 | MCMC.iterations = NULL, 37 | include.always = ~ a, 38 | # initprobs = c(1, 1, seq(.5, 0.1, length=5)), 39 | weights = NULL, 40 | renormalize = TRUE 41 | ) 42 | 43 | fit2 <- bas.lm( 44 | formula = y ~ ., 45 | data = data, 46 | prior = "hyper-g-laplace", 47 | alpha = 3, 48 | modelprior = Bernoulli(c(1,1, rep(.2,5))), 49 | n.models = NULL, 50 | method = "BAS", 51 | MCMC.iterations = NULL, 52 | include.always = ~ a, 53 | # initprobs = c(1, 1, seq(.5, 0.1, length=5)), 54 | weights = NULL, 55 | renormalize = TRUE 56 | ) 57 | 58 | 59 | fit3 <- bas.lm( 60 | formula = y ~ ., 61 | data = data, 62 | prior = "hyper-g-laplace", 63 | alpha = 3, 64 | modelprior = Bernoulli(c(1,1, rep(.2,5))), 65 | # include.always = ~ a, 66 | n.models = NULL, 67 | method = "BAS", 68 | MCMC.iterations = NULL, 69 | # initprobs = c(1, seq(.5, 0.1, length=5)), 70 | weights = NULL, 71 | renormalize = TRUE 72 | ) 73 | 74 | compute_prior_inclusion_probs(fit1) 75 | compute_prior_inclusion_probs(fit2) 76 | compute_prior_inclusion_probs(fit3) 77 | 78 | # issue #87 should be equal 79 | expect_equal(compute_prior_inclusion_probs(fit1), compute_prior_inclusion_probs(fit2)) 80 | 81 | hyp = c(1,.5, 1, .5, 1, .5, .5) 82 | 83 | fit4 <- bas.lm( 84 | formula = y ~ ., 85 | data = data, 86 | prior = "hyper-g-laplace", 87 | alpha = 3, 88 | modelprior = Bernoulli(hyp), 89 | n.models = NULL, 90 | method = "BAS", 91 | MCMC.iterations = NULL, 92 | # initprobs = c(1, seq(.5, 0.1, length=5)), 93 | weights = NULL, 94 | renormalize = TRUE 95 | ) 96 | 97 | expect_equal(hyp, as.numeric(compute_prior_inclusion_probs(fit4))) 98 | 99 | # issue #87 should be equal 100 | expect_equal(compute_prior_inclusion_probs(fit2), compute_prior_inclusion_probs(fit3)) 101 | } 102 | ) 103 | 104 | 105 | -------------------------------------------------------------------------------- /R/outliers.R: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | # This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | # License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | # 5 | ########## Functions for Chaloner and Brant ############### 6 | #' Bayesian Outlier Detection 7 | #' 8 | #' Calculate the posterior probability that the absolute value of 9 | #' error exceeds more than k standard deviations 10 | #' P(|epsilon_j| > k sigma | data) 11 | #' under the model Y = X B + epsilon, 12 | #' with epsilon ~ N(0, sigma^2 I) 13 | #' based on the paper 14 | #' by Chaloner & Brant Biometrika (1988). Either k or the prior 15 | #' probability of there being no outliers must be provided. 16 | #' This only uses the reference prior p(B, sigma) = 1; 17 | #' other priors and model averaging to come. 18 | 19 | #' 20 | #' @param lmobj An object of class `lm` 21 | #' @param k number of standard deviations used in calculating 22 | #' probability of an individual case being an outlier, 23 | #' P(|error| > k sigma | data) 24 | #' @param prior.prob The prior probability of there being no 25 | #' outliers in the sample of size n 26 | #' @return Returns a list of three items: 27 | #' \item{e}{residuals} 28 | #' \item{hat}{leverage values} 29 | #' \item{prob.outlier}{posterior probabilities of a point being an outlier} 30 | #' \item{prior.prob}{prior probability of a point being an outlier} 31 | #' @references Chaloner & Brant (1988) 32 | #' A Bayesian Approach to Outlier Detection and Residual Analysis 33 | #' Biometrika (1988) 75, 651-659 34 | #' @examples 35 | #' data("stackloss") 36 | #' stack.lm <- lm(stack.loss ~ ., data = stackloss) 37 | #' stack.outliers <- Bayes.outlier(stack.lm, k = 3) 38 | #' plot(stack.outliers$prob.outlier, type = "h", ylab = "Posterior Probability") 39 | #' # adjust for sample size for calculating prior prob that a 40 | #' # a case is an outlier 41 | #' stack.outliers <- Bayes.outlier(stack.lm, prior.prob = 0.95) 42 | #' # cases where posterior probability exceeds prior probability 43 | #' which(stack.outliers$prob.outlier > stack.outliers$prior.prob) 44 | #' @export 45 | Bayes.outlier <- function(lmobj, k, prior.prob) { 46 | e <- residuals(lmobj) 47 | h <- hatvalues(lmobj) 48 | alpha <- (lmobj$df.residual) / 2 49 | rate <- (lmobj$df.residual * (summary(lmobj)$sigma)^2) / 2 50 | n <- length(e) 51 | 52 | if (missing(k) & missing(prior.prob)) { 53 | stop("please provide either k or the prior probability of no outliers") 54 | } 55 | else { 56 | if (missing(k)) k <- qnorm(.5 + .5 * (prior.prob^(1 / n))) 57 | } 58 | pr <- rep(0, n) 59 | for (i in 1:n) { 60 | pr[i] <- integrate( 61 | outlier.prob, 62 | lower = 0, 63 | upper = Inf, 64 | ehat = e[i], 65 | hii = h[i], 66 | alpha = alpha, 67 | rate = rate, 68 | nsd = k 69 | )$value 70 | } 71 | return(list( 72 | e = e, 73 | hat = h, 74 | prob.outlier = pr, 75 | prior.prob = pnorm(-k) * 2 76 | )) 77 | } 78 | 79 | outlier.prob <- function(phi, ehat, hii, alpha, rate, nsd) { 80 | z1 <- (nsd - ehat * sqrt(phi)) / sqrt(hii) 81 | z2 <- (-nsd - ehat * sqrt(phi)) / sqrt(hii) 82 | pr.phi <- (1 - pnorm(z1) + pnorm(z2)) * dgamma(phi, shape = alpha, rate = rate) 83 | return(pr.phi) 84 | } 85 | -------------------------------------------------------------------------------- /tests/testthat/test-coefficients.R: -------------------------------------------------------------------------------- 1 | context("coefficients.bas") 2 | 3 | test_that("coefficients", { 4 | data("Hald") 5 | hald_gprior <- bas.lm(Y ~ ., data = Hald, prior = "ZS-null", 6 | modelprior = beta.binomial(1, 1)) 7 | expect_is(coefficients(hald_gprior), "coef.bas") 8 | expect_length(coefficients(hald_gprior, estimator='MPM'),11) 9 | expect_equal("HPM", coefficients(hald_gprior, estimator='HPM')$estimator) 10 | expect_error(coefficients(hald_gprior, estimator='BPM')) 11 | expect_null(print(coefficients(hald_gprior, estimator="BMA"))) 12 | expect_equal(coefficients(hald_gprior, estimator='HPM')$postmean, 13 | coefficients(hald_gprior, estimator='BMA', n.models=1)$postmean) 14 | 15 | coef_hald <- coef(hald_gprior) 16 | confint_hald <- confint(coef_hald) 17 | expect_is(confint_hald, "confint.bas") 18 | expect_is(confint(coef_hald, approx=FALSE, nsim=5000), "confint.bas") 19 | expect_length(confint(coef_hald, parm="X4"), 3) 20 | expect_null(plot(confint(coef_hald, parm=2:5))) 21 | expect_null(plot(confint(coef(hald_gprior, estimator='HPM')))) 22 | expect_null(plot(confint(coef(hald_gprior, estimator='HPM')), 23 | horizontal = TRUE)) 24 | expect_error(confint(coef(hald_gprior), nsim=1)) 25 | }) 26 | 27 | test_that("plot posterior coefficients", { 28 | data(UScrime, package="MASS") 29 | UScrime[,-2] <- log(UScrime[,-2]) 30 | crime_bic <- bas.lm(y ~ ., data=UScrime, n.models=2^10, prior="BIC") 31 | crime_coef <- coef(crime_bic) 32 | expect_null(plot(crime_coef, subset=2:4, ask=TRUE)) 33 | expect_null(plot(crime_coef, ask=FALSE)) 34 | }) 35 | 36 | # GitHub issue #56 and #39 37 | 38 | test_that("formula and env issues with MPM",{ 39 | data(UScrime, package = "MASS") 40 | UScrime <- UScrime[, 1:5] 41 | 42 | crime.bic1 <- bas.lm(formula = M ~ So + Ed + Po1 + Po2, 43 | data = UScrime, 44 | prior = "JZS", 45 | initprobs = c(1, 0.5, 0.5, 0.5, 0.5), 46 | renormalize = TRUE) 47 | coef.mpm1 <- coef(crime.bic1, estimator = "MPM") 48 | 49 | form <- M ~ So + Ed + Po1 + Po2 50 | crime.bic2 <- bas.lm(formula = form, 51 | data = UScrime, 52 | prior = "JZS", 53 | initprobs = c(1, 0.5, 0.5, 0.5, 0.5), 54 | renormalize = TRUE) 55 | 56 | coef.mpm2 = coef(crime.bic2, estimator = "MPM") 57 | expect_equal(coef.mpm1, coef.mpm2) 58 | } 59 | ) 60 | 61 | 62 | test_that("env and lm", { 63 | data(UScrime, package = "MASS") 64 | UScrime <- UScrime[, 1:5] 65 | 66 | mylm = function(object) { 67 | modelform = as.formula(eval(object$call$formula, parent.frame())) 68 | environment(modelform) = environment() 69 | data = eval(object$call$data) 70 | weights = eval(object$call$weights) 71 | 72 | object = lm(formula = modelform, 73 | data = data, 74 | weights = weights) 75 | return(object) } 76 | 77 | 78 | crime.lm1 <- lm(formula = M ~ So + Ed + Po1 + Po2, data = UScrime) 79 | tmp1 = mylm(crime.lm1) 80 | 81 | form = M ~ So + Ed + Po1 + Po2 82 | crime.lm2 <- lm(formula = form, data = UScrime) 83 | 84 | tmp = mylm(crime.lm2) 85 | 86 | expect_equal(coef(tmp), coef(tmp1)) 87 | 88 | }) 89 | 90 | -------------------------------------------------------------------------------- /.github/workflows/rhub.yaml: -------------------------------------------------------------------------------- 1 | # R-hub's generic GitHub Actions workflow file. It's canonical location is at 2 | # https://github.com/r-hub/actions/blob/v1/workflows/rhub.yaml 3 | # You can update this file to a newer version using the rhub2 package: 4 | # 5 | # rhub::rhub_setup() 6 | # 7 | # It is unlikely that you need to modify this file manually. 8 | 9 | name: R-hub 10 | run-name: "${{ github.event.inputs.id }}: ${{ github.event.inputs.name || format('Manually run by {0}', github.triggering_actor) }}" 11 | 12 | on: 13 | workflow_dispatch: 14 | inputs: 15 | config: 16 | description: 'A comma separated list of R-hub platforms to use.' 17 | type: string 18 | default: 'linux,windows,macos' 19 | name: 20 | description: 'Run name. You can leave this empty now.' 21 | type: string 22 | id: 23 | description: 'Unique ID. You can leave this empty now.' 24 | type: string 25 | 26 | jobs: 27 | 28 | setup: 29 | runs-on: ubuntu-latest 30 | outputs: 31 | containers: ${{ steps.rhub-setup.outputs.containers }} 32 | platforms: ${{ steps.rhub-setup.outputs.platforms }} 33 | 34 | steps: 35 | # NO NEED TO CHECKOUT HERE 36 | - uses: r-hub/actions/setup@v1 37 | with: 38 | config: ${{ github.event.inputs.config }} 39 | id: rhub-setup 40 | 41 | linux-containers: 42 | needs: setup 43 | if: ${{ needs.setup.outputs.containers != '[]' }} 44 | runs-on: ubuntu-latest 45 | name: ${{ matrix.config.label }} 46 | strategy: 47 | fail-fast: false 48 | matrix: 49 | config: ${{ fromJson(needs.setup.outputs.containers) }} 50 | container: 51 | image: ${{ matrix.config.container }} 52 | 53 | steps: 54 | - uses: r-hub/actions/checkout@v1 55 | - uses: r-hub/actions/platform-info@v1 56 | with: 57 | token: ${{ secrets.RHUB_TOKEN }} 58 | job-config: ${{ matrix.config.job-config }} 59 | - uses: r-hub/actions/setup-deps@v1 60 | with: 61 | token: ${{ secrets.RHUB_TOKEN }} 62 | job-config: ${{ matrix.config.job-config }} 63 | - uses: r-hub/actions/run-check@v1 64 | with: 65 | token: ${{ secrets.RHUB_TOKEN }} 66 | job-config: ${{ matrix.config.job-config }} 67 | 68 | other-platforms: 69 | needs: setup 70 | if: ${{ needs.setup.outputs.platforms != '[]' }} 71 | runs-on: ${{ matrix.config.os }} 72 | name: ${{ matrix.config.label }} 73 | strategy: 74 | fail-fast: false 75 | matrix: 76 | config: ${{ fromJson(needs.setup.outputs.platforms) }} 77 | 78 | steps: 79 | - uses: r-hub/actions/checkout@v1 80 | - uses: r-hub/actions/setup-r@v1 81 | with: 82 | job-config: ${{ matrix.config.job-config }} 83 | token: ${{ secrets.RHUB_TOKEN }} 84 | - uses: r-hub/actions/platform-info@v1 85 | with: 86 | token: ${{ secrets.RHUB_TOKEN }} 87 | job-config: ${{ matrix.config.job-config }} 88 | - uses: r-hub/actions/setup-deps@v1 89 | with: 90 | job-config: ${{ matrix.config.job-config }} 91 | token: ${{ secrets.RHUB_TOKEN }} 92 | - uses: r-hub/actions/run-check@v1 93 | with: 94 | job-config: ${{ matrix.config.job-config }} 95 | token: ${{ secrets.RHUB_TOKEN }} 96 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at clyde@duke.edu. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /src/mtherr.c: -------------------------------------------------------------------------------- 1 | // # nocov start 2 | 3 | /* 4 | Cephes Math Library Release 2.0: April, 1987 5 | Copyright 1984, 1987 by Stephen L. Moshier 6 | Direct inquiries to 30 Frost Street, Cambridge, MA 02140 7 | */ 8 | /* mtherr.c 9 | * 10 | * Library common error handling routine 11 | * 12 | * 13 | * 14 | * SYNOPSIS: 15 | * 16 | * char *fctnam; 17 | * int code; 18 | * int mtherr(); 19 | * 20 | * mtherr( fctnam, code ); 21 | * 22 | * 23 | * 24 | * DESCRIPTION: 25 | * 26 | * This routine may be called to report one of the following 27 | * error conditions (in the include file mconf.h). 28 | * 29 | * Mnemonic Value Significance 30 | * 31 | * DOMAIN 1 argument domain error 32 | * SING 2 function singularity 33 | * OVERFLOW 3 overflow range error 34 | * UNDERFLOW 4 underflow range error 35 | * TLOSS 5 total loss of precision 36 | * PLOSS 6 partial loss of precision 37 | * EDOM 33 Unix domain error code 38 | * ERANGE 34 Unix range error code 39 | * 40 | * The default version of the file prints the function name, 41 | * passed to it by the pointer fctnam, followed by the 42 | * error condition. The display is directed to the standard 43 | * output device. The routine then returns to the calling 44 | * program. Users may wish to modify the program to abort by 45 | * calling exit() under severe error conditions such as domain 46 | * errors. 47 | * 48 | * Since all error conditions pass control to this function, 49 | * the display may be easily changed, eliminated, or directed 50 | * to an error logging device. 51 | * 52 | * SEE ALSO: 53 | * 54 | * mconf.h 55 | * 56 | */ 57 | 58 | 59 | 60 | #include 61 | #include 62 | // #include "mconf.h" 63 | 64 | /* Constant definitions for math error conditions 65 | */ 66 | 67 | #define DOMAIN 1 /* argument domain error */ 68 | #define SING 2 /* argument singularity */ 69 | #define OVERFLOW 3 /* overflow range error */ 70 | #define UNDERFLOW 4 /* underflow range error */ 71 | #define TLOSS 5 /* total loss of precision */ 72 | #define PLOSS 6 /* partial loss of precision */ 73 | 74 | #define EDOM 33 75 | #define ERANGE 34 76 | 77 | int merror = 0; 78 | 79 | /* Notice: the order of appearance of the following 80 | * messages is bound to the error codes defined 81 | * in mconf.h. 82 | */ 83 | static char *ermsg[7] = { 84 | "unknown", /* error code 0 */ 85 | "domain", /* error code 1 */ 86 | "singularity", /* et seq. */ 87 | "overflow", 88 | "underflow", 89 | "total loss of precision", 90 | "partial loss of precision" 91 | }; 92 | 93 | 94 | int mtherr(char *name, int code ) 95 | // char *name; 96 | // int code; 97 | { 98 | 99 | /* Display string passed by calling program, 100 | * which is supposed to be the name of the 101 | * function in which the error occurred: 102 | */ 103 | warning( "\n%s ", name ); 104 | 105 | /* Set global error message word */ 106 | merror = code; 107 | 108 | /* Display error message defined 109 | * by the code argument. 110 | */ 111 | if( (code <= 0) || (code >= 7) ) 112 | code = 0; 113 | warning( "%s error\n", ermsg[code] ); 114 | 115 | /* Return to calling 116 | * program 117 | */ 118 | return( 0 ); 119 | } 120 | 121 | // # nocov end 122 | -------------------------------------------------------------------------------- /R/update.R: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | # This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | # License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | # 5 | #' Update BAS object using a new prior 6 | #' 7 | #' Update a BMA object using a new prior distribution on the coefficients. 8 | #' 9 | #' Recomputes the marginal likelihoods for the new methods for models already 10 | #' sampled in current object. 11 | #' 12 | #' @aliases update update.bas 13 | #' @param object BMA object to update 14 | #' @param newprior Update posterior model probabilities, probne0, shrinkage, 15 | #' logmarg, etc, using prior based on newprior. See \code{\link{bas}} for 16 | #' available methods 17 | #' @param alpha optional new value of hyperparameter in prior for method 18 | #' @param ... optional arguments 19 | #' @return A new object of class BMA 20 | #' @author Merlise Clyde \email{clyde@@stat.duke.edu} 21 | #' @seealso \code{\link{bas}} for available methods and choices of alpha 22 | #' @references Clyde, M. Ghosh, J. and Littman, M. (2010) Bayesian Adaptive 23 | #' Sampling for Variable Selection and Model Averaging. Journal of 24 | #' Computational Graphics and Statistics. 20:80-101 \cr 25 | #' \doi{10.1198/jcgs.2010.09049} 26 | #' @keywords regression 27 | #' @examples 28 | #' 29 | #' \donttest{ 30 | #' library(MASS) 31 | #' data(UScrime) 32 | #' UScrime[,-2] <- log(UScrime[,-2]) 33 | #' crime.bic <- bas.lm(y ~ ., data=UScrime, n.models=2^10, prior="BIC",initprobs= "eplogp") 34 | #' crime.ebg <- update(crime.bic, newprior="EB-global") 35 | #' crime.zs <- update(crime.bic, newprior="ZS-null") 36 | #' } 37 | #' 38 | #' @rdname update 39 | #' @method update bas 40 | #' @family bas methods 41 | #' @export 42 | update.bas <- function(object, newprior, alpha = NULL, ...) { 43 | method.num <- switch(newprior, 44 | "g-prior" = 0, 45 | "hyper-g" = 1, 46 | "EB-local" = 2, 47 | "BIC" = 3, 48 | "ZS-null" = 4, 49 | "ZS-full" = 5, 50 | "hyper-g-laplace" = 6, 51 | "AIC" = 7, 52 | "EB-global" = 2, 53 | "hyper-g-n" = 8, 54 | "JZS" = 9, 55 | ) 56 | if (is.null(alpha) && 57 | (method.num == 0 || method.num == 1 || method.num == 6 || method.num == 8)) { 58 | stop(paste("Must specify a value of alpha for", newprior)) 59 | } 60 | 61 | if (is.null(alpha)) alpha <- 0.0 62 | object$alpha <- alpha 63 | 64 | if (newprior == "EB-global") { 65 | object <- EB.global(object) 66 | } else { 67 | object$prior <- newprior 68 | SSY <- sum((object$Y - mean(object$Y))^2) 69 | R2Full <- summary(lm(object$Y ~ object$X[, -1]))$r.squared 70 | logmarg <- object$logmarg 71 | shrinkage <- object$shrinkage 72 | tmp <- .C(C_gexpectations_vect, 73 | nmodels = as.integer(length(object$which)), 74 | p = as.integer(object$n.vars), pmodel = as.integer(object$rank), 75 | nobs = as.integer(object$n), R2 = object$R2, alpha = as.double(alpha), 76 | method = as.integer(method.num), RSquareFull = as.double(R2Full), SSY = as.double(SSY), 77 | logmarg = logmarg, shrinkage = shrinkage 78 | ) 79 | object$logmarg <- tmp$logmarg 80 | object$shrinkage <- tmp$shrinkage 81 | object$postprobs <- exp(object$logmarg - min(object$logmarg)) * object$priorprobs 82 | object$postprobs <- object$postprobs / sum(object$postprobs) 83 | which <- which.matrix(object$which, object$n.vars) 84 | object$probne0 <- object$postprobs %*% which 85 | } 86 | return(object) 87 | } 88 | -------------------------------------------------------------------------------- /R/EB_global.R: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | # This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | # License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | # 5 | #' Find the global Empirical Bayes estimates for BMA 6 | #' 7 | #' Finds the global Empirical Bayes estimates of g in Zellner's g-prior and 8 | #' model probabilities 9 | #' 10 | #' Uses the EM algorithm in Liang et al to estimate the type II MLE of g in 11 | #' Zellner's g prior 12 | #' 13 | #' @aliases EB.global EB.global.bas 14 | #' @param object A 'bas' object created by \code{\link{bas}} 15 | #' @param tol tolerance for estimating g 16 | #' @param g.0 initial value for g 17 | #' @param max.iterations Maximum number of iterations for the EM algorithm 18 | #' @return An object of class 'bas' using Zellner's g prior with an estimate of 19 | #' g based on all models 20 | #' @author Merlise Clyde \email{clyde@@stat.duke.edu} 21 | #' @seealso \code{\link{bas}}, \code{\link{update}} 22 | #' @references Liang, F., Paulo, R., Molina, G., Clyde, M. and Berger, J.O. 23 | #' (2008) Mixtures of g-priors for Bayesian Variable Selection. Journal of the 24 | #' American Statistical Association. 103:410-423. \cr 25 | #' \doi{10.1198/016214507000001337} 26 | #' @keywords regression 27 | #' @examples 28 | #' 29 | #' library(MASS) 30 | #' data(UScrime) 31 | #' UScrime[,-2] = log(UScrime[,-2]) 32 | #' # EB local uses a different g within each model 33 | #' crime.EBL = bas.lm(y ~ ., data=UScrime, n.models=2^15, 34 | #' prior="EB-local", initprobs= "eplogp") 35 | #' # use a common (global) estimate of g 36 | #' crime.EBG = EB.global(crime.EBL) 37 | #' 38 | #' 39 | #' @rdname EB.global 40 | #' @family coef priors 41 | #' @export 42 | EB.global = function(object, tol= .1, g.0=NULL, max.iterations=100) { 43 | n = object$n 44 | SSY = var(object$Y)*(n-1) 45 | SSE <- (1.0 - object$R2)*SSY 46 | SSR = SSY - SSE 47 | p = object$size - 1 48 | R2 = object$R2 49 | prior = object$priorprobs 50 | 51 | postmodelprob <- function(R2, p, n, g, prior=1) { 52 | logmarg <- .5*((n - 1 - p)*log(1 + g) - (n-1)*log( 1 + g*(1 - R2))) 53 | logmarg[p == 0] = 0 54 | modelprob <- exp(logmarg - max(logmarg)) 55 | modelprob <- modelprob*prior/sum(modelprob*prior) 56 | if (any(is.na(modelprob))) warning("NA's in modelprobs") # nocov 57 | return(modelprob) 58 | } 59 | 60 | best = sort.list(-object$logmarg)[1] 61 | sbest = min(object$shrinkage[best], .99) 62 | 63 | if (is.null(g.0)) g.0 = sbest/(1 - sbest) 64 | tau.0 = g.0 + 1 65 | phi = (n - 1)/(SSY - (g.0/(1 + g.0))*SSR) 66 | post.prob = postmodelprob(object$R2,p, n, max(tau.0 - 1, 0), prior) 67 | tau.0 = sum(post.prob*SSR*phi)/(sum(post.prob*p)) 68 | tau = tau.0 - 2*tol 69 | it = 0 70 | 71 | while (abs(tau - tau.0) > tol | it < max.iterations) { 72 | g = max(tau - 1, 0) 73 | phi = (n - 1)/(SSY - (g/(1 + g))*SSR) 74 | post.prob = postmodelprob(object$R2,p, n, g, prior) 75 | tau.0 = tau 76 | tau = sum(post.prob*SSR*phi)/(sum(post.prob*p)) 77 | it = it + 1 78 | } 79 | 80 | g = max(tau -1, 0) 81 | logmarg = .5*((n -1 - p)*log(1 + g) - (n-1)*log( 1 + g*(1 - R2))) 82 | logmarg[p == 0] = 0 83 | postprobs = postmodelprob(object$R2,p, n, g, prior) 84 | which = which.matrix(object$which, object$n.var) 85 | object$probne0 = as.vector(postprobs %*% which) 86 | object$postprobs=postprobs 87 | object$g = g 88 | object$logmarg = logmarg 89 | object$shrinkage = object$shrinkage*0 + g/(1 + g) 90 | object$method = "EB-global" 91 | return(object) 92 | } 93 | 94 | -------------------------------------------------------------------------------- /src/E_ZS.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | // This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | // License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | // SPDX-License-Identifier: GPL-3.0 5 | // 6 | #include 7 | #include 8 | #include 9 | #include 10 | #define lgamma lgammafn 11 | double E_ZS_approx_null(double R2, int n, int k){ 12 | 13 | /* this computes a Laplace approximation to the posterior expectation 14 | of g/(1+g) under model M_k with $k$ covariates; there is a common 15 | intercept 16 | 17 | E[g/(1+g) | y, M_k] 18 | 19 | R2 = 1-SSE/SST; the coefficient of determination 20 | n = sample size; 21 | k = number of covariates of the current model 22 | 23 | The prior under consideration is Zellner & Siow (1980) 24 | */ 25 | 26 | /* this version: JAN 19 2003 */ 27 | 28 | void posroot(double a, double b, double c, double *root, double *status); 29 | double h1(double g, double eps, int n, int k); 30 | double h2(double g, double eps, int n, int k); 31 | double infoh1(double g, double eps, int n, int k); 32 | double infoh2(double g, double eps, int n, int k); 33 | 34 | double status,root1,root2; 35 | double a,b,c,aux,eps,denom,numer, s; 36 | 37 | eps=1.0-R2; 38 | 39 | aux=-eps*((double)k+3.); 40 | a=(double)n-(double)k-4.; 41 | b=(double)n*(1.+eps)-1.; 42 | c=(double)n; 43 | 44 | a=a/aux; 45 | b=b/aux; 46 | c=c/aux; 47 | numer = 1.0; 48 | denom = 1.0; 49 | 50 | if (k == 0 || n <= k+1 || R2 >= 1.0) { return(0.0); } 51 | else { 52 | posroot(a,b,c,&root1,&status); 53 | 54 | if(status!=1.){ 55 | // # nocov start 56 | if(status==0.) error("No positive roots for the numerator R2=%lf n=%d k=%d\n", 57 | R2, n, k); 58 | else error("More than one positive root for the numerator\n"); 59 | // # nocov end 60 | } 61 | else{ 62 | numer=h1(root1,eps,n,k)-log(-infoh1(root1,eps,n,k))/2.; 63 | } 64 | 65 | aux=-eps*((double)k+3.); 66 | a=(double)n-(double)k-2.*eps-4.; 67 | b=(double)n*(1.+eps)-3.; 68 | c=(double)n; 69 | 70 | a=a/aux; 71 | b=b/aux; 72 | c=c/aux; 73 | 74 | 75 | posroot(a,b,c,&root2,&status); 76 | 77 | if(status!=1.){ 78 | // # nocov start 79 | if(status==0.) error("\n No positive roots for the denominator R2=%lf n=%d k=%d\n\n", 80 | R2, n, k); 81 | else error("\n More than one positive root for the denominator\n"); 82 | // # nocov end 83 | } 84 | else{ 85 | denom=h2(root2,eps,n,k)-log(-infoh2(root2,eps,n,k))/2.; 86 | } 87 | s = exp(numer-denom); 88 | return(s); 89 | } 90 | } 91 | 92 | double h1(double g, double eps, int n, int k){ 93 | double aux; 94 | 95 | aux=((double)n-3.-(double)k)*log(1.+g)-((double)n-1.)*log(1.+eps*g)- 96 | log(g)-((double)n)/g; 97 | aux=aux/2.; 98 | return(aux); 99 | } 100 | 101 | double h2(double g, double eps, int n, int k){ 102 | double aux; 103 | 104 | aux=((double)n-1.-(double)k)*log(1.+g)-((double)n-1.)*log(1.+eps*g)- 105 | 3*log(g)-((double)n)/g; 106 | aux=aux/2.; 107 | return(aux); 108 | } 109 | 110 | double infoh1(double g, double eps, int n, int k){ 111 | double aux; 112 | aux= -((double)n-3.-(double)k)/R_pow_di(1.+g,2); 113 | aux=aux+((double)n-1.)*R_pow_di(eps,2)/R_pow_di(1.+eps*g,2)+1./R_pow_di(g,2); 114 | aux=aux-2.*(double)n/R_pow_di(g,3); 115 | aux=aux/2.; 116 | return(aux); 117 | } 118 | 119 | double infoh2(double g, double eps, int n, int k){ 120 | double aux; 121 | aux= -((double)n-1.-(double)k)/R_pow_di(1.+g,2); 122 | aux=aux+((double)n-1.)*R_pow_di(eps,2)/R_pow_di(1.+eps*g,2)+3./R_pow_di(g,2); 123 | aux=aux-2.*(double)n/R_pow_di(g,3); 124 | aux=aux/2.; 125 | return(aux); 126 | } 127 | 128 | -------------------------------------------------------------------------------- /src/hypergeometric1F1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | extern double hyperg(double, double, double), lgammafn(double); 6 | double loghyperg1F1_laplace(double, double, double); 7 | 8 | double loghyperg1F1(double a, double b, double x, int laplace) 9 | { 10 | double y = 1.0; 11 | 12 | if (laplace == 0) { 13 | if (x <0) { 14 | /* Since Linux system tends to report error for negative x, we 15 | use the following fomular to convert it to positive value 16 | 1F1(a, b, x) = 1F1(b - a, b, -x) * exp(x) */ 17 | y = log(hyperg(b-a, b, -x)) + x; 18 | } 19 | else { 20 | y = log( hyperg(a, b, x)); 21 | } 22 | } 23 | else { 24 | /* Laplace approximation assumes -x for x positive 25 | if ( x <= 0.0 ){y = loghyperg1F1_laplace(a, b, -x); } 26 | else { y = loghyperg1F1_laplace(b - a, b, x) + x;} */ 27 | y = loghyperg1F1_laplace(a, b, x); 28 | } 29 | 30 | // Rprintf("LOG Cephes 1F1(%lf, %lf, %lf) = %lf (%lf)\n", a,b,x,log(y), y); 31 | 32 | 33 | // ly = hyperg1F1_laplace(a,b,x); 34 | // Rprintf("called from hyperg1F1: LOG Pos 1F1(%lf, %lf, %lf) = %lf (%lf)\n", a,b,x,ly, exp(ly)); 35 | if (!R_FINITE(y) && laplace == 0) { 36 | warning("Cephes 1F1 function returned NA, using Laplace approximation"); 37 | y = loghyperg1F1_laplace(a, b, x); // try Laplace approximation 38 | } 39 | 40 | return(y); 41 | } 42 | 43 | 44 | double loghyperg1F1_laplace(double a, double b, double x) 45 | { 46 | double mode,mode1, mode2, lprec, prec, logy; 47 | 48 | /* int u^(a-1) (1-u)^(b-1) exp(-x u) du assuming that x >= 0 */ 49 | 50 | prec = 0.0; 51 | logy = 0.0; 52 | 53 | if ( x <= 0.0) { 54 | if (x < 0.0) { 55 | x = -x; 56 | logy = -lgammafn(b) - lgammafn(a) + lgammafn(a+b); 57 | 58 | // mode = (2.0 - 2.0* a + b - x - sqrt(pow(b, 2.0) - 2.0*b*x + x*(4.0*(a-1.0)+x)))/ 59 | // (2*(a - 1.0 - b)); 60 | mode1 = .5*(-a + b + x - sqrt( 4.*a*b + pow(a - b - x, 2.0)))/a; 61 | mode1 = 1.0/(1.0 + mode1); 62 | mode2 = .5*(-a + b + x + sqrt( 4.*a*b + pow(a - b -x, 2.0)))/a; 63 | mode2 = 1.0/(1.0 + mode2); 64 | if (a*log(mode1) + b*log(1.0 - mode1) - x*mode1 > 65 | a*log(mode2) + b*log(1.0 - mode2) - x*mode2) mode = mode1; 66 | else mode = mode2; 67 | // Rprintf("mode 1 %lf, mode %lf\n", mode1, mode2); 68 | if (mode < 0) { 69 | // # nocov start 70 | mode = 0.0; 71 | warning("1F1 Laplace approximation on boundary\n"); 72 | // # nocov end 73 | } 74 | else{ 75 | /* prec = a*mode*(1.0 - mode) + (1.0-mode)*(1.0 - mode)*b + 76 | x*pow(1.0-mode, 3.0) - x*mode*(1.0 - 77 | mode)*(1.0-mode); */ 78 | prec = (1.0-mode)*((a + b - x)*pow(mode,2) + (1.0-mode)*mode*(a + b + x)); 79 | if (prec > 0) { 80 | lprec = log(prec); 81 | logy += a*log(mode) + b*log(1.0 - mode) - x*mode; 82 | logy += -0.5*lprec + M_LN_SQRT_2PI; 83 | } 84 | else {prec = 0.0;} 85 | } 86 | 87 | // Rprintf("mode %lf prec %lf, Lap 1F1(%lf, %lf, %lf) = %lf\n", mode, prec, a,b,x, logy); 88 | } 89 | else {logy = 0.0;} 90 | } 91 | else { 92 | logy = x + loghyperg1F1_laplace(b - a, a, -x); 93 | } 94 | 95 | return(logy); 96 | } 97 | 98 | 99 | void hypergeometric1F1(double *a, double *b, double *x, double *y, int *npara, int *Method) 100 | { 101 | int k; 102 | for (k = 0; k < *npara; k++) { 103 | // if (x[k] <0) { 104 | /* Since Linex system tends to report error for negative x, we 105 | use the following fomular to convert it to positive value 106 | 1F1(a, b, x) = 1F1(b - a, b, -x) * exp(x) */ 107 | /* a[k] = b[k] - a[k]; 108 | y[k] = hyperg(a[k], b[k], -x[k])*exp(x[k]); 109 | } 110 | else { 111 | y[k] = hyperg(a[k], b[k], x[k]); 112 | }*/ 113 | y[k] = loghyperg1F1(a[k], b[k], x[k], Method[k]); 114 | } 115 | } 116 | 117 | 118 | -------------------------------------------------------------------------------- /src/hg_approx_null_np.c: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | // This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | // License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | // SPDX-License-Identifier: GPL-3.0 5 | // 6 | #include "bas.h" 7 | 8 | #define lgamma lgammafn 9 | double LogBF_Hg_null(double r2curr, int n, int d, double alpha, int gpower); 10 | void posroot(double a, double b, double c, double *root, double *status); 11 | double lik_null_HG(double g, double R2,int n,int k, double alpha, int gpower); 12 | double info_null_HG(double g, double R2, int n, int k, double alpha); 13 | 14 | double lik_null_HG(double g, double R2, int n, int k, double alpha, int gpower){ 15 | /* this computes log(likelihood x prior), where the likelihood is marginal 16 | on the intercept, regression coefficients and the variance 17 | */ 18 | double aux; 19 | 20 | if (R2 >= 1.0) R2 = 1.0; 21 | aux=((double)n-1.-(double)k)*log(1.+g)-((double)n-1.)*log(1.+(1.-R2)*g)+ 2.*(double)gpower*log(g)-alpha*log(1.+g/(double)n); 22 | aux=aux/2.; 23 | aux=aux - log((double)n) + log(alpha/2.-1.); 24 | 25 | return(aux); 26 | } 27 | 28 | 29 | double info_null_HG(double g,double R2,int n,int k, double alpha) 30 | {/* This computs the second derivative of LogLik(tau) which is 31 | equal to 32 | (1/2)*(- alpha ng/(n+g)^2-(n-1) eg/(1+eg)^2+(n-1-p)g/(1+g)^2) 33 | where g=e^{\tau} 34 | */ 35 | 36 | double aux; 37 | 38 | aux= ((double)n-1.-(double)k)*g/R_pow_di(1.+g,2); 39 | aux=aux-((double)n-1.)*(1.-R2)*g/R_pow_di(1.+(1.-R2)*g,2); 40 | aux=aux-alpha*(double)n*g/R_pow_di((double)n+g,2); 41 | aux=aux/2.; 42 | return(aux); 43 | } 44 | 45 | 46 | 47 | double LogBF_Hg_null(double R2, int n, int d, double alpha, int gpower){ 48 | 49 | /* this computes a Laplace approximation to the log of the Bayes factor 50 | with respect to the null model (intercept only), log(m_k)-log(m_0) 51 | 52 | R2 = 1-SSE/SST; the coefficient of determination 53 | e = 1 - R2; 54 | n = sample size; 55 | k = number of covariates of the current model (exclusing the intercept) 56 | 57 | The prior under consideration is Hyper-g with prior (1+g/n)^{-alpha/2} 58 | 59 | The cubic equation for loglik'(g)=0 is 60 | -e (alpha - 2 gpower + k) g^3 61 | - {[e (k - 2 gpower) - (1 - e)] n + (1 - e) + k + (1 + e) (alpha - 2 gpower)} g^2 62 | + [(1 - e) (n - 1) n - k n - alpha + 2 gpower (1 + (1 + e) n)] g + 2 gpower n 63 | */ 64 | 65 | /* this version: April 11 2005 */ 66 | 67 | 68 | double status,root, logmarg; 69 | double a,b,c,e,aux; 70 | int k; 71 | 72 | logmarg = NA_REAL; 73 | k = d - 1; 74 | e = 1.-R2; 75 | aux=-e*(alpha - (double)gpower*2. + (double)k); 76 | a= - ((e*((double)k - 2.*(double)gpower) - (1. - e))*(double)n + (1. - e) + (double)k + (1. + e)*(alpha - 2.*(double)gpower)); 77 | b= ((1. - e)*((double)n - 1.)*(double)n - (double)k*(double)n - alpha + 2.*(double)gpower*(1. + (1. + e)*(double)n)); 78 | c=(double)n*2.*(double)gpower; 79 | 80 | a=a/aux; 81 | b=b/aux; 82 | c=c/aux; 83 | posroot(a,b,c,&root,&status); 84 | if (k == 0 || n <= d || R2 >= 1.0) { logmarg = 0.0; } 85 | else { 86 | if(status!=1.){ 87 | logmarg =0.0; // # nocov 88 | // if(status==0.) Rprintf("\n No positive roots\n"); 89 | //else Rprintf("\n More than one positive root; this should not happen\n"); 90 | } 91 | else{ 92 | logmarg = lik_null_HG(root,R2,n,k, alpha, gpower)+ 93 | (log(4.*asin(1.))- 94 | log(-info_null_HG(root,R2,n,k, alpha)))/2.;} 95 | } 96 | return(logmarg); 97 | 98 | } 99 | 100 | 101 | // # nocov start 102 | void LogBF_Hg_null_vect(double *r2curr, int *n, int *dim, int *nmodels, double *logmarg, double *alpha, int *gpower) { 103 | 104 | 105 | int i; 106 | for (i=0; i < *nmodels; i++) { 107 | logmarg[i] = LogBF_Hg_null(r2curr[i], *n, dim[i], *alpha, *gpower); 108 | } 109 | } 110 | 111 | // # nocov end 112 | -------------------------------------------------------------------------------- /man/image.bas.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/image.R 3 | \name{image.bas} 4 | \alias{image.bas} 5 | \alias{image} 6 | \title{Images of models used in Bayesian model averaging} 7 | \usage{ 8 | \method{image}{bas}( 9 | x, 10 | top.models = 20, 11 | intensity = TRUE, 12 | prob = TRUE, 13 | log = TRUE, 14 | rotate = TRUE, 15 | color = "rainbow", 16 | subset = NULL, 17 | drop.always.included = FALSE, 18 | offset = 0.75, 19 | digits = 3, 20 | vlas = 2, 21 | plas = 0, 22 | rlas = 0, 23 | ... 24 | ) 25 | } 26 | \arguments{ 27 | \item{x}{A BMA object of type 'bas' created by BAS} 28 | 29 | \item{top.models}{Number of the top ranked models to plot} 30 | 31 | \item{intensity}{Logical variable, when TRUE image intensity is proportional 32 | to the probability or log(probability) of the model, when FALSE, intensity 33 | is binary indicating just presence (light) or absence (dark) of a variable.} 34 | 35 | \item{prob}{Logical variable for whether the area in the image for each 36 | model should be proportional to the posterior probability (or log 37 | probability) of the model (TRUE) or with equal area (FALSE).} 38 | 39 | \item{log}{Logical variable indicating whether the intensities should be 40 | based on log posterior odds (TRUE) or posterior probabilities (FALSE). The 41 | log of the posterior odds is for comparing the each model to the worst model 42 | in the top.models.} 43 | 44 | \item{rotate}{Should the image of models be rotated so that models are on 45 | the y-axis and variables are on the x-axis (TRUE)} 46 | 47 | \item{color}{The color scheme for image intensities. The value "rainbow" 48 | uses the rainbow palette. The value "blackandwhite" produces a black and 49 | white image (greyscale image)} 50 | 51 | \item{subset}{indices of variables to include/exclude in plot} 52 | 53 | \item{drop.always.included}{logical variable to drop variables that are 54 | always forced into the model. FALSE by default.} 55 | 56 | \item{offset}{numeric value to add to intensity} 57 | 58 | \item{digits}{number of digits in posterior probabilities to keep} 59 | 60 | \item{vlas}{las parameter for placing variable names; see par} 61 | 62 | \item{plas}{las parameter for posterior probability axis} 63 | 64 | \item{rlas}{las parameter for model ranks} 65 | 66 | \item{...}{Other parameters to be passed to the \code{image} and \code{axis} 67 | functions.} 68 | } 69 | \description{ 70 | Creates an image of the models selected using \code{\link{bas}}. 71 | } 72 | \details{ 73 | Creates an image of the model space sampled using \code{\link{bas}}. If a 74 | subset of the top models are plotted, then probabilities are renormalized 75 | over the subset. 76 | } 77 | \note{ 78 | Suggestion to allow area of models be proportional to posterior 79 | probability due to Thomas Lumley 80 | } 81 | \examples{ 82 | 83 | require(graphics) 84 | data("Hald") 85 | hald.ZSprior <- bas.lm(Y ~ ., data = Hald, prior = "ZS-null") 86 | image(hald.ZSprior, drop.always.included = TRUE) # drop the intercept 87 | } 88 | \references{ 89 | Clyde, M. (1999) Bayesian Model Averaging and Model Search 90 | Strategies (with discussion). In Bayesian Statistics 6. J.M. Bernardo, A.P. 91 | Dawid, J.O. Berger, and A.F.M. Smith eds. Oxford University Press, pages 92 | 157-185. 93 | } 94 | \seealso{ 95 | \code{\link{bas}} 96 | 97 | Other bas methods: 98 | \code{\link{BAS}}, 99 | \code{\link{bas.lm}()}, 100 | \code{\link{coef.bas}()}, 101 | \code{\link{confint.coef.bas}()}, 102 | \code{\link{confint.pred.bas}()}, 103 | \code{\link{diagnostics}()}, 104 | \code{\link{fitted.bas}()}, 105 | \code{\link{force.heredity.bas}()}, 106 | \code{\link{plot.confint.bas}()}, 107 | \code{\link{predict.bas}()}, 108 | \code{\link{predict.basglm}()}, 109 | \code{\link{summary.bas}()}, 110 | \code{\link{update.bas}()}, 111 | \code{\link{variable.names.pred.bas}()} 112 | 113 | Other bas plots: 114 | \code{\link{plot.bas}()}, 115 | \code{\link{plot.coef.bas}()} 116 | } 117 | \author{ 118 | Merlise Clyde \email{clyde@stat.duke.edu} 119 | } 120 | \concept{bas methods} 121 | \concept{bas plots} 122 | \keyword{regression} 123 | -------------------------------------------------------------------------------- /man/plot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plot.R 3 | \name{plot.bas} 4 | \alias{plot.bas} 5 | \title{Plot Diagnostics for an BAS Object} 6 | \usage{ 7 | \method{plot}{bas}( 8 | x, 9 | which = c(1:4), 10 | caption = c("Residuals vs Fitted", "Model Probabilities", "Model Complexity", 11 | "Inclusion Probabilities"), 12 | panel = if (add.smooth) panel.smooth else points, 13 | sub.caption = NULL, 14 | main = "", 15 | ask = prod(par("mfcol")) < length(which) && dev.interactive(), 16 | col.in = 2, 17 | col.ex = 1, 18 | col.pch = 1, 19 | cex.lab = 1, 20 | ..., 21 | id.n = 3, 22 | labels.id = NULL, 23 | cex.id = 0.75, 24 | add.smooth = getOption("add.smooth"), 25 | label.pos = c(4, 2), 26 | subset = NULL, 27 | drop.always.included = FALSE 28 | ) 29 | } 30 | \arguments{ 31 | \item{x}{\code{bas} BMA object result of 'bas'} 32 | 33 | \item{which}{if a subset of the plots is required, specify a subset of the 34 | numbers '1:4'} 35 | 36 | \item{caption}{captions to appear above the plots} 37 | 38 | \item{panel}{panel function. The useful alternative to 'points', 39 | 'panel.smooth' can be chosen by 'add.smooth = TRUE'} 40 | 41 | \item{sub.caption}{common title-above figures if there are multiple; used as 42 | 'sub' (s.'title') otherwise. If 'NULL', as by default, a possible shortened 43 | version of \code{deparse(x$call)} is used} 44 | 45 | \item{main}{title to each plot-in addition to the above 'caption'} 46 | 47 | \item{ask}{logical; if 'TRUE', the user is asked before each plot, see 48 | 'par(ask=.)'} 49 | 50 | \item{col.in}{color for the included variables} 51 | 52 | \item{col.ex}{color for the excluded variables} 53 | 54 | \item{col.pch}{color for points in panels 1-3} 55 | 56 | \item{cex.lab}{graphics parameter to control size of variable names} 57 | 58 | \item{...}{other parameters to be passed through to plotting functions} 59 | 60 | \item{id.n}{number of points to be labeled in each plot, starting with the 61 | most extreme} 62 | 63 | \item{labels.id}{vector of labels, from which the labels for extreme points 64 | will be chosen. 'NULL' uses observation numbers} 65 | 66 | \item{cex.id}{magnification of point labels.} 67 | 68 | \item{add.smooth}{logical indicating if a smoother should be added to most 69 | plots; see also 'panel' above} 70 | 71 | \item{label.pos}{positioning of labels, for the left half and right half of 72 | the graph respectively, for plots 1-4} 73 | 74 | \item{subset}{indices of variables to include/exclude in plot of marginal posterior 75 | inclusion probabilities (NULL).} 76 | 77 | \item{drop.always.included}{logical variable to drop marginal posterior inclusion 78 | probabilities 79 | for variables that are always forced into the model. FALSE by default.} 80 | } 81 | \description{ 82 | Four plots (selectable by 'which') are currently available: a plot of 83 | residuals against fitted values, Cumulative Model Probabilities, log 84 | marginal likelihoods versus model dimension, and marginal inclusion 85 | probabilities. 86 | } 87 | \details{ 88 | This provides a panel of 4 plots: the first is a plot of the residuals 89 | versus fitted values under BMA. The second is a plot of the cumulative 90 | marginal likelihoods of models; if the model space cannot be enumerated then 91 | this provides some indication of whether the probabilities are leveling off. 92 | The third is a plot of log marginal likelihood versus model dimension and 93 | the fourth plot show the posterior marginal inclusion probabilities. 94 | } 95 | \examples{ 96 | 97 | data(Hald) 98 | hald.gprior = bas.lm(Y~ ., data=Hald, prior="g-prior", alpha=13, 99 | modelprior=beta.binomial(1,1), 100 | initprobs="eplogp") 101 | 102 | plot(hald.gprior) 103 | 104 | 105 | } 106 | \seealso{ 107 | \code{\link{plot.coef.bas}} and \code{\link{image.bas}}. 108 | 109 | Other bas plots: 110 | \code{\link{image.bas}()}, 111 | \code{\link{plot.coef.bas}()} 112 | } 113 | \author{ 114 | Merlise Clyde, based on plot.lm by John Maindonald and Martin 115 | Maechler 116 | } 117 | \concept{bas plots} 118 | \keyword{regression} 119 | -------------------------------------------------------------------------------- /R/plot_coef.R: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | # This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | # License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | # 5 | #' Plots the posterior distributions of coefficients derived from Bayesian 6 | #' model averaging 7 | #' 8 | #' Displays plots of the posterior distributions of the coefficients generated 9 | #' by Bayesian model averaging over linear regression. 10 | #' 11 | #' Produces plots of the posterior distributions of the coefficients under 12 | #' model averaging. The posterior probability that the coefficient is zero is 13 | #' represented by a solid line at zero, with height equal to the probability. 14 | #' The nonzero part of the distribution is scaled so that the maximum height is 15 | #' equal to the probability that the coefficient is nonzero. 16 | #' 17 | #' The parameter \code{e} specifies the range over which the distributions are 18 | #' to be graphed by specifying the tail probabilities that dictate the range to 19 | #' plot over. 20 | #' 21 | #' @param x object of class coef.bas 22 | #' @param e optional numeric value specifying the range over which the 23 | #' distributions are to be graphed. 24 | #' @param subset optional numerical vector specifying which variables to graph 25 | #' (including the intercept) 26 | #' @param ask Prompt for next plot 27 | #' @param ... other parameters to be passed to \code{plot} and \code{lines} 28 | #' @note For mixtures of g-priors, uncertainty in g is not incorporated at this 29 | #' time, thus results are approximate 30 | #' @author based on function \code{plot.bic} by Ian Painter in package BMA; 31 | #' adapted for 'bas' class by Merlise Clyde \email{clyde@@stat.duke.edu} 32 | #' @seealso \code{ \link{coef.bas}} 33 | #' @references Hoeting, J.A., Raftery, A.E. and Madigan, D. (1996). A method 34 | #' for simultaneous variable selection and outlier identification in linear 35 | #' regression. Computational Statistics and Data Analysis, 22, 251-270. 36 | #' @keywords regression 37 | #' @examples 38 | #' 39 | #' \dontrun{library(MASS) 40 | #' data(UScrime) 41 | #' UScrime[,-2] <- log(UScrime[,-2]) 42 | #' crime_bic <- bas.lm(y ~ ., data=UScrime, n.models=2^15, prior="BIC") 43 | #' plot(coefficients(crime_bic), ask=TRUE) 44 | #' } 45 | #' 46 | #' @rdname plot.coef 47 | #' @family bas plots 48 | #' @export 49 | plot.coef.bas <- function(x, e = 1e-04, subset = 1:x$n.vars, ask = TRUE, ...) { 50 | plotvar <- function(prob0, mixprobs, df, means, sds, name, 51 | e = 1e-04, nsteps = 500, ...) { 52 | if (prob0 == 1 | length(means) == 0) { # nocov start 53 | xlower <- -0 54 | xupper <- 0 55 | xmax <- 1 # nocov end 56 | } 57 | else { 58 | qmin <- min(qnorm(e / 2, means, sds)) 59 | qmax <- max(qnorm(1 - e / 2, means, sds)) 60 | xlower <- min(qmin, 0) 61 | xupper <- max(0, qmax) 62 | } 63 | xx <- seq(xlower, xupper, length.out = nsteps) 64 | yy <- rep(0, times = length(xx)) 65 | maxyy <- 1 66 | if (prob0 < 1 & length(sds) > 0) { 67 | yy <- mixprobs %*% apply(matrix(xx, ncol = 1), 1, 68 | FUN = function(x, d, m, s) { 69 | dt(x = (x - m) / s, df = d) / s 70 | }, 71 | d = df, m = means, s = sds 72 | ) 73 | maxyy <- max(yy) 74 | } 75 | 76 | ymax <- max(prob0, 1 - prob0) 77 | plot(c(xlower, xupper), c(0, ymax), 78 | type = "n", 79 | xlab = "", ylab = "", main = name, ... 80 | ) 81 | lines(c(0, 0), c(0, prob0), lty = 1, lwd = 3, ...) 82 | lines(xx, (1 - prob0) * yy / maxyy, lty = 1, lwd = 1, ...) 83 | invisible() 84 | } 85 | 86 | if (ask) { 87 | op <- par(ask = TRUE) 88 | on.exit(par(op)) 89 | } 90 | df <- x$df 91 | 92 | for (i in subset) { 93 | sel <- x$conditionalmeans[, i] != 0 94 | prob0 <- 1 - x$probne0[i] 95 | mixprobs <- x$postprobs[sel] / (1.0 - prob0) 96 | means <- x$conditionalmeans[sel, i, drop = TRUE] 97 | sds <- x$conditionalsd[sel, i, drop = TRUE] 98 | name <- x$namesx[i] 99 | df.sel <- df[sel] 100 | plotvar(prob0, mixprobs, df.sel, means, sds, name, e = e, ...) 101 | } 102 | invisible() 103 | } 104 | -------------------------------------------------------------------------------- /man/fitted.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/predict.R 3 | \name{fitted.bas} 4 | \alias{fitted.bas} 5 | \alias{fitted} 6 | \title{Fitted values for a BAS BMA objects} 7 | \usage{ 8 | \method{fitted}{bas}( 9 | object, 10 | type = "link", 11 | estimator = "BMA", 12 | top = NULL, 13 | na.action = na.pass, 14 | ... 15 | ) 16 | } 17 | \arguments{ 18 | \item{object}{An object of class 'bas' as created by \code{\link{bas}}} 19 | 20 | \item{type}{type equals "response" or "link" in the case of GLMs (default is 'link')} 21 | 22 | \item{estimator}{estimator type of fitted value to return. Default is to use 23 | BMA with all models. Options include \cr 'HPM' the highest probability model 24 | \cr 'BMA' Bayesian model averaging, using optionally only the 'top' models 25 | \cr 'MPM' the median probability model of Barbieri and Berger. 'BPM' the 26 | model that is closest to BMA predictions under squared error loss} 27 | 28 | \item{top}{optional argument specifying that the 'top' models will be used 29 | in constructing the BMA prediction, if NULL all models will be used. If 30 | top=1, then this is equivalent to 'HPM'} 31 | 32 | \item{na.action}{function determining what should be done with missing values in newdata. The default is to predict NA.} 33 | 34 | \item{...}{optional arguments, not used currently} 35 | } 36 | \value{ 37 | A vector of length n of fitted values. 38 | } 39 | \description{ 40 | Calculate fitted values for a BAS BMA object 41 | } 42 | \details{ 43 | Calculates fitted values at observed design matrix using either the highest 44 | probability model, 'HPM', the posterior mean (under BMA) 'BMA', the median 45 | probability model 'MPM' or the best predictive model 'BPM". The median 46 | probability model is defined by including variable where the marginal 47 | inclusion probability is greater than or equal to 1/2. For type="BMA", the 48 | weighted average may be based on using a subset of the highest probability 49 | models if an optional argument is given for top. By default BMA uses all 50 | sampled models, which may take a while to compute if the number of variables 51 | or number of models is large. The "BPM" is found be computing the squared 52 | distance of the vector of fitted values for a model and the fitted values 53 | under BMA and returns the model with the smallest distance. In the presence 54 | of multicollinearity this may be quite different from the MPM, with extreme 55 | collinearity may drop relevant predictors. 56 | } 57 | \examples{ 58 | 59 | data(Hald) 60 | hald.gprior = bas.lm(Y~ ., data=Hald, prior="ZS-null", initprobs="Uniform") 61 | plot(Hald$Y, fitted(hald.gprior, estimator="HPM")) 62 | plot(Hald$Y, fitted(hald.gprior, estimator="BMA", top=3)) 63 | plot(Hald$Y, fitted(hald.gprior, estimator="MPM")) 64 | plot(Hald$Y, fitted(hald.gprior, estimator="BPM")) 65 | 66 | } 67 | \references{ 68 | Barbieri, M. and Berger, J.O. (2004) Optimal predictive model 69 | selection. Annals of Statistics. 32, 870-897. \cr 70 | \url{https://projecteuclid.org/euclid.aos/1085408489&url=/UI/1.0/Summarize/euclid.aos/1085408489} 71 | 72 | Clyde, M. Ghosh, J. and Littman, M. (2010) Bayesian Adaptive Sampling for 73 | Variable Selection and Model Averaging. Journal of Computational Graphics 74 | and Statistics. 20:80-101 \cr 75 | \doi{10.1198/jcgs.2010.09049} 76 | } 77 | \seealso{ 78 | \code{\link{predict.bas}} \code{\link{predict.basglm}} 79 | 80 | Other bas methods: 81 | \code{\link{BAS}}, 82 | \code{\link{bas.lm}()}, 83 | \code{\link{coef.bas}()}, 84 | \code{\link{confint.coef.bas}()}, 85 | \code{\link{confint.pred.bas}()}, 86 | \code{\link{diagnostics}()}, 87 | \code{\link{force.heredity.bas}()}, 88 | \code{\link{image.bas}()}, 89 | \code{\link{plot.confint.bas}()}, 90 | \code{\link{predict.bas}()}, 91 | \code{\link{predict.basglm}()}, 92 | \code{\link{summary.bas}()}, 93 | \code{\link{update.bas}()}, 94 | \code{\link{variable.names.pred.bas}()} 95 | 96 | Other predict methods: 97 | \code{\link{predict.bas}()}, 98 | \code{\link{predict.basglm}()}, 99 | \code{\link{variable.names.pred.bas}()} 100 | } 101 | \author{ 102 | Merlise Clyde \email{clyde@duke.edu} 103 | } 104 | \concept{bas methods} 105 | \concept{predict methods} 106 | \keyword{regression} 107 | -------------------------------------------------------------------------------- /R/summary.R: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2024 Merlise Clyde and contributors to BAS. All rights reserved. 2 | # This work is licensed under a GNU GENERAL PUBLIC LICENSE Version 3.0 3 | # License text is available at https://www.gnu.org/licenses/gpl-3.0.html 4 | # 5 | #' Print a Summary of Bayesian Model Averaging objects from BAS 6 | #' 7 | #' \code{summary} and \code{print} methods for Bayesian model averaging objects 8 | #' created by \code{bas} Bayesian Adaptive Sampling 9 | #' 10 | #' The print methods display a view similar to \code{print.lm} . The summary 11 | #' methods display a view specific to Bayesian model averaging giving the top 5 12 | #' highest probability models represented by their inclusion indicators. 13 | #' Summaries of the models include the Bayes Factor (BF) of each model to the 14 | #' model with the largest marginal likelihood, the posterior probability of the 15 | #' models, R2, dim (which includes the intercept) and the log of the marginal 16 | #' likelihood. 17 | #' 18 | #' @aliases print.bas print 19 | #' @param x object of class 'bas' 20 | #' @param digits optional number specifying the number of digits to display 21 | #' @param ... other parameters to be passed to \code{print.default} 22 | #' @author Merlise Clyde \email{clyde@@stat.duke.edu} 23 | #' @seealso \code{\link{coef.bas}} 24 | #' @keywords print regression 25 | #' @examples 26 | #' 27 | #' library(MASS) 28 | #' data(UScrime) 29 | #' UScrime[, -2] <- log(UScrime[, -2]) 30 | #' crime.bic <- bas.lm(y ~ ., data = UScrime, n.models = 2^15, prior = "BIC", initprobs = "eplogp") 31 | #' print(crime.bic) 32 | #' summary(crime.bic) 33 | #' @rdname print.bas 34 | #' @method print bas 35 | #' @export 36 | print.bas <- function(x, digits = max(3L, getOption("digits") - 3L), ...) { 37 | cat("\nCall:\n", paste(deparse(x$call), 38 | sep = "\n", 39 | collapse = "\n" 40 | ), 41 | "\n\n", 42 | sep = "" 43 | ) 44 | cat("\n Marginal Posterior Inclusion Probabilities: \n") 45 | out <- x$probne0 46 | names(out) <- x$namesx 47 | print.default(format(out, digits = digits), 48 | print.gap = 2L, 49 | quote = FALSE 50 | ) 51 | invisible() 52 | } 53 | 54 | 55 | 56 | #' Summaries of Bayesian Model Averaging objects from BAS 57 | #' 58 | #' \code{summary} and \code{print} methods for Bayesian model averaging objects 59 | #' created by \code{bas} Bayesian Adaptive Sampling 60 | #' 61 | #' The print methods display a view similar to \code{print.lm} . The summary 62 | #' methods display a view specific to Bayesian model averaging giving the top 5 63 | #' highest probability models represented by their inclusion indicators. 64 | #' Summaries of the models include the Bayes Factor (BF) of each model to the 65 | #' model with the largest marginal likelihood, the posterior probability of the 66 | #' models, R2, dim (which includes the intercept) and the log of the marginal 67 | #' likelihood. 68 | #' 69 | #' @aliases summary.bas summary 70 | #' @param object object of class 'bas' 71 | #' @param n.models optional number specifying the number of best models to 72 | #' display in summary 73 | #' @param ... other parameters to be passed to \code{summary.default} 74 | #' @author Merlise Clyde \email{clyde@@duke.edu} 75 | #' @seealso \code{\link{coef.bas}} 76 | #' @keywords print regression 77 | #' @examples 78 | #' data(UScrime, package = "MASS") 79 | #' UScrime[, -2] <- log(UScrime[, -2]) 80 | #' crime.bic <- bas.lm(y ~ ., data = UScrime, n.models = 2^15, prior = "BIC", initprobs = "eplogp") 81 | #' print(crime.bic) 82 | #' summary(crime.bic) 83 | #' @rdname summary 84 | #' @family bas methods 85 | #' @method summary bas 86 | #' @export 87 | 88 | summary.bas <- function(object, n.models = 5, ...) { 89 | best <- order(-object$postprobs) 90 | n.models <- min(n.models, length(best)) 91 | best <- best[1:n.models] 92 | x <- cbind( 93 | list2matrix.which(object, best), 94 | exp(object$logmarg[best] - max(object$logmarg[best])), 95 | round(object$postprobs[best], 4), 96 | round(object$R2[best], 4), 97 | object$size[best], 98 | object$logmarg[best] 99 | ) 100 | x <- t(x) 101 | x <- cbind(NA, x) 102 | 103 | x[1:object$n.vars, 1] <- object$probne0 104 | colnames(x) <- c("P(B != 0 | Y)", paste("model", 1:n.models)) 105 | rownames(x) <- c(object$namesx, "BF", "PostProbs", "R2", "dim", "logmarg") 106 | return(x) 107 | } 108 | --------------------------------------------------------------------------------