Nothing
context("LINPRED and related functions")
skip_on_cran()
test_that("LINPRED basic fixed effects models", {
nimbleOptions(enableMacroComments = FALSE)
set.seed(123)
modInfo <- list(constants=list(y = rnorm(10), x=factor(sample(letters[1:3], 10, replace=T)),
x2=factor(sample(letters[4:5], 10, replace=T)),
x3=round(rnorm(10),3), x4=round(rnorm(10), 3), n = 10),
inits=list(beta_Intercept=0))
# Intercept-only model
code <- nimbleCode({
mu[1:n] <- LINPRED(~1)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept
}
beta_Intercept ~ dnorm(0, sd = 1000)
})
)
new_const <- modInfo$constants
new_const$x <- as.numeric(new_const$x)
new_const$x2 <- as.numeric(new_const$x2)
expect_equal(mod$getConstants(), new_const)
expect_equal(mod$modelDef$macroInits, list(beta_Intercept = 0))
# Covariates both factor and continous
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + x3)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x[x[i_1]] + beta_x3 *
x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x[1] <- 0
beta_x[2] ~ dnorm(0, sd = 1000)
beta_x[3] ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
})
)
expect_equivalent(mod$modelDef$macroInits, list(beta_Intercept = 0,
beta_x= structure(c(0, 0, 0), dim = 3L),
beta_x3=0))
expect_equivalent(mod$beta_x3, 0)
# Drop intercept
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + x3 - 1)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_x[x[i_1]] + beta_x3 * x3[i_1]
}
beta_x[1] ~ dnorm(0, sd = 1000)
beta_x[2] ~ dnorm(0, sd = 1000)
beta_x[3] ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
})
)
# Change prefix
code <- nimbleCode({
mu[1:n] <- LINPRED(~x, coefPrefix=alpha_)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- alpha_Intercept + alpha_x[x[i_1]]
}
alpha_Intercept ~ dnorm(0, sd = 1000)
alpha_x[1] <- 0
alpha_x[2] ~ dnorm(0, sd = 1000)
alpha_x[3] ~ dnorm(0, sd = 1000)
})
)
expect_equivalent(mod$modelDef$macroInits, list(alpha_Intercept = 0,
alpha_x = structure(c(0, 0, 0), dim = 3L)))
# With link function
code <- nimbleCode({
mu[1:n] <- LINPRED(~x3, link = log)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
log(mu[i_1]) <- beta_Intercept + beta_x3 * x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
})
)
# Set custom priors
priors <- setPriors(intercept="dnorm(0, sd=1)", coefficient="dnorm(0, sd=2)")
code <- nimbleCode({
mu[1:n] <- LINPRED(~x3, priors=priors)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x3 * x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1)
beta_x3 ~ dnorm(0, sd = 2)
})
)
# No priors
code <- nimbleCode({
mu[1:n] <- LINPRED(~x3, priors=NULL)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x3 * x3[i_1]
}
})
)
# Modmatnames = TRUE
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + x3, modelMatrixNames = TRUE)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x[x[i_1]] + beta_x3 *
x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x[1] <- 0
beta_x[2] <- beta_xb
beta_xb ~ dnorm(0, sd = 1000)
beta_x[3] <- beta_xc
beta_xc ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
})
)
# Continous-continous interaction
code <- nimbleCode({
mu[1:n] <- LINPRED(~x3*x4)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x3 * x3[i_1] + beta_x4 *
x4[i_1] + beta_x3_x4 * x3[i_1] * x4[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
beta_x4 ~ dnorm(0, sd = 1000)
beta_x3_x4 ~ dnorm(0, sd = 1000)
})
)
expect_equivalent(mod$modelDef$macroInits,
list(beta_Intercept=0, beta_x3=0, beta_x4=0, beta_x3_x4=0))
# Continous-factor interaction
code <- nimbleCode({
mu[1:n] <- LINPRED(~x*x3)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x[x[i_1]] + beta_x3 *
x3[i_1] + beta_x_x3[x[i_1]] * x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x[1] <- 0
beta_x[2] ~ dnorm(0, sd = 1000)
beta_x[3] ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
beta_x_x3[1] <- 0
beta_x_x3[2] ~ dnorm(0, sd = 1000)
beta_x_x3[3] ~ dnorm(0, sd = 1000)
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = structure(c(0, 0, 0), dim = 3L),
beta_x3 = 0, beta_x_x3 = c(0, 0, 0))
)
# continuous-factor interaction with modelMatrixNames = TRUE
code <- nimbleCode({
mu[1:n] <- LINPRED(~x*x3, modelMatrixNames = TRUE)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x[x[i_1]] + beta_x3 *
x3[i_1] + beta_x_x3[x[i_1]] * x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x[1] <- 0
beta_x[2] <- beta_xb
beta_xb ~ dnorm(0, sd = 1000)
beta_x[3] <- beta_xc
beta_xc ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
beta_x_x3[1] <- 0
beta_x_x3[2] <- beta_xb_x3
beta_xb_x3 ~ dnorm(0, sd = 1000)
beta_x_x3[3] <- beta_xc_x3
beta_xc_x3 ~ dnorm(0, sd = 1000)
})
)
# Drop some terms in interaction
code <- nimbleCode({
mu[1:n] <- LINPRED(~x*x3-1-x)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_x3 * x3[i_1] + beta_x_x3[x[i_1]] * x3[i_1]
}
beta_x3 ~ dnorm(0, sd = 1000)
beta_x_x3[1] ~ dnorm(0, sd = 1000)
beta_x_x3[2] ~ dnorm(0, sd = 1000)
beta_x_x3[3] ~ dnorm(0, sd = 1000)
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_x3 = 0, beta_x_x3 = c(0, 0, 0))
)
# continuous-factor interaction with modelMatrixNames = TRUE
code <- nimbleCode({
mu[1:n] <- LINPRED(~x*x3, modelMatrixNames = TRUE)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x[x[i_1]] + beta_x3 *
x3[i_1] + beta_x_x3[x[i_1]] * x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x[1] <- 0
beta_x[2] <- beta_xb
beta_xb ~ dnorm(0, sd = 1000)
beta_x[3] <- beta_xc
beta_xc ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
beta_x_x3[1] <- 0
beta_x_x3[2] <- beta_xb_x3
beta_xb_x3 ~ dnorm(0, sd = 1000)
beta_x_x3[3] <- beta_xc_x3
beta_xc_x3 ~ dnorm(0, sd = 1000)
})
)
# Factor-factor interaction
code <- nimbleCode({
mu[1:n] <- LINPRED(~x*x2)
})
mod <- nimbleModel(code, constants = modInfo$constants)
# For reference
mm <- model.matrix(~x*x2, as.data.frame(modInfo$constants[c("x", "x2")]))
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x[x[i_1]] + beta_x2[x2[i_1]] +
beta_x_x2[x[i_1], x2[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x[1] <- 0
beta_x[2] ~ dnorm(0, sd = 1000)
beta_x[3] ~ dnorm(0, sd = 1000)
beta_x2[1] <- 0
beta_x2[2] ~ dnorm(0, sd = 1000)
beta_x_x2[1, 1] <- 0
beta_x_x2[2, 1] <- 0
beta_x_x2[3, 1] <- 0
beta_x_x2[1, 2] <- 0
beta_x_x2[2, 2] ~ dnorm(0, sd = 1000)
beta_x_x2[3, 2] ~ dnorm(0, sd = 1000)
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = structure(c(0, 0, 0), dim = 3L),
beta_x2 = structure(c(0, 0), dim = 2L), beta_x_x2 = structure(c(0,
0, 0, 0, 0, 0), dim = 3:2))
)
# Factor-factor interaction with modelMatrixNames = TRUE
code <- nimbleCode({
mu[1:n] <- LINPRED(~x*x2, modelMatrixNames = TRUE)
})
mod <- nimbleModel(code, constants = modInfo$constants)
# For reference
mm <- model.matrix(~x*x2, as.data.frame(modInfo$constants[c("x", "x2")]))
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x[x[i_1]] + beta_x2[x2[i_1]] +
beta_x_x2[x[i_1], x2[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x[1] <- 0
beta_x[2] <- beta_xb
beta_xb ~ dnorm(0, sd = 1000)
beta_x[3] <- beta_xc
beta_xc ~ dnorm(0, sd = 1000)
beta_x2[1] <- 0
beta_x2[2] <- beta_x2e
beta_x2e ~ dnorm(0, sd = 1000)
beta_x_x2[1, 1] <- 0
beta_x_x2[2, 1] <- 0
beta_x_x2[3, 1] <- 0
beta_x_x2[1, 2] <- 0
beta_x_x2[2, 2] <- beta_xb_x2e
beta_xb_x2e ~ dnorm(0, sd = 1000)
beta_x_x2[3, 2] <- beta_xc_x2e
beta_xc_x2e ~ dnorm(0, sd = 1000)
})
)
# Covariate not in constants works (but is assumed to be continuous)
code <- nimbleCode({
mu[1:n] <- LINPRED(~x5, modelMatrixNames = TRUE)
})
mod <- nimbleModel(code, constants = modInfo$constants)
mod$getCode()
nimbleOptions(enableMacroComments = TRUE)
})
test_that("LINPRED error traps LHS in formula", {
nimbleOptions(enableMacroComments = FALSE)
set.seed(123)
modInfo <- list(constants=list(y = rnorm(10), x=round(rnorm(10), 3), n = 10))
# Missing LHS error trapping must be handled by buildMacro() in nimble
# Enable the test below when the use3pieces error trap PR in nimble is merged
#code <- quote(LINPRED(~1))
#expect_error(
# LINPRED$process(code, modelInfo=modInfo, environment()),
# "This macro must be used as part of an assignment"
#)
# LHS in formula
code <- quote(mu[1:n] <- LINPRED(y~1))
expect_error(
LINPRED$process(code, modelInfo=modInfo, environment()),
"Formula should be RHS-only"
)
})
test_that("LINPRED with uncorrelated random effects", {
nimbleOptions(enableMacroComments = FALSE)
set.seed(123)
modInfo <- list(constants= list(y = rnorm(10), group=factor(sample(letters[1:3], 10, replace=T)),
x2=factor(sample(letters[4:5], 10, replace=T)),
x=round(rnorm(10),3), x3=round(rnorm(10), 3),
x4 = factor(sample(letters[6:8], 10, replace=T)), n=10))
# Random intercept
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (1|group))
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = sd_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1)
)
# Set SD prefix
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (1|group), sdPrefix=alpha_)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
alpha_sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = alpha_sd_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
alpha_sd_group = 1)
)
# Set custom priors
pr <- setPriors(intercept="dnorm(0, sd=1)", sd="dunif(0, 1)")
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (1|group), priors=pr)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 1)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = sd_group)
}
})
)
# Uncorrelated random continuous slopes and intercepts
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x||group))
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]] +
beta_x_group[group[i_1]] * x[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = sd_group)
}
sd_x_group ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_x_group[i_3] ~ dnorm(0, sd = sd_x_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1, beta_x_group = c(0, 0, 0), sd_x_group = 1)
)
# Just random slopes, not intercepts
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x-1||group))
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_x_group[group[i_1]] *
x[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_x_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_x_group[i_2] ~ dnorm(0, sd = sd_x_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0,
beta_x_group = c(0, 0, 0), sd_x_group = 1)
)
# No fixed effects
code <- nimbleCode({
mu[1:n] <- LINPRED(~0 + (x||group))
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_group[group[i_1]] + beta_x_group[group[i_1]] *
x[i_1]
}
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = sd_group)
}
sd_x_group ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_x_group[i_3] ~ dnorm(0, sd = sd_x_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1, beta_x_group = c(0, 0, 0), sd_x_group = 1)
)
# Factor random slope
code <- nimbleCode({
mu[1:n] <- LINPRED(~x2 + (x2||group))
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x2[x2[i_1]] + beta_group[group[i_1]] +
beta_x2_group[x2[i_1], group[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x2[1] <- 0
beta_x2[2] ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = sd_group)
}
sd_x2d_group ~ dunif(0, 100)
sd_x2e_group ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_x2_group[1, i_3] ~ dnorm(0, sd = sd_x2d_group)
}
for (i_4 in 1:3) {
beta_x2_group[2, i_4] ~ dnorm(0, sd = sd_x2e_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x2 = structure(c(0, 0), dim = 2L),
beta_group = structure(c(0, 0, 0), dim = 3L), sd_group = 1,
beta_x2_group = structure(c(0, 0, 0, 0, 0, 0), dim = 2:3),
sd_x2d_group = 1, sd_x2e_group = 1)
)
# Continuous-continous Interaction in random term
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x:x3||group))
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]] +
beta_x_x3_group[group[i_1]] * x[i_1] * x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = sd_group)
}
sd_x_x3_group ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_x_x3_group[i_3] ~ dnorm(0, sd = sd_x_x3_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1, beta_x_x3_group = c(0, 0, 0), sd_x_x3_group = 1)
)
# Continuous-factor interaction in random term
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x:x2||group))
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]] +
beta_x_x2_group[x2[i_1], group[i_1]] * x[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = sd_group)
}
sd_x_x2d_group ~ dunif(0, 100)
sd_x_x2e_group ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_x_x2_group[1, i_3] ~ dnorm(0, sd = sd_x_x2d_group)
}
for (i_4 in 1:3) {
beta_x_x2_group[2, i_4] ~ dnorm(0, sd = sd_x_x2e_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1, beta_x_x2_group = structure(c(0, 0, 0, 0, 0, 0), dim = 2:3),
sd_x_x2d_group = 1, sd_x_x2e_group = 1)
)
# Factor-factor interaction in random term
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x2:x4||group))
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]] +
beta_x2_x4_group[x2[i_1], x4[i_1], group[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = sd_group)
}
sd_x2d_x4f_group ~ dunif(0, 100)
sd_x2e_x4f_group ~ dunif(0, 100)
sd_x2d_x4g_group ~ dunif(0, 100)
sd_x2e_x4g_group ~ dunif(0, 100)
sd_x2d_x4h_group ~ dunif(0, 100)
sd_x2e_x4h_group ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_x2_x4_group[1, 1, i_3] ~ dnorm(0, sd = sd_x2d_x4f_group)
}
for (i_4 in 1:3) {
beta_x2_x4_group[2, 1, i_4] ~ dnorm(0, sd = sd_x2e_x4f_group)
}
for (i_5 in 1:3) {
beta_x2_x4_group[1, 2, i_5] ~ dnorm(0, sd = sd_x2d_x4g_group)
}
for (i_6 in 1:3) {
beta_x2_x4_group[2, 2, i_6] ~ dnorm(0, sd = sd_x2e_x4g_group)
}
for (i_7 in 1:3) {
beta_x2_x4_group[1, 3, i_7] ~ dnorm(0, sd = sd_x2d_x4h_group)
}
for (i_8 in 1:3) {
beta_x2_x4_group[2, 3, i_8] ~ dnorm(0, sd = sd_x2e_x4h_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1,
beta_x2_x4_group = structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), dim = c(2L, 3L, 3L)),
sd_x2d_x4f_group = 1, sd_x2e_x4f_group = 1, sd_x2d_x4g_group = 1,
sd_x2e_x4g_group = 1, sd_x2d_x4h_group = 1, sd_x2e_x4h_group = 1)
)
# Drop terms in random expression
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x-1||group))
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_x_group[group[i_1]] *
x[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_x_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_x_group[i_2] ~ dnorm(0, sd = sd_x_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_x_group = c(0, 0, 0), sd_x_group = 1)
)
nimbleOptions(enableMacroComments=TRUE)
})
test_that("Centering with uncorrelated random effects", {
nimbleOptions(enableMacroComments = FALSE)
set.seed(123)
modInfo <- list(constants= list(y = rnorm(10), group=factor(sample(letters[1:3], 10, replace=T)),
x2=factor(sample(letters[4:5], 10, replace=T)),
x=round(rnorm(10),3), x3=round(rnorm(10), 3),
x4 = factor(sample(letters[6:8], 10, replace=T)), n=10))
# Center random effects on group instead of 0
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x||group), centerVar=group)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_group[group[i_1]] + beta_x_group[group[i_1]] *
x[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(beta_Intercept, sd = sd_group)
}
sd_x_group ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_x_group[i_3] ~ dnorm(beta_x, sd = sd_x_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1, beta_x_group = c(0, 0, 0), sd_x_group = 1)
)
# Centering when there are multiple grouping factors
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x||group) + (1|x4), centerVar=group)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_group[group[i_1]] + beta_x_group[group[i_1]] *
x[i_1] + beta_x4[x4[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(beta_Intercept, sd = sd_group)
}
sd_x_group ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_x_group[i_3] ~ dnorm(beta_x, sd = sd_x_group)
}
sd_x4 ~ dunif(0, 100)
for (i_4 in 1:3) {
beta_x4[i_4] ~ dnorm(0, sd = sd_x4)
}
})
)
# Centering with no intercept
code <- nimbleCode({
mu[1:n] <- LINPRED(~0 + x + (x||group), centerVar=group)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_group[group[i_1]] + beta_x_group[group[i_1]] *
x[i_1]
}
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = sd_group)
}
sd_x_group ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_x_group[i_3] ~ dnorm(beta_x, sd = sd_x_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1, beta_x_group = c(0, 0, 0), sd_x_group = 1)
)
# Centering when there are no fixed effects
code <- nimbleCode({
mu[1:n] <- LINPRED(~0 + (x||group), centerVar=group)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_group[group[i_1]] + beta_x_group[group[i_1]] *
x[i_1]
}
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = sd_group)
}
sd_x_group ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_x_group[i_3] ~ dnorm(0, sd = sd_x_group)
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1, beta_x_group = c(0, 0, 0), sd_x_group = 1)
)
nimbleOptions(enableMacroComments = TRUE)
})
test_that("noncentered parameterization with uncorrelated random effects", {
nimbleOptions(enableMacroComments = FALSE)
set.seed(123)
modInfo <- list(constants= list(y = rnorm(10), group=factor(sample(letters[1:3], 10, replace=T)),
x2=factor(sample(letters[4:5], 10, replace=T)),
x=round(rnorm(10),3), x3=round(rnorm(10), 3),
x4 = factor(sample(letters[6:8], 10, replace=T)), n=10))
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x||group), noncentered=TRUE)
})
mod <- nimbleModel(code, constants=modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]] +
beta_x_group[group[i_1]] * x[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group_raw[i_2] ~ dnorm(0, sd = 1)
}
for (i_3 in 1:3) {
beta_group[i_3] <- 0 + sd_group * beta_group_raw[i_3]
}
sd_x_group ~ dunif(0, 100)
for (i_4 in 1:3) {
beta_x_group_raw[i_4] ~ dnorm(0, sd = 1)
}
for (i_5 in 1:3) {
beta_x_group[i_5] <- 0 + sd_x_group * beta_x_group_raw[i_5]
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1, beta_x_group = c(0, 0, 0), sd_x_group = 1,
beta_group_raw = structure(c(0, 0, 0), dim = 3L), beta_x_group_raw = c(0, 0, 0))
)
# With centering variable also
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x||group), noncentered=TRUE, centerVar=group)
})
mod <- nimbleModel(code, constants=modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_group[group[i_1]] + beta_x_group[group[i_1]] *
x[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group_raw[i_2] ~ dnorm(0, sd = 1)
}
for (i_3 in 1:3) {
beta_group[i_3] <- beta_Intercept + sd_group * beta_group_raw[i_3]
}
sd_x_group ~ dunif(0, 100)
for (i_4 in 1:3) {
beta_x_group_raw[i_4] ~ dnorm(0, sd = 1)
}
for (i_5 in 1:3) {
beta_x_group[i_5] <- beta_x + sd_x_group * beta_x_group_raw[i_5]
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1, beta_x_group = c(0, 0, 0), sd_x_group = 1,
beta_group_raw = structure(c(0, 0, 0), dim = 3L), beta_x_group_raw = c(0, 0, 0))
)
# Factor slope
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x2||group), noncentered=TRUE)
})
mod <- nimbleModel(code, constants=modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]] +
beta_x2_group[x2[i_1], group[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_group_raw[i_2] ~ dnorm(0, sd = 1)
}
for (i_3 in 1:3) {
beta_group[i_3] <- 0 + sd_group * beta_group_raw[i_3]
}
sd_x2d_group ~ dunif(0, 100)
sd_x2e_group ~ dunif(0, 100)
for (i_4 in 1:3) {
beta_x2_group_raw[1, i_4] ~ dnorm(0, sd = 1)
}
for (i_5 in 1:3) {
beta_x2_group[1, i_5] <- 0 + sd_x2d_group * beta_x2_group_raw[1,
i_5]
}
for (i_6 in 1:3) {
beta_x2_group_raw[2, i_6] ~ dnorm(0, sd = 1)
}
for (i_7 in 1:3) {
beta_x2_group[2, i_7] <- 0 + sd_x2e_group * beta_x2_group_raw[2,
i_7]
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
sd_group = 1, beta_x2_group = structure(c(0, 0, 0, 0, 0, 0), dim = 2:3),
sd_x2d_group = 1, sd_x2e_group = 1, beta_group_raw = structure(c(0, 0, 0), dim = 3L),
beta_x2_group_raw = structure(c(0, 0, 0, 0, 0, 0), dim = 2:3))
)
nimbleOptions(enableMacroComments = TRUE)
})
test_that("correlated random effects", {
nimbleOptions(enableMacroComments = FALSE)
set.seed(123)
modInfo <- list(constants= list(y = rnorm(10), group=factor(sample(letters[1:3], 10, replace=T)),
x2=factor(sample(letters[4:5], 10, replace=T)),
x=round(rnorm(10),3), x3=round(rnorm(10), 3),
x4 = factor(sample(letters[6:8], 10, replace=T)), n=10))
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x|group))
})
mod <- nimbleModel(code, constants=modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]] +
beta_x_group[group[i_1]] * x[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
sd_x_group ~ dunif(0, 100)
re_sds_group[1] <- sd_group
re_sds_group[2] <- sd_x_group
Ustar_group[1:2, 1:2] ~ dlkj_corr_cholesky(1, 2)
U_group[1:2, 1:2] <- uppertri_mult_diag(Ustar_group[1:2,
1:2], re_sds_group[1:2])
re_means_group[1] <- 0
re_means_group[2] <- 0
for (i_2 in 1:3) {
B_group[i_2, 1:2] ~ dmnorm(re_means_group[1:2], cholesky = U_group[1:2,
1:2], prec_param = 0)
beta_group[i_2] <- B_group[i_2, 1]
beta_x_group[i_2] <- B_group[i_2, 2]
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
beta_x_group = c(0, 0, 0), sd_group = 1, sd_x_group = 1)
)
# Set LKJ shape value
pr <- setPriors(lkjShape=3)
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x|group), priors=pr)
})
mod <- nimbleModel(code, constants=modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]] +
beta_x_group[group[i_1]] * x[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
sd_x_group ~ dunif(0, 100)
re_sds_group[1] <- sd_group
re_sds_group[2] <- sd_x_group
Ustar_group[1:2, 1:2] ~ dlkj_corr_cholesky(3, 2)
U_group[1:2, 1:2] <- uppertri_mult_diag(Ustar_group[1:2,
1:2], re_sds_group[1:2])
re_means_group[1] <- 0
re_means_group[2] <- 0
for (i_2 in 1:3) {
B_group[i_2, 1:2] ~ dmnorm(re_means_group[1:2], cholesky = U_group[1:2,
1:2], prec_param = 0)
beta_group[i_2] <- B_group[i_2, 1]
beta_x_group[i_2] <- B_group[i_2, 2]
}
})
)
# More than two correlated params
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x + x3|group))
})
mod <- nimbleModel(code, constants=modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]] +
beta_x_group[group[i_1]] * x[i_1] + beta_x3_group[group[i_1]] *
x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
sd_x_group ~ dunif(0, 100)
sd_x3_group ~ dunif(0, 100)
re_sds_group[1] <- sd_group
re_sds_group[2] <- sd_x_group
re_sds_group[3] <- sd_x3_group
Ustar_group[1:3, 1:3] ~ dlkj_corr_cholesky(1, 3)
U_group[1:3, 1:3] <- uppertri_mult_diag(Ustar_group[1:3,
1:3], re_sds_group[1:3])
re_means_group[1] <- 0
re_means_group[2] <- 0
re_means_group[3] <- 0
for (i_2 in 1:3) {
B_group[i_2, 1:3] ~ dmnorm(re_means_group[1:3], cholesky = U_group[1:3,
1:3], prec_param = 0)
beta_group[i_2] <- B_group[i_2, 1]
beta_x_group[i_2] <- B_group[i_2, 2]
beta_x3_group[i_2] <- B_group[i_2, 3]
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
beta_x_group = c(0, 0, 0), beta_x3_group = c(0, 0, 0), sd_group = 1,
sd_x_group = 1, sd_x3_group = 1)
)
# Factor random slopes don't work
code <- quote(LINPRED_PRIORS(~x + (x2|group)))
expect_error(LINPRED_PRIORS$process(code, modInfo, NULL), "Correlated")
nimbleOptions(enableMacroComments = TRUE)
})
test_that("Centering with correlated random effects", {
nimbleOptions(enableMacroComments = FALSE)
set.seed(123)
modInfo <- list(constants= list(y = rnorm(10), group=factor(sample(letters[1:3], 10, replace=T)),
x2=factor(sample(letters[4:5], 10, replace=T)),
x=round(rnorm(10),3), x3=round(rnorm(10), 3),
x4 = factor(sample(letters[6:8], 10, replace=T)), n=10))
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (x|group), centerVar=group)
})
mod <- nimbleModel(code, constants=modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_group[group[i_1]] + beta_x_group[group[i_1]] *
x[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
sd_x_group ~ dunif(0, 100)
re_sds_group[1] <- sd_group
re_sds_group[2] <- sd_x_group
Ustar_group[1:2, 1:2] ~ dlkj_corr_cholesky(1, 2)
U_group[1:2, 1:2] <- uppertri_mult_diag(Ustar_group[1:2,
1:2], re_sds_group[1:2])
re_means_group[1] <- beta_Intercept
re_means_group[2] <- beta_x
for (i_2 in 1:3) {
B_group[i_2, 1:2] ~ dmnorm(re_means_group[1:2], cholesky = U_group[1:2,
1:2], prec_param = 0)
beta_group[i_2] <- B_group[i_2, 1]
beta_x_group[i_2] <- B_group[i_2, 2]
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_Intercept = 0, beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
beta_x_group = c(0, 0, 0), sd_group = 1, sd_x_group = 1)
)
# With intercept dropped
code <- nimbleCode({
mu[1:n] <- LINPRED(~0 + x + (x|group), centerVar=group)
})
mod <- nimbleModel(code, constants=modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_group[group[i_1]] + beta_x_group[group[i_1]] *
x[i_1]
}
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
sd_x_group ~ dunif(0, 100)
re_sds_group[1] <- sd_group
re_sds_group[2] <- sd_x_group
Ustar_group[1:2, 1:2] ~ dlkj_corr_cholesky(1, 2)
U_group[1:2, 1:2] <- uppertri_mult_diag(Ustar_group[1:2,
1:2], re_sds_group[1:2])
re_means_group[1] <- 0
re_means_group[2] <- beta_x
for (i_2 in 1:3) {
B_group[i_2, 1:2] ~ dmnorm(re_means_group[1:2], cholesky = U_group[1:2,
1:2], prec_param = 0)
beta_group[i_2] <- B_group[i_2, 1]
beta_x_group[i_2] <- B_group[i_2, 2]
}
})
)
expect_equal(
mod$modelDef$macroInits,
list(beta_x = 0, beta_group = structure(c(0, 0, 0), dim = 3L),
beta_x_group = c(0, 0, 0), sd_group = 1, sd_x_group = 1)
)
nimbleOptions(enableMacroComments = TRUE)
})
test_that("Noncentered parameterization doesn't work with correlated random effects", {
nimbleOptions(enableMacroComments = FALSE)
set.seed(123)
modInfo <- list(constants= list(y = rnorm(10), group=factor(sample(letters[1:3], 10, replace=T)),
x2=factor(sample(letters[4:5], 10, replace=T)),
x=round(rnorm(10),3), x3=round(rnorm(10), 3),
x4 = factor(sample(letters[6:8], 10, replace=T)), n=10))
# Noncentered doesn't work with correlated random effects
code <- quote(LINPRED_PRIORS(~x + (x|group), noncentered=TRUE))
expect_error(LINPRED_PRIORS$process(code, modInfo, NULL)$code, "Noncentered")
nimbleOptions(enableMacroComments = TRUE)
})
test_that("LINPRED with brackets on RHS of formula", {
nimbleOptions(enableMacroComments = FALSE)
set.seed(123)
modInfo <- list(constants=list(y = rnorm(10),
x=matrix(sample(letters[1:3], 10, replace=T), ncol=1),
x2=factor(sample(letters[4:5], 10, replace=T)),
site = sample(1:10, 10, replace=TRUE),
x3=round(rnorm(10),3), x4=round(rnorm(10), 3), n = 10, J =3),
inits=list(beta_Intercept=0))
# Different dimensions on RHS
code <- nimbleCode({
mu[1:n] <- LINPRED(~x[1:n, 1] + x3)
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x[x[i_1, 1]] + beta_x3 *
x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x[1] <- 0
beta_x[2] ~ dnorm(0, sd = 1000)
beta_x[3] ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
})
)
# Nested indexing
code <- nimbleCode({
mu[1:n] <- LINPRED(~x2 + x3[site[1:n]])
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x2[x2[i_1]] + beta_x3 *
x3[site[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x2[1] <- 0
beta_x2[2] ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
})
)
# Interaction with different indices
code <- nimbleCode({
mu[1:n] <- LINPRED(~x[1:n,1]*x3[site[1:n]])
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x[x[i_1, 1]] + beta_x3 *
x3[site[i_1]] + beta_x_x3[x[i_1, 1]] * x3[site[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x[1] <- 0
beta_x[2] ~ dnorm(0, sd = 1000)
beta_x[3] ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
beta_x_x3[1] <- 0
beta_x_x3[2] ~ dnorm(0, sd = 1000)
beta_x_x3[3] ~ dnorm(0, sd = 1000)
})
)
# Random effect
code <- nimbleCode({
mu[1:n] <- LINPRED(~(x3[site[1:n]]||x[1:n,1]))
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x[x[i_1, 1]] + beta_x3_x[x[i_1,
1]] * x3[site[i_1]]
}
beta_Intercept ~ dnorm(0, sd = 1000)
sd_x ~ dunif(0, 100)
for (i_2 in 1:3) {
beta_x[i_2] ~ dnorm(0, sd = sd_x)
}
sd_x3_x ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_x3_x[i_3] ~ dnorm(0, sd = sd_x3_x)
}
})
)
nimbleOptions(enableMacroComments = TRUE)
})
test_that("LINPRED with factor array covariate", {
nimbleOptions(enableMacroComments = FALSE)
set.seed(123)
modInfo <- list(constants=list(y=matrix(rnorm(12), 3, 4),
x=matrix(sample(letters[1:3], 12, replace=T), 3, 4),
M=3, J=4))
code <- nimbleCode({
mu[1:M, 1:J] <- LINPRED(~x)
})
mod <- nimbleModel(code, constants=modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:M) {
for (i_2 in 1:J) {
mu[i_1, i_2] <- beta_Intercept + beta_x[x[i_1, i_2]]
}
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x[1] <- 0
beta_x[2] ~ dnorm(0, sd = 1000)
beta_x[3] ~ dnorm(0, sd = 1000)
})
)
expect_equal(dim(mod$getConstants()$x), dim(modInfo$constants$x))
nimbleOptions(enableMacroComments = TRUE)
})
test_that("Nested random effects", {
nimbleOptions(enableMacroComments = FALSE)
set.seed(123)
modInfo <- list(constants=list(y = rnorm(10),
x=factor(sample(letters[1:3], 10, replace=T)),
w = factor(sample(letters[6:8], 10, replace=T)),
x3=round(rnorm(10),3), n=10),
indexCreator=nimble:::labelFunctionCreator("i"))
# w:x notation
# Linear predictor
code <- quote(mu[1:n] <- LINPRED(~x3 + (x3||x:w), priors=NULL))
out <- LINPRED$process(code, modelInfo=modInfo, NULL)
# Make sure new combined levels constant is added
expect_equal(
out$modelInfo$constants$x_w,
factor(paste(modInfo$constants$x, modInfo$constants$w, sep=":"))
)
expect_equal(length(levels(out$modelInfo$constants$x_w)), 7)
code <- nimbleCode({
mu[1:n] <- LINPRED(~x3 + (x3||x:w))
})
mod <- nimbleModel(code, constants=modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x3 * x3[i_1] + beta_x_w[x_w[i_1]] +
beta_x3_x_w[x_w[i_1]] * x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
sd_x_w ~ dunif(0, 100)
for (i_2 in 1:7) {
beta_x_w[i_2] ~ dnorm(0, sd = sd_x_w)
}
sd_x3_x_w ~ dunif(0, 100)
for (i_3 in 1:7) {
beta_x3_x_w[i_3] ~ dnorm(0, sd = sd_x3_x_w)
}
})
)
expect_equal(mod$getConstants()$x_w, as.numeric(out$modelInfo$constants$x_w))
# w/x notation, which adds |w random effect(s)
bars <- reformulas::findbars(~x3 + (x3||w/x)) # for reference
code <- nimbleCode({
mu[1:n] <- LINPRED(~x3 + (x3||w/x))
})
mod <- nimbleModel(code, constants=modInfo$constants)
expect_equal(
mod$getCode(),
quote({
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x3 * x3[i_1] + beta_x_w[x_w[i_1]] +
beta_w[w[i_1]] + beta_x3_x_w[x_w[i_1]] * x3[i_1] +
beta_x3_w[w[i_1]] * x3[i_1]
}
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x3 ~ dnorm(0, sd = 1000)
sd_x_w ~ dunif(0, 100)
for (i_2 in 1:7) {
beta_x_w[i_2] ~ dnorm(0, sd = sd_x_w)
}
sd_w ~ dunif(0, 100)
for (i_3 in 1:3) {
beta_w[i_3] ~ dnorm(0, sd = sd_w)
}
sd_x3_x_w ~ dunif(0, 100)
for (i_4 in 1:7) {
beta_x3_x_w[i_4] ~ dnorm(0, sd = sd_x3_x_w)
}
sd_x3_w ~ dunif(0, 100)
for (i_5 in 1:3) {
beta_x3_w[i_5] ~ dnorm(0, sd = sd_x3_w)
}
})
)
expect_equal(mod$getConstants()$x_w, as.numeric(out$modelInfo$constants$x_w))
nimbleOptions(enableMacroComments = TRUE)
})
test_that("Macro comments work with LINPRED", {
nimbleOptions(enableMacroComments = TRUE)
set.seed(123)
modInfo <- list(constants= list(y = rnorm(10), group=factor(sample(letters[1:3], 10, replace=T)),
x2=factor(sample(letters[4:5], 10, replace=T)),
x=round(rnorm(10),3), x3=round(rnorm(10), 3),
x4 = factor(sample(letters[6:8], 10, replace=T)), n=10))
# Random intercept
code <- nimbleCode({
mu[1:n] <- LINPRED(~x + (1|group))
})
mod <- nimbleModel(code, constants = modInfo$constants)
expect_equal(
mod$getCode(),
quote({
"# LINPRED"
" ## nimbleMacros::FORLOOP"
for (i_1 in 1:n) {
mu[i_1] <- beta_Intercept + beta_x * x[i_1] + beta_group[group[i_1]]
}
" ## ----"
" ## nimbleMacros::LINPRED_PRIORS"
beta_Intercept ~ dnorm(0, sd = 1000)
beta_x ~ dnorm(0, sd = 1000)
sd_group ~ dunif(0, 100)
" ### nimbleMacros::FORLOOP"
for (i_2 in 1:3) {
beta_group[i_2] ~ dnorm(0, sd = sd_group)
}
" ### ----"
" ## ----"
"# ----"
})
)
})
test_that("removeBracketsFromFormula",{
expect_equal(
removeBracketsFromFormula(~x + x2),
~x + x2
)
expect_equal(
removeBracketsFromFormula(~x[1:n] + x2),
~x + x2
)
expect_equal(
removeBracketsFromFormula(~x[1:n] + x2[1:m]),
~x + x2
)
expect_equal(
removeBracketsFromFormula(~x[alpha[1:n]] + x2[1:m]),
~x + x2
)
expect_equal(
removeBracketsFromFormula(~x[1:N, 1:J, 1:K[1:N]] + x2[1:m]),
~x + x2
)
})
test_that("extractBracket", {
expect_error(extractBracket(quote(x)))
expect_equal(
extractBracket(quote(x[1:n])),
c(x="[1:n]")
)
expect_equal(
extractBracket(quote(x[alpha[1:n]])),
c(x="[alpha[1:n]]")
)
})
test_that("extractAllBrackets", {
expect_equal(
extractAllBrackets(~x+x2),
NULL
)
expect_equal(
extractAllBrackets(~x[1:n]),
c(x="[1:n]")
)
expect_equal(
extractAllBrackets(~x[1:n]+x2),
c(x="[1:n]")
)
expect_equal(
extractAllBrackets(~x[1:n]+x2[1:k]),
c(x="[1:n]", x2="[1:k]")
)
expect_equal(
extractAllBrackets(~x[1:n]*x2[1:k]),
c(x="[1:n]", x2="[1:k]")
)
expect_equal(
extractAllBrackets(~x[alpha[1:n]]+x2[1:k]),
c(x="[alpha[1:n]]", x2="[1:k]")
)
})
test_that("makeDummyDataFrame", {
set.seed(123)
dat <- list(x=factor(sample(letters[1:3], 10, replace=T)),
x2=factor(sample(letters[4:5], 10, replace=T)),
x3=round(rnorm(10),3))
expect_equal(
makeDummyDataFrame(~x + x3, dat),
data.frame(x=factor("c", levels=levels(dat$x)), x3=1.224)
)
expect_equal(
makeDummyDataFrame(~x + x3 + x4, dat),
data.frame(x=factor("c", levels=levels(dat$x)), x3=1.224, x4=0)
)
dat <- list(x=rnorm(3), z=NULL)
expect_error(
makeDummyDataFrame(~x + z, dat),
"List element z in constants is NULL"
)
})
test_that("processNestedRandomEffects", {
dat <- list(group=factor(c("a","b","c")), group2=factor(c("d","e","f")))
out1 <- processNestedRandomEffects(quote(1|group), dat)
expect_equal(out1$barExp, quote(1|group))
expect_equal(out1$constants, NULL)
out2 <- processNestedRandomEffects(quote(1|group:group2), dat)
expect_equal(out2$barExp, quote(1|group_group2))
expect_equal(out2$constants, list(group_group2=factor(c("a:d", "b:e", "c:f"))))
# Check the new factor is not duplicated
dat2 <- c(dat, out2$constants)
out3 <- processNestedRandomEffects(quote(1|group:group2), dat2)
expect_equal(out3$constants, list())
# Handle character matrices
dat2 <- list(group=matrix(c("a","b","b","a"), 2, 2),
group2=matrix(c("c","d","c","d"), 2, 2))
out4 <- processNestedRandomEffects(quote(1|group:group2), dat2)
expect_equal(out4$constants$group_group2,
matrix(c("a:c","b:d","b:c","a:d"), 2, 2))
# Mismatched array sizes should error
dat3 <- list(group=matrix(c("a","b","b","a","z","z"), 3, 2),
group2=matrix(c("c","d","c","d"), 2, 2))
expect_error(processNestedRandomEffects(quote(1|group:group2), dat3))
})
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.