You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#Simple GLMM. Based on mosquito death in a experimental hut trial
#Here random effects are crossed, rather than nested.
#But the overall method should apply more generally
#Can provide stan model comparison, if useful
library(ggplot2)
library(drjacoby)
#In this trial, we are evaluating two mosquito nets, one of which is an untreated (control) net
#There are four huts: each night a volunteer sleeps in each hut, under the net.
#The sleepers & the nets are moved around the different huts over the course of 32 nights
#Here's the trial structure. For 'net', 0=untreated control, 1=insecticide-treated net (ITN)
dfm <- data.frame('hut'=rep(c(1,2,3,4),32), 'sleeper' = c(rep(c(1,2,3,4),8), rep(c(4,1,2,3),8),
rep(c(3,4,1,2),8), rep(c(2,3,4,1),8)), 'net' = rep(c(0,0,1,1,1,1,0,0), 16) )
#How many mosquitoes enter each hut each night? Draw from a Poisson distribution
dfm$n <- rpois(128, lambda = 11)
dfm$dead <- NA
#To simulate how many mosquitoes die each night (binomial sampling), we include an effect for the ITN
#We also include a weaker effect, depending on the hut & sleeper
for(i in 1:128){
rho <- -1 + 0.1dfm$hut[i] - 0.2dfm$sleeper[i] + 1.5 * dfm$net[i]#prob on the logistic scale
#whack a bit o' noise on it
rho2 <- rnorm(1,mean = rho, sd = 0.1)
#convert to probability scale
prb <- exp(rho2)/(1+exp(rho2))
dfm$dead[i] <- rbinom(1, size = dfm$n[i], prob = prb)
}
#Now prepare what we need for drjacoby. There are 4 random effects for hut and 4 for sleeper.
#In total, there are 16 combinations of these
M <- 16 # no. of combinations of the two random effects? (4 values each)
df_params <- define_params(name = "hut1", min = -Inf, max = Inf, init = 0, block = c(1,2,3,4,M+1),
name = "hut2", min = -Inf, max = Inf, init = 0, block = c(5,6,7,8,M+1),
name = "hut3", min = -Inf, max = Inf, init = 0, block = c(9,10,11,12,M+1),
name = "hut4", min = -Inf, max = Inf, init = 0, block = c(13,14,15,16,M+1),
name = "sleeper1", min = -Inf, max = Inf, init = 0, block = c(1,5,9,13,M+1),
name = "sleeper2", min = -Inf, max = Inf, init = 0, block = c(2,6,10,14,M+1),
name = "sleeper3", min = -Inf, max = Inf, init = 0, block = c(3,7,11,15,M+1),
name = "sleeper4", min = -Inf, max = Inf, init = 0, block = c(4,8,12,16,M+1),
name = "sigma_hut", min = 0, max = Inf, init = 1, block = M+1,
name = "sigma_sleeper", min = 0, max = Inf, init = 1, block = M+1,
name = "a1", min = -Inf, max = Inf, init = 0, block = 1:M,
name = "a0", min = -Inf, max = Inf, init = 0, block = 1:M)
#Now we have to work out which data points need to go with each block
#empty list for the data
lst <- list()
#empty dataframe
dfa <- data.frame('blck'=rep(0,16), 'blckH'=rep(0,16), 'blckS'=rep(0,16))
count <- 1
for(j in 1:4){
for(k in 1:4){
aux <- dfm[dfm$hut == j & dfm$sleeper == k,]
#preare data for a block, store as a list
lst[[as.character(count)]] <- list(total = aux$n, dead = aux$dead, net = aux$net)
dfa$blck[count] <- count
dfa$blckH[count] <- j
dfa$blckS[count] <- k
count <- count + 1
}
}
#Look at dfa. For each block, which random effect do we need for hut (H) and sleeper (S)?
head(dfa)
#define log-likelihood function
r_loglike <- function(params, data, misc) {
#unpack parameters
#Patient-specific first
hut <- rep(0,4)
sleeper <- rep(0,4)
for (i in 1:4) {
hut[i] <- params[i]
sleeper[i] <- params[4 + i]
}
a1 <- params["a1"]
a0 <- params["a0"]
sigma_hut <- params["sigma_hut"]
sigma_sleeper <- params["sigma_sleeper"]
#get current update block
block = misc$block
#distinct method for first M blocks, vs (M+1)
ret = 0.0;
if (block == (M+1)) { # // likelihood for the global parameters
for(i in 1:4){
ret <- ret + dnorm(hut[i], mean=0, sd=sigma_hut, log=T) +
dnorm(sleeper[i], mean=0, sd=sigma_sleeper, log=T)
}
}else{
tot <- data[[block]]$total
ded <- data[[block]]$dead
nt <- data[[block]]$net
nnn <- length(tot)
for(j in 1:nnn){
#use dfa to index the random effects?
lprob <- a0 + a1*nt[j] + hut[dfa$blckH[block]] + sleeper[dfa$blckS[block]] # on logistic scale
#convert to probability scale
prb <- exp(lprob)/(1+exp(lprob))
ret <- ret + dbinom(ded[j], tot[j], prb, log = T)
}
}
return(ret)
}
date()
mcmc <- run_mcmc(data = lst,
df_params = df_params,
loglike = r_loglike,
logprior = r_logprior,
burnin = 2e3,
samples = 6e3,
chains = 3,
#cluster = cl,
silent = F)
date()
plot_par(mcmc, show = c('a0','a1','sigma_hut','sigma_sleeper'), phase = "sampling")
plot_credible(mcmc, show = c('a0','a1','sigma_hut','sigma_sleeper'))
#random effect for sleeper should be (more-or-less) descending (see line 19)
plot_credible(mcmc, show = paste0('sleeper',seq(1,4)))
#random effect for hut should be (more-or-less) asscending (see line 19)
plot_credible(mcmc, show = paste0('hut',seq(1,4)))
The text was updated successfully, but these errors were encountered:
#Simple GLMM. Based on mosquito death in a experimental hut trial
#Here random effects are crossed, rather than nested.
#But the overall method should apply more generally
#Can provide stan model comparison, if useful
library(ggplot2)
library(drjacoby)
#In this trial, we are evaluating two mosquito nets, one of which is an untreated (control) net
#There are four huts: each night a volunteer sleeps in each hut, under the net.
#The sleepers & the nets are moved around the different huts over the course of 32 nights
#Here's the trial structure. For 'net', 0=untreated control, 1=insecticide-treated net (ITN)
dfm <- data.frame('hut'=rep(c(1,2,3,4),32), 'sleeper' = c(rep(c(1,2,3,4),8), rep(c(4,1,2,3),8),
rep(c(3,4,1,2),8), rep(c(2,3,4,1),8)), 'net' = rep(c(0,0,1,1,1,1,0,0), 16) )
#How many mosquitoes enter each hut each night? Draw from a Poisson distribution
dfm$n <- rpois(128, lambda = 11)
dfm$dead <- NA
#To simulate how many mosquitoes die each night (binomial sampling), we include an effect for the ITN
#We also include a weaker effect, depending on the hut & sleeper
for(i in 1:128){
rho <- -1 + 0.1dfm$hut[i] - 0.2dfm$sleeper[i] + 1.5 * dfm$net[i]#prob on the logistic scale
#whack a bit o' noise on it
rho2 <- rnorm(1,mean = rho, sd = 0.1)
#convert to probability scale
prb <- exp(rho2)/(1+exp(rho2))
dfm$dead[i] <- rbinom(1, size = dfm$n[i], prob = prb)
}
#Now prepare what we need for drjacoby. There are 4 random effects for hut and 4 for sleeper.
#In total, there are 16 combinations of these
M <- 16 # no. of combinations of the two random effects? (4 values each)
df_params <- define_params(name = "hut1", min = -Inf, max = Inf, init = 0, block = c(1,2,3,4,M+1),
name = "hut2", min = -Inf, max = Inf, init = 0, block = c(5,6,7,8,M+1),
name = "hut3", min = -Inf, max = Inf, init = 0, block = c(9,10,11,12,M+1),
name = "hut4", min = -Inf, max = Inf, init = 0, block = c(13,14,15,16,M+1),
name = "sleeper1", min = -Inf, max = Inf, init = 0, block = c(1,5,9,13,M+1),
name = "sleeper2", min = -Inf, max = Inf, init = 0, block = c(2,6,10,14,M+1),
name = "sleeper3", min = -Inf, max = Inf, init = 0, block = c(3,7,11,15,M+1),
name = "sleeper4", min = -Inf, max = Inf, init = 0, block = c(4,8,12,16,M+1),
name = "sigma_hut", min = 0, max = Inf, init = 1, block = M+1,
name = "sigma_sleeper", min = 0, max = Inf, init = 1, block = M+1,
name = "a1", min = -Inf, max = Inf, init = 0, block = 1:M,
name = "a0", min = -Inf, max = Inf, init = 0, block = 1:M)
#Now we have to work out which data points need to go with each block
#empty list for the data
lst <- list()
#empty dataframe
dfa <- data.frame('blck'=rep(0,16), 'blckH'=rep(0,16), 'blckS'=rep(0,16))
count <- 1
for(j in 1:4){
for(k in 1:4){
aux <- dfm[dfm$hut == j & dfm$sleeper == k,]
#preare data for a block, store as a list
lst[[as.character(count)]] <- list(total = aux$n, dead = aux$dead, net = aux$net)
dfa$blck[count] <- count
dfa$blckH[count] <- j
dfa$blckS[count] <- k
count <- count + 1
}
}
#Look at dfa. For each block, which random effect do we need for hut (H) and sleeper (S)?
head(dfa)
#define log-likelihood function
r_loglike <- function(params, data, misc) {
#unpack parameters
#Patient-specific first
hut <- rep(0,4)
sleeper <- rep(0,4)
for (i in 1:4) {
hut[i] <- params[i]
sleeper[i] <- params[4 + i]
}
a1 <- params["a1"]
a0 <- params["a0"]
sigma_hut <- params["sigma_hut"]
sigma_sleeper <- params["sigma_sleeper"]
#get current update block
block = misc$block
#distinct method for first M blocks, vs (M+1)
ret = 0.0;
if (block == (M+1)) { # // likelihood for the global parameters
for(i in 1:4){
ret <- ret + dnorm(hut[i], mean=0, sd=sigma_hut, log=T) +
dnorm(sleeper[i], mean=0, sd=sigma_sleeper, log=T)
}
}else{
tot <- data[[block]]$total
ded <- data[[block]]$dead
nt <- data[[block]]$net
nnn <- length(tot)
for(j in 1:nnn){
#use dfa to index the random effects?
lprob <- a0 + a1*nt[j] + hut[dfa$blckH[block]] + sleeper[dfa$blckS[block]] # on logistic scale
#convert to probability scale
prb <- exp(lprob)/(1+exp(lprob))
ret <- ret + dbinom(ded[j], tot[j], prb, log = T)
}
}
return(ret)
}
#define log-prior function
r_logprior <- function(params, misc) {
sigma_hut = params["sigma_hut"]
sigma_sleeper = params["sigma_sleeper"]
a0 = params["a0"]
a1 = params["a1"]
l1 <- dnorm(x=a0, mean = 0, sd = 2.5, log = T)
l2 <- dnorm(x=a1, mean = 0, sd = 1, log = T)
l3 <- dexp(x = sigma_sleeper, rate = 1, log = T)
l4 <- dexp(x = sigma_hut, rate = 1, log = T)
ret <- l1 + l2 + l3 + l4
return(ret)
}
date()
mcmc <- run_mcmc(data = lst,
df_params = df_params,
loglike = r_loglike,
logprior = r_logprior,
burnin = 2e3,
samples = 6e3,
chains = 3,
#cluster = cl,
silent = F)
date()
plot_par(mcmc, show = c('a0','a1','sigma_hut','sigma_sleeper'), phase = "sampling")
plot_credible(mcmc, show = c('a0','a1','sigma_hut','sigma_sleeper'))
#random effect for sleeper should be (more-or-less) descending (see line 19)
plot_credible(mcmc, show = paste0('sleeper',seq(1,4)))
#random effect for hut should be (more-or-less) asscending (see line 19)
plot_credible(mcmc, show = paste0('hut',seq(1,4)))
The text was updated successfully, but these errors were encountered: