Nothing
## test more exotic familes/model types
stopifnot(require("testthat"),
require("glmmTMB"))
simfun0 <- function(beta=c(2,1),
sd.re=5,
ngrp=10,nobs=200,
invlink=exp) {
x <- rnorm(nobs)
f <- factor(rep(1:ngrp,nobs/ngrp))
u <- rnorm(ngrp,sd=sd.re)
eta <- beta[1]+beta[2]*x+u[f]
mu <- invlink(eta)
return(data.frame(x,f,mu))
}
context("alternative binomial specifications")
test_that("binomial", {
load(system.file("testdata","radinger_dat.RData",package="lme4"))
radinger_dat <<- radinger_dat ## global assignment for testthat
mod1 <<- glmmTMB(presabs~predictor+(1|species),family=binomial,
radinger_dat)
mod2 <<- update(mod1,as.logical(presabs)~.)
expect_equal(predict(mod1),predict(mod2))
## Compare 2-column and prop/size specification
dd <- data.frame(success=1:10, failure=11:20)
dd$size <- rowSums(dd)
dd$prop <- local( success / size, dd)
mod4 <- glmmTMB(cbind(success,failure)~1,family=binomial,data=dd)
mod5 <- glmmTMB(prop~1,weights=size,family=binomial,data=dd)
expect_equal( logLik(mod4) , logLik(mod5) )
expect_equal( fixef(mod4)$cond , fixef(mod5)$cond )
## Now with extra weights
dd$w <- 2
mod6 <- glmmTMB(cbind(success,failure)~1,family=binomial,data=dd,weights=w)
mod7 <- glmmTMB(prop~1,weights=size*w,family=binomial,data=dd)
mod6.glm <- glm(cbind(success,failure)~1,family=binomial,data=dd,weights=w)
mod7.glm <- glm(prop~1,weights=size*w,family=binomial,data=dd)
expect_equal( logLik(mod6)[[1]] , logLik(mod6.glm)[[1]] )
expect_equal( logLik(mod7)[[1]] , logLik(mod7.glm)[[1]] )
expect_equal( fixef(mod6)$cond , fixef(mod7)$cond )
## Test TRUE/FALSE specification
x <- c(TRUE, TRUE, FALSE)
dx <- data.frame(x)
m1 <- glmmTMB(x~1, family=binomial(), data=dx)
m2 <- glm (x~1, family=binomial(), data=dx)
expect_equal(
as.numeric(logLik(m1)),
as.numeric(logLik(m2))
)
expect_equal(
as.numeric(unlist(fixef(m1))),
as.numeric(coef(m2))
)
## Mis-specifications
prop <- c(.1, .2, .3) ## weights=1 => prop * weights non integers
expect_warning( glmmTMB(prop~1, family=binomial()) ) ## Warning as glm
x <- c(1, 2, 3) ## weights=1 => x > weights !
expect_error ( glmmTMB(x~1, family=binomial(),
data = data.frame(x))) ## Error as glm
})
context("non-integer count warnings")
test_that("count distributions", {
dd <- data.frame(y=c(0.5,1,1,1))
for (f in c("binomial","betabinomial","poisson",
"genpois",
## "compois", ## fails anyway ...
"truncated_genpois",
# "truncated_compois",
"nbinom1",
"nbinom2"
# why do these truncated cases fail?
##, "truncated_nbinom1",
##"truncated_nbinom2"
)) {
expect_warning(m <- glmmTMB(y~1,data=dd,family=f),
"non-integer")
}
})
context("fitting exotic families")
test_that("beta", {
skip_on_cran()
set.seed(101)
nobs <- 200; eps <- 0.001; phi <- 0.1
dd0 <- simfun0(nobs=nobs,sd.re=1,invlink=plogis)
y <- with(dd0,rbeta(nobs,shape1=mu/phi,shape2=(1-mu)/phi))
dd <<- data.frame(dd0,y=pmin(1-eps,pmax(eps,y)))
m1 <- glmmTMB(y~x+(1|f),family=beta_family(),
data=dd)
expect_equal(fixef(m1)[[1]],
structure(c(1.98250567574413, 0.843382531038295),
.Names = c("(Intercept)", "x")),
tol=1e-5)
expect_equal(c(VarCorr(m1)[[1]][[1]]),
0.433230926800709, tol=1e-5)
## allow family="beta", but with warning
expect_warning(m2 <- glmmTMB(y~x+(1|f),family="beta",
data=dd),"please use")
expect_equal(coef(summary(m1)),coef(summary(m2)))
})
test_that("nbinom", {
skip_on_cran()
nobs <- 200; phi <- 0.1
set.seed(101)
dd0 <- simfun0(nobs=nobs)
## global assignment for testthat (??)
dd <- data.frame(dd0,y=rnbinom(nobs,size=phi,mu=dd0$mu))
m1 <- glmmTMB(y~x+(1|f),family=nbinom2(),
data=dd)
expect_equal(fixef(m1)[[1]],
structure(c(2.09866748794435, 1.12703589660625),
.Names = c("(Intercept)", "x")),
tolerance = 1e-5)
expect_equal(c(VarCorr(m1)[[1]][[1]]),
9.54680210862774, tolerance = 1e-5)
expect_equal(sigma(m1),0.09922738,tolerance = 1e-5)
expect_equal(head(residuals(m1, type = "deviance"),2),
c(`1` = -0.806418177063906, `2` = -0.312895476230701),
tolerance = 1e-5)
## nbinom1
## to simulate, back-calculate shape parameters for NB2 ...
nbphi <- 2
nbvar <- nbphi*dd0$mu ## n.b. actual model is (1+phi)*var,
## so estimate of phi is approx. 1
## V = mu*(1+mu/k) -> mu/k = V/mu-1 -> k = mu/(V/mu-1)
k <- with(dd0,mu/(nbvar/mu - 1))
y <- rnbinom(nobs,size=k,mu=dd$mu)
dd <- data.frame(dd0,y=y) ## global assignment for testthat
m1 <- glmmTMB(y~x+(1|f),family=nbinom1(),
data=dd)
expect_equal(c(unname(c(fixef(m1)[[1]])),
c(VarCorr(m1)[[1]][[1]]),
sigma(m1)),
c(1.93154240357181, 0.992776302432081,
16.447888398429, 1.00770603513152),
tolerance = 1e-5)
expect_equal(head(residuals(m1, type = "deviance"),2),
c(`1` = 0.966425183534698, `2` = -0.213960044837981),
tolerance = 1e-5)
## identity link: GH #20
x <- 1:100; m <- 2; b <- 100
y <- m*x+b
set.seed(101)
dat <<- data.frame(obs=rnbinom(length(y), mu=y, size=5), x=x)
## with(dat, plot(x, obs))
## coef(mod1 <- MASS::glm.nb(obs~x,link="identity",dat))
expect_equal(fixef(glmmTMB(obs~x, family=nbinom2(link="identity"), dat)),
structure(list(cond = structure(c(115.092240041138, 1.74390840106971),
.Names = c("(Intercept)", "x")), zi = numeric(0),
disp = structure(1.71242627201796, .Names = "(Intercept)")),
.Names = c("cond", "zi", "disp"), class = "fixef.glmmTMB"))
## segfault (GH #248)
dd <- data.frame(success=1:10,failure=10)
expect_error(glmmTMB(cbind(success,failure)~1,family=nbinom2,data=dd),
"matrix-valued responses are not allowed")
})
test_that("dbetabinom", {
skip_on_cran()
set.seed(101)
nobs <- 200; eps <- 0.001; phi <- 0.1
dd0 <- simfun0(nobs=nobs,sd.re=1,invlink=plogis)
p <- with(dd0,rbeta(nobs,shape1=mu/phi,shape2=(1-mu)/phi))
p <- pmin(1-eps,pmax(p,eps))
b <- rbinom(nobs,size=5,prob=p)
dd <<- data.frame(dd0,y=b,N=5)
m1 <- glmmTMB(y/N~x+(1|f),
weights=N,
family=betabinomial(),
data=dd)
expect_equal(c(unname(c(fixef(m1)[[1]])),
c(VarCorr(m1)[[1]][[1]]),
sigma(m1)),
c(2.1482114,1.0574946,0.7016553,8.3768711),
tolerance=1e-5)
## Two-column specification
m2 <- glmmTMB(cbind(y, N-y) ~ x + (1|f),
family=betabinomial(),
data=dd)
expect_identical(m1$fit, m2$fit)
## Rolf Turner example:
X <- readRDS(system.file("test_data","turner_bb.rds",package="glmmTMB"))
fmla <- cbind(Dead, Alive) ~ (Trt + 0)/Dose + (Dose | Rep)
## baseline (binomial, not betabinomial)
fit0 <- glmmTMB(fmla, data = X, family = binomial(link = "cloglog"),
dispformula = ~1)
skip_on_cran()
## fails ATLAS tests with failure in inner optimization
## loop ("gradient function must return a numeric vector of length 16")
fit1 <- suppressWarnings(
## NaN function evaluation;
## non-pos-def Hessian;
## false convergence warning from nlminb
glmmTMB(fmla, data = X, family = betabinomial(link = "cloglog"),
dispformula = ~1)
)
fit1_glmmA <- readRDS(system.file("test_data","turner_bb_GLMMadaptive.rds",
package="glmmTMB"))
suppressWarnings(
fit2 <- glmmTMB(fmla, data = X,
family = betabinomial(link = "cloglog"),
dispformula = ~1,
start=list(beta=fixef(fit0)$cond))
## non-pos-def Hessian warning
## diagnose() suggests a singular fit
## but fixed effects actually look OK
)
ff1 <- fixef(fit1)$cond
ff2 <- fixef(fit2)$cond
## conclusions:
## (1) glmmTMB fit from initial starting vals is bad
## (2) glmmTMB fit from restart is OK (for fixed effects)
## (3) GLMMadaptive matches OK **but not** for nAGQ=1 (which _should_
## fit) --
np <- length(ff1)
ff_GA <- fit1_glmmA[1:np,ncol(fit1_glmmA)]
expect_equal(ff_GA, ff2, tolerance=0.05)
if (FALSE) {
## graphical exploration ...
cc <- cbind(ff1,ff2,fit1_glmmA[1:np,])
matplot(cc,type="b")
## plot diffs between glmmTMB fit and GLMMadaptive for nAGQ>1
adiff <- sweep(fit1_glmmA[1:np,-1],1,ff2,"-")
matplot(adiff, type="b",
ylab="diff from glmmTMB")
}
})
test_that("truncated", {
skip_on_cran()
## Poisson
set.seed(101)
z_tp <<- rpois(1000,lambda=exp(1))
z_tp <<- z_tp[z_tp>0]
if (FALSE) {
## n.b.: keep library() calls commented out, they may
## trigger CRAN complaints
## library(glmmADMB)
g0_tp <- glmmadmb(z_tp~1,family="truncpoiss",link="log")
fixef(g0) ## 0.9778591
}
g1_tp <- glmmTMB(z_tp~1,family=truncated_poisson(),
data=data.frame(z_tp))
expect_equal(unname(fixef(g1_tp)[[1]]),0.9778593,tolerance = 1e-5)
## Truncated poisson with zeros => invalid:
num_zeros <- 10
z_tp0 <<- c(rep(0, num_zeros), z_tp)
expect_error(g1_tp0 <- glmmTMB(z_tp0~1,family=truncated_poisson(),
data=data.frame(z_tp0)))
## Truncated poisson with zeros and zero-inflation:
g1_tp0 <- glmmTMB(z_tp0~1,family=truncated_poisson(),
ziformula=~1,
data=data.frame(z_tp0))
expect_equal( plogis(as.numeric(fixef(g1_tp0)$zi)), num_zeros/length(z_tp0), tolerance = 1e-7 ) ## Test zero-prob
expect_equal(fixef(g1_tp0)$cond, fixef(g1_tp)$cond, tolerance = 1e-6) ## Test conditional model
## nbinom2
set.seed(101)
z_nb <<- rnbinom(1000,size=2,mu=exp(2))
z_nb <<- z_nb[z_nb>0]
if (FALSE) {
## library(glmmADMB)
g0_nb2 <- glmmadmb(z_nb~1,family="truncnbinom",link="log")
fixef(g0_nb2) ## 1.980207
g0_nb2$alpha ## 1.893
}
g1_nb2 <- glmmTMB(z_nb~1,family=truncated_nbinom2(),
data=data.frame(z_nb))
expect_equal(c(unname(fixef(g1_nb2)[[1]]),sigma(g1_nb2)),
c(1.980207,1.892970),tolerance = 1e-5)
## Truncated nbinom2 with zeros => invalid:
num_zeros <- 10
z_nb0 <<- c(rep(0, num_zeros), z_nb)
expect_error(g1_nb0 <- glmmTMB(z_nb0~1,family=truncated_nbinom2(),
data=data.frame(z_nb0)))
## Truncated nbinom2 with zeros and zero-inflation:
g1_nb0 <- glmmTMB(z_nb0~1,family=truncated_nbinom2(),
ziformula=~1,
data=data.frame(z_nb0))
expect_equal( plogis(as.numeric(fixef(g1_nb0)$zi)), num_zeros/length(z_nb0), tolerance = 1e-7 ) ## Test zero-prob
expect_equal(fixef(g1_nb0)$cond, fixef(g1_nb2)$cond, tolerance = 1e-6) ## Test conditional model
## nbinom1: constant mean, so just a reparameterization of
## nbinom2 (should have the same likelihood)
## phi=(1+mu/k)=1+exp(2)/2 = 4.69
if (FALSE) {
## library(glmmADMB)
g0_nb1 <- glmmadmb(z_nb~1,family="truncnbinom1",link="log")
fixef(g0_nb1) ## 2.00112
g0_nb1$alpha ## 3.784
}
g1_nb1 <- glmmTMB(z_nb~1,family=truncated_nbinom1(),
data=data.frame(z_nb))
expect_equal(c(unname(fixef(g1_nb1)[[1]]),sigma(g1_nb1)),
c(1.980207,3.826909),tolerance = 1e-5)
## Truncated nbinom1 with zeros => invalid:
expect_error(g1_nb0 <- glmmTMB(z_nb0~1,family=truncated_nbinom1(),
data=data.frame(z_nb0)))
## Truncated nbinom2 with zeros and zero-inflation:
g1_nb0 <- glmmTMB(z_nb0~1,family=truncated_nbinom1(),
ziformula=~1,
data=data.frame(z_nb0))
expect_equal( plogis(as.numeric(fixef(g1_nb0)$zi)), num_zeros/length(z_nb0), tolerance = 1e-7 ) ## Test zero-prob
expect_equal(fixef(g1_nb0)$cond, fixef(g1_nb1)$cond, tolerance = 1e-6) ## Test conditional model
})
##Genpois
test_that("truncated_genpois",{
skip_on_cran()
tgp1 <<- glmmTMB(z_nb ~1, data=data.frame(z_nb), family=truncated_genpois())
tgpdat <<- data.frame(y=simulate(tgp1)[,1])
tgp2 <<- glmmTMB(y ~1, tgpdat, family=truncated_genpois())
expect_equal(sigma(tgp1), sigma(tgp2), tolerance = 1e-1)
expect_equal(fixef(tgp1)$cond[1], fixef(tgp2)$cond[1], tolerance = 1e-2)
cc <- confint(tgp2, full=TRUE)
expect_lt(cc["sigma", "2.5 %"], sigma(tgp1))
expect_lt(sigma(tgp1), cc["sigma", "97.5 %"])
expect_lt(cc["cond.(Intercept)", "2.5 %"], unname(fixef(tgp1)$cond[1]))
expect_lt(unname(fixef(tgp1)$cond[1]), cc["cond.(Intercept)", "97.5 %"])
})
context("trunc compois")
##Compois
test_that("truncated_compois",{
skip_on_cran()
cmpdat <<- data.frame(f=factor(rep(c('a','b'), 10)),
y=c(15,5,20,7,19,7,19,7,19,6,19,10,20,8,21,8,22,7,20,8))
tcmp1 <<- glmmTMB(y~f, cmpdat, family= truncated_compois())
expect_equal(unname(fixef(tcmp1)$cond), c(2.9652730653, -0.9773987194), tolerance = 1e-6)
expect_equal(sigma(tcmp1), 0.1833339, tolerance = 1e-6)
expect_equal(predict(tcmp1,type="response")[1:2], c(19.4, 7.3), tolerance = 1e-6)
})
context("compois")
test_that("compois", {
skip_on_cran()
# cmpdat <<- data.frame(f=factor(rep(c('a','b'), 10)),
# y=c(15,5,20,7,19,7,19,7,19,6,19,10,20,8,21,8,22,7,20,8))
cmp1 <<- glmmTMB(y~f, cmpdat, family=compois())
expect_equal(unname(fixef(cmp1)$cond), c(2.9652730653, -0.9773987194), tolerance = 1e-6)
expect_equal(sigma(cmp1), 0.1833339, tolerance = 1e-6)
expect_equal(predict(cmp1,type="response")[1:2], c(19.4, 7.3), tolerance = 1e-6)
})
context("genpois")
test_that("genpois", {
skip_on_cran()
gendat <<- data.frame(y=c(11,10,9,10,9,8,11,7,9,9,9,8,11,10,11,9,10,7,13,9))
gen1 <<- glmmTMB(y~1, family=genpois(), gendat)
expect_equal(unname(fixef(gen1)$cond), 2.251292, tolerance = 1e-6)
expect_equal(sigma(gen1), 0.235309, tolerance = 1e-6)
})
context("tweedie")
test_that("tweedie", {
skip_on_cran()
## Boiled down tweedie:::rtweedie :
rtweedie <- function (n, xi = power, mu, phi, power = NULL)
{
mu <- array(dim = n, mu)
if ((power > 1) & (power < 2)) {
rt <- array(dim = n, NA)
lambda <- mu^(2 - power)/(phi * (2 - power))
alpha <- (2 - power)/(1 - power)
gam <- phi * (power - 1) * mu^(power - 1)
N <- rpois(n, lambda = lambda)
for (i in (1:n)) {
rt[i] <- sum(rgamma(N[i], shape = -alpha, scale = gam[i]))
}
} else stop()
as.vector(rt)
}
## Simulation experiment
nobs <- 2000; mu <- 4; phi <- 2; p <- 1.7
set.seed(101)
y <- rtweedie(nobs, mu=mu, phi=phi, power=p)
twm <- glmmTMB(y ~ 1, family=tweedie(), data = NULL)
## Check mu
expect_equal(unname( exp(fixef(twm)$cond) ),
mu,
tolerance = .1)
## Check phi
expect_equal(unname( exp(fixef(twm)$disp) ),
phi,
tolerance = .1)
## Check power
expect_equal(unname( plogis(twm$fit$par["psi"]) + 1 ),
p,
tolerance = .01)
## Check internal rtweedie used by simulate
y2 <- c(simulate(twm)[,1],simulate(twm)[,1])
twm2 <- glmmTMB(y2 ~ 1, family=tweedie(), data = NULL)
expect_equal(fixef(twm)$cond, fixef(twm2)$cond, tolerance = 1e-1)
expect_equal(sigma(twm), sigma(twm2), tolerance = 1e-1)
expect_equal(ranef(twm),
structure(list(cond = list(), zi = list()), class = "ranef.glmmTMB"))
})
test_that("gaussian_sqrt", {
set.seed(101)
nobs <- 200
dd0_sqrt <- simfun0(nobs=nobs,sd.re=1,invlink=function(x) x^2)
dd0_sqrt$y <- rnorm(nobs,mean=dd0_sqrt$mu,sd=0.1)
g1 <- glmmTMB(y~x+(1|f), family=gaussian(link="sqrt"),
data=dd0_sqrt)
expect_equal(fixef(g1),
structure(list(cond = c(`(Intercept)` = 2.03810165917618, x = 1.00241002916226
), zi = numeric(0), disp = c(`(Intercept)` = -4.68350239019746)), class = "fixef.glmmTMB"),
tolerance = 1e-6)
})
test_that("link function info available", {
fam1 <- c("poisson","nbinom1","nbinom2","compois")
fam2 <- c("binomial","beta_family","betabinomial","tweedie")
for (f in c(fam1,paste0("truncated_",fam1),fam2)) {
## print(f)
expect_true("linkinv" %in% names(get(f)()))
}
})
d.AD <- data.frame(counts=c(18,17,15,20,10,20,25,13,12),
outcome=gl(3,1,9),
treatment=gl(3,3))
glm.D93 <- glmmTMB(counts ~ outcome + treatment, family = poisson(), data=d.AD)
glm.D93C <- glmmTMB(counts ~ outcome + treatment, family = "poisson", data=d.AD)
test_that("link info added to family", {
expect_warning(glm.D93B <- glmmTMB(counts ~ outcome + treatment,
family = list(family="poisson", link="log"),
d.AD))
## note update(..., family= ...) is only equal up to tolerance=5e-5 ...
expect_equal(predict(glm.D93),predict(glm.D93B))
expect_equal(predict(glm.D93),predict(glm.D93C))
})
test_that("lognormal family", {
test_fun <- function(n, m, v) {
x <- rnorm(n, mean=m, sd=sqrt(v))
dd <- data.frame(y=exp(x))
m1 <- glmmTMB(y~1, family="lognormal", data=dd)
m2 <- glmmTMB(log(y) ~ 1, data = dd)
expect_equal(logLik(m1), logLik(m2)-sum(log(dd$y)))
## noisy because of expected vs observed mean/variance
expect_equal(unname(fixef(m1)$cond), m+v/2, tolerance = 1e-2)
expect_equal(sigma(m1), sqrt((exp(v)-1)*exp(2*m+v)), tolerance = 5e-2)
}
set.seed(102)
test_fun(n = 2e4, m = 0.4, v = 0.2)
test_fun(n = 2e4, m = 0.7, v = 0.5)
})
test_that("t-distributed response", {
set.seed(101)
dd <- data.frame(y = 3 + 5*rt(1000, df = 10))
m1 <- glmmTMB(y ~ 1, family = t_family, data = dd)
expect_equal(unname(fixef(m1)$cond), 2.89682907080939,
tolerance = 1e-6)
expect_equal(sigma(m1), 4.96427774321411,
tolerance = 1e-6)
m2 <- glmmTMB(y ~ 1, family = t_family, data = dd,
start = list(psi = log(10)),
map = list(psi = factor(NA)))
expect_equal(sigma(m2), 5.01338678750139,
tolerance = 1e-6)
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.