# Copyright 2018 Google LLC. All Rights Reserved. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA library(BoomSpikeSlab) library(testthat) library(MASS) cat("test-logit\n") test_that("Calls with the same random seed return the same draws", { n <- 100 niter <- 1000 x <- rnorm(n) beta0 <- -3 beta1 <- 1 logits <- beta0 + beta1*x probabilities <- plogis(logits) y <- as.numeric(runif(n) <= probabilities) ## Do the check with model selection turned off, signaled by ## expected.model.size > number of variables. model1 <- logit.spike(y ~ x, niter = niter, expected.model.size = 3, seed = 31417, ping = -1) model2 <- logit.spike(y ~ x, niter = niter, expected.model.size = 3, seed = 31417, ping = -1) expect_equal(model1$beta, model2$beta) ## Now do the check with model selection turned on. model1 <- logit.spike(y ~ x, niter = niter, seed = 31417, ping = -1) model2 <- logit.spike(y ~ x, niter = niter, seed = 31417, ping = -1) expect_equal(model1$beta, model2$beta) }) test_that("Pima Indians works without threads", { if (requireNamespace("MASS")) { data(Pima.tr, package = "MASS") data(Pima.te, package = "MASS") pima <- rbind(Pima.tr, Pima.te) niter <- 1000 sample.size <- nrow(pima) m <- logit.spike(type == "Yes" ~ ., data = pima, niter = niter) expect_true(!is.null(m$beta)) expect_true(is.matrix(m$beta)) expect_equal(dim(m$beta), c(1000, 8)) expect_equal(length(m$fitted.probabilities), sample.size) expect_equal(length(m$fitted.logits), sample.size) expect_equal(length(m$deviance.residuals), sample.size) expect_equal(length(m$log.likelihood), niter) expect_true(!is.null(m$prior)) m.summary <- summary(m) expect_true(!is.null(m.summary$coefficients)) expect_true(is.matrix(m.summary$predicted.vs.actual)) expect_equal(ncol(m.summary$predicted.vs.actual), 2) expect_equal(nrow(m.summary$predicted.vs.actual), 10) expect_equal(length(m.summary$deviance.r2.distribution), 1000) expect_equal(length(m.summary$deviance.r2), 1) expect_true(is.numeric(m.summary$deviance.r2)) # The following is always true regardless of the data. expect_true(m.summary$max.log.likelihood >= m.summary$mean.log.likelihood) # The following is true for this data. expect_true(m.summary$max.log.likelihood > m.summary$null.log.likelihood) m <- logit.spike(type == "Yes" ~ ., data = Pima.tr, niter = niter) predictions <- predict(m, newdata = Pima.te) } }) test_that("Pima indians analysis runs with threads", { if (requireNamespace("MASS")) { data(Pima.tr, package = "MASS") data(Pima.te, package = "MASS") pima <- rbind(Pima.tr, Pima.te) niter <- 1000 sample.size <- nrow(pima) m <- logit.spike(type == "Yes" ~ ., data = pima, niter = niter, nthreads = 8) expect_true(!is.null(m$beta)) expect_true(is.matrix(m$beta)) expect_equal(dim(m$beta), c(1000, 8)) expect_equal(length(m$fitted.probabilities), sample.size) expect_equal(length(m$fitted.logits), sample.size) expect_equal(length(m$deviance.residuals), sample.size) expect_equal(length(m$log.likelihood), niter) expect_true(!is.null(m$prior)) m.summary <- summary(m) expect_true(!is.null(m.summary$coefficients)) expect_true(is.matrix(m.summary$predicted.vs.actual)) expect_equal(ncol(m.summary$predicted.vs.actual), 2) expect_equal(nrow(m.summary$predicted.vs.actual), 10) expect_equal(length(m.summary$deviance.r2.distribution), 1000) expect_equal(length(m.summary$deviance.r2), 1) expect_true(is.numeric(m.summary$deviance.r2)) # The following is always true regardless of the data. expect_true(m.summary$max.log.likelihood >= m.summary$mean.log.likelihood) # The following is true for this data. expect_true(m.summary$max.log.likelihood > m.summary$null.log.likelihood) tmp.file <- tempfile() png(tmp.file) plot(m) plot(m, "coefficients") plot(m, "scaled.coefficients") plot(m, "fit") plot(m, "residuals") plot(m, "size") dev.off() } }) test_that("Small number of cases", { ## The model should run and give sensible results even if, ## e.g. there are no/all successes or there are very few data ## points. This code should produce a warning about the ## prior.success.probability begin zero. x <- matrix(rnorm(45), ncol = 9) x <- cbind(1, x) y <- rep(FALSE, nrow(x)) expect_warning( m <- logit.spike(y ~ x, niter = 100), "Fudging around the fact that prior.success.probability is zero. Setting it to 0.14286") invisible(NULL) }) test_that("contrasts.arg respected", { if (requireNamespace("MASS")) { data(Pima.tr, package = "MASS") data(Pima.te, package = "MASS") pima <- rbind(Pima.tr, Pima.te) df0 <- pima[1:100, ] df1 <- pima[101:532, ] xlevels <- list(skin = c("10", "20", "30", "40", "50", "60", "100")) df1$skin <- factor(round(df1$skin, -1), levels = xlevels$skin) df0$skin <- factor(round(df0$skin, -1)) model1 <- logit.spike(type == "Yes" ~ ., drop.unused.levels = FALSE, data = df1, niter = 500, seed = 31417, ping = -1) model2 <- logit.spike(type == "Yes" ~ ., drop.unused.levels = FALSE, data = df1, niter = 500, seed = 31417, ping = -1, contrasts = list(skin="contr.helmert")) model3 <- logit.spike(type == "Yes" ~ ., drop.unused.levels = FALSE, data = df1, niter = 500, seed = 31417, ping = -1, contrasts = list(skin="contr.poly")) model4 <- logit.spike(type == "Yes" ~ ., drop.unused.levels = FALSE, data = df1, niter = 500, seed = 31417, ping = -1, contrasts = list(skin="contr.sum")) model5 <- logit.spike(type == "Yes" ~ ., drop.unused.levels = FALSE, data = df1, niter = 500, seed = 31417, ping = -1, contrasts = list(skin="contr.SAS")) expect_equal(model1$xlevels, xlevels) expect_equal(model2$xlevels, xlevels) expect_equal(model3$xlevels, xlevels) expect_equal(model4$xlevels, xlevels) expect_equal(model5$xlevels, xlevels) betanames <- c("(Intercept)", "npreg", "glu", "bp", "skin20", "skin30", "skin40", "skin50", "skin60", "skin100", "bmi", "ped", "age") expect_equal(ncol(model1$beta), length(betanames)) expect_equal(ncol(model2$beta), length(betanames)) expect_equal(ncol(model3$beta), length(betanames)) expect_equal(ncol(model4$beta), length(betanames)) expect_equal(ncol(model5$beta), length(betanames)) } })