I'm a beginner with OpenBUGS which I use through the R2OpenBUGS R package. I try to set state space model for identifying a lognormal signal in very noisy data. After many trials and errors, I managed to get this code but I still get the following error message: "empty slot not allowed in variable name error pos 664" which I don't understand. Can anyone knows what is wrong with the code ?
Disclaimer:
alt = measured altitude
true_alt = what I try to assess
nbird = number of individuals
nobs = number of observations (this number is not the same for every bird)
nstate = 'flight state', which is the way the birds behave (nstate = 3 because there are 3 different behaviours)
I try to determine the lognormal distribution of true_alt for each state.
model <- function(){
## MODEL SPECIFICATION
for(j in 1:nbird){
for(i in 1:nobs[j]){
alt[i,j] ~ dnorm(true_alt[i,j], tau.obs)
log(true_alt[i,j]) <- log_true_alt[i,j]
log_true_alt[i,j] ~ dnorm(mean.alt[i,j], tau[state[i,j]])
mean.alt[i,j] <- alt1[state[i,j]] + ind.re[j]
}
}
for(i in 1:nstate){ tau[i] <- 1/(sig[i]) }
# Random Effects:
tau.re <- 1/sig.re
for(j in 1:nbird) { ind.re[j] ~ dnorm(0, tau.re) }
## PRIORS
for(i in 1:nstate) {
alt1[i] ~ dnorm(0, 0.01)
sig[i] ~ dunif(0, 200)
}
sig.re ~ dunif(0, 200)
state ~ dunif(1,3)
## POSTERIOR PREDICTIVE DISTRIBUTIONS FOR EACH STATE
for(s in 1:nstate){
log_alt_pred[s] ~ dnorm(alt1[s], tau[s])
log(alt_pred[s]) <- log_alt_pred[s]
}
}
Thank you!!!
It could be because in your priors you're trying to set a distribution for "alt1[i]" but in your model you've used "alt[i,j]".
Related
I have fitted following simple linear regression Bayesian model using rjags.
I was able to run the model by specifying all the predictors separately(like for a lm object). Now I want to learn how to specify the predictors by introducing them as a matrix instead of specifying them separately.
So I ran the following code, but it gave some errors.
I used tobbaco data set in rrr package to provide a reproducible example.
library(rrr)
require(dplyr)
library(rjags)
tobacco <- as_data_frame(tobacco)
N1 = length(tobacco$Y1.BurnRate)
x1 = model.matrix(Y1.BurnRate~X2.PercentChlorine+X3.PercentPotassium ,data = tobacco)
bayes_model_mul1=
"model {
for(i in 1:N1){
Y1.BurnRate[i]~dnorm(mu1[i],tau1)
for(j in 1:3){
mu1[i]=beta1[j]*x1[i,j]
}
}
for (l in 1:3) { beta1[l] ~dnorm(0, 0.001) }
tau1 ~ dgamma(.01,.01)
sigma_tau1 = 1/tau1
}"
model3 <- jags.model(textConnection(bayes_model_mul1),
data = list(Y1.BurnRate=tobacco$Y1.BurnRate, x1=x1, N1=N1),
n.chains=1)
After I run model3 , I got following error.
Error in jags.model(textConnection(bayes_model_mul1), data = list(Y1.BurnRate = tobacco$Y1.BurnRate, :
RUNTIME ERROR:
Compilation error on line 6.
Attempt to redefine node mu1[1]
Can anyone help me figure this out ?
Does this due to introducing predictors as a matrix ?
There are a few ways to do this, here are two:
Use matrix multiplication outside of the likelihood loop
m1 =
"model {
mu1 = x1 %*% beta1 # ---> this
for(i in 1:N1){
Y1.BurnRate[i] ~ dnorm(mu1[i], tau1)
}
for (l in 1:3) { beta1[l] ~ dnorm(0, 0.001) }
tau1 ~ dgamma(.01,.01)
sigma_tau1 = 1/tau1
}"
Use inprod to multiply the parameters with the design matrix
m2 =
"model {
for(i in 1:N1){
mu1[i] = inprod(beta1, x1[i,]) #----> this
Y1.BurnRate[i] ~ dnorm(mu1[i], tau1)
}
for (l in 1:3) { beta1[l] ~ dnorm(0, 0.001) }
tau1 ~ dgamma(.01,.01)
sigma_tau1 = 1/tau1
}"
You received an error with for(j in 1:3){ mu1[i] = beta1[j]* x1[i,j] } as every time you loop though the parameter index j you overwrite mu1[i]. It also doesn't sum up the individual terms. You may be able to index mu1 with j as well and then sum but untested ...
I am looking to run a hierarchical poisson model to hockey goal tending data. here is the model as set up in bugs:
modelString <- "model {
for(i in 1:n_obs){
hockey_goals[i] ~ dpois(p[i])
log(p[i]) <- p_inter + p_age * age[i] + p_sv_pct * sv_pct[i] + p_team * team[i] + p_win_pct * win_pct[i] + log(n_mins[i])
}
p_inter ~ dnorm(0,0.00001)
p_age ~ dnorm(0, 0.00001)
p_sv_pct ~ dnorm(0, 0.00001)
p_team ~ dnorm(0, 0.00001)
p_win_pct ~ dnorm(0, 0.00001)
}"
I then compile and load the data:
season_goals <- data$GA
n_mins <- data$MIN
age <- data$Age
sv_pct <- data$SV.
team <- data$Tm
win_pct <- data$W/data$GP
data <- list(n_obs=length(season_goals),n_mins=n_mins,hockey_goals=season_goals,age=age,
sv_pct=sv_pct,team=team,win_pct=win_pct)
# Get the data into BUGS:
modelData( bugsData( data ) )
#------------------------------------------------------------------------------
# INTIALIZE THE CHAINS.
nchain = 1
modelCompile( numChains=nchain )
modelGenInits()
#------------------------------------------------------------------------------
# RUN THE CHAINS.
samplesSet( c("p_age","p_sv_pct","p_team","p_win_pct") )
# R command defines a new variable that specifies an arbitrary chain length:
chainLength = 10000
# BRugs tells BUGS to generate a MCMC chain:
modelUpdate( chainLength )
At this point I get an error:
Error in handleRes(res) : NA
Any ideas on where I went wrong...?
I wish I could just comment but I don't have enough reputation. Anyway, I made up some data and ran a simplified version of your model (i.e. with only age and minutes played). I ran it in the GUI version of OpenBUGS and it didn't work. I then changed the priors on you coefficients to dnorm(0,0.01) and it updated.
So I would suggest changing the priors. The ones you have are very, very vague. Changing them as suggested will not effect your inference and you may get the model to run.
I am puzzled by a simple question in R JAGS. I have for example, 10 parameters: d[1], d[2], ..., d[10]. It is intuitive from the data that they should be increasing. So I want to put a constraint on them.
Here is what I tried to do but it give error messages saying "Node inconsistent with parents":
model{
...
for (j in 1:10){
d.star[j]~dnorm(0,0.0001)
}
d=sort(d.star)
}
Then I tried this:
d[1]~dnorm(0,0.0001)
for (j in 2:10){
d[j]~dnorm(0,0.0001)I(d[j-1],)
}
This worked, but I don't know if this is the correct way to do it. Could you share your thoughts?
Thanks!
If you are ever uncertain about something like this, it is best to just simulate some data to determine if the model structure you suggest works (spoiler alert: it does).
Here is the model that I used:
cat('model{
d[1] ~ dnorm(0, 0.0001) # intercept
d[2] ~ dnorm(0, 0.0001)
for(j in 3:11){
d[j] ~ dnorm(0, 0.0001) I(d[j-1],)
}
for(i in 1:200){
y[i] ~ dnorm(mu[i], tau)
mu[i] <- inprod(d, x[i,])
}
tau ~ dgamma(0.01,0.01)
}',
file = "model_example.R")```
And here are the data I simulated to use with this model.
library(run.jags)
library(mcmcplots)
# intercept with sorted betas
set.seed(161)
betas <- c(1,sort(runif(10, -5,5)))
# make covariates, 1 for intercept
x <- cbind(1,matrix(rnorm(2000), nrow = 200, ncol = 10))
# deterministic part of model
y_det <- x %*% betas
# add noise
y <- rnorm(length(y_det), y_det, 1)
data_list <- list(y = as.numeric(y), x = x)
# fit the model
mout <- run.jags('model_example.R',monitor = c("d", "tau"), data = data_list)
Following this, we can plot out the estimates and overlay the true parameter values
caterplot(mout, "d", reorder = FALSE)
points(rev(c(1:11)) ~ betas, pch = 18,cex = 0.9)
The black points are the true parameter values, the blue points and lines are the estimates. Looks like this set up does fine so long as there are enough data to estimate all of those parameters.
It looks like there is an syntax error in the first implementation. Just try:
model{
...
for (j in 1:10){
d.star[j]~dnorm(0,0.0001)
}
d[1:10] <- sort(d.star) # notice d is indexed.
}
and compare the results with those of the second implementation. According to the documentation, these are both correct, but it is advised to use the function sort.
I'm using rjags to calculate a species abundance using an N-mixture model and count data. To capture over dispersion of my data, I used hyperpriors. But I get an
"Error in node S[1,1,2] Invalid parent values"
My guess is that I have a problem in the dimension of my prior OR one of the prior is negative, null or NA which stops the calculation of node S.
Any idea how to stop this problem ? Is it possible to initialize S?
model {
## PRIORS ##
lambda[1] ~ dunif(0, 500)
lambda[2] ~ dunif(0, 500)
p[1] ~ dunif(0, 1)
p[2] ~ dunif(0, 1)
# surdispersion
muepsomega1 ~ dnorm(0,0.0001)
sigepsomega1 ~ dunif(0,100)
iomega1 ~ dnorm(0,0.0001)
tauepsomega1 <- 1/(sigepsomega1*sigepsomega1)
omega2 ~ dunif(0, 1)
## LIKELIHOOD ##
# Create a loop across all j sites
for(j in 1:nSites) {
# surdispersion sur omega 1
omega1[j] <- iomega1 + epsomega1[j]
epsomega1[j] ~ dnorm(muepsomega1,tauepsomega1)
N[1,j,1] ~ dpois(lambda[1])
N[2,j,1] ~ dpois(lambda[2])
for (i in 1:3) {
S[i,j,1] ~ dnegbin(2, 1)
} # end loop i
for(t in 2:nYears) {
# Estimate survivorship (between year survival)
S[1,j,t] ~ dnegbin(omega1[j], N[1,j,t-1])
S[2,j,t] ~ dnegbin(omega2, N[2,j,t-1])
N[1,j,t] <- S[1,j,t]
N[2,j,t] <- S[2,j,t]
} # end loop t in 2:years
# Loop across sampling replicates to estimate detection
for (t in 1:nYears){
for(k in 1:nReps){
n[1,j,k,t] ~ dnegbin(p[1], N[1,j,t])
n[2,j,k,t] ~ dnegbin(p[2], N[2,j,t])
} # end loop k nreps
} # end loop j sites
}
This is how I call the model:
#Model file
modFile = "model/2016-07-12/model_Nmix.R"
inits <- function(){
list('lambda' =c(1,1), 'p'= c(1,1),'omega2' = 1,'iomega1'=1, 'muepsomega1'= 1, 'sigepsomega1'= 1, 'epsomega1'=c(1,1,1,1,1,1,1)) } # size epsomega1 is length(nSites)=7
# Compile the model
require(rjags)
abundance.out <- jags.model(file=modFile, data=data,n.chains = 3, n.adapt = 3000)
Let epsomega1 and iomega1 come from distributions that don't have any probability density over negative values. Gamma, uniform, log-normal, or truncated normal distributions are candidates, and your choice should depend on what you think the most correct model specification actually is.
I am a student studying bayesian statistics and have just begun to use JAGS using a intro script written by my lecturer, with us (the students) having to only enter the data and the number of iterations. The following is the script with my data added into it:
setwd("C:\\Users\\JohnSmith\\Downloads")
rawdata = read.table("bwt.txt",header=TRUE)
Birthweight = rawdata$Birthweight
Age = rawdata$Age
model = "model
{
beta0 ~ dnorm(0, 1/1000^2)
beta1 ~ dnorm(0, 1/1000^2)
log_sigma ~ dunif(-10, 10)
sigma <- exp(log_sigma)
for(i in 1:N)
{
mu[i] <- beta0 + beta1 * Age[i]
Birthweight[i] ~ dnorm(mu[i], 1/sigma^2)
}
}
"
data = list(x=Birthweight, y=Age, N=24)
# Variables to monitor
variable_names = c('beta0','beta1')
# How many burn-in steps?
burn_in = 1000
# How many proper steps?
steps = 100000
# Thinning?
thin = 10
# Random number seed
seed = 2693795
# NO NEED TO EDIT PAST HERE!!!
# Just run it all and use the results list.
library('rjags')
# Write model out to file
fileConn=file("model.temp")
writeLines(model, fileConn)
close(fileConn)
if(all(is.na(data)))
{
m = jags.model(file="model.temp", inits=list(.RNG.seed=seed, .RNG.name="base::Mersenne-Twister"))
} else
{
m = jags.model(file="model.temp", data=data, inits=list(.RNG.seed=seed, .RNG.name="base::Mersenne-Twister"))
}
update(m, burn_in)
draw = jags.samples(m, steps, thin=thin, variable.names = variable_names)
# Convert to a list
make_list <- function(draw)
{
results = list()
for(name in names(draw))
{
# Extract "chain 1"
results[[name]] = as.array(draw[[name]][,,1])
# Transpose 2D arrays
if(length(dim(results[[name]])) == 2)
results[[name]] = t(results[[name]])
}
return(results)
}
results = make_list(draw)
However, when I run the following code I get the following error message:
Error in jags.model(file = "model.temp", data = data, inits = list(.RNG.seed = seed, :
RUNTIME ERROR:
Compilation error on line 11.
Unknown parameter Age
In addition: Warning messages:
1: In jags.model(file = "model.temp", data = data, inits = list(.RNG.seed = seed, :
Unused variable "x" in data
2: In jags.model(file = "model.temp", data = data, inits = list(.RNG.seed = seed, :
Unused variable "y" in data
But as far as I can see, line 11 is blank, which leaves me stumped as to where the error is coming from. If anyone can give me some tips as to solve this, it will be greatly appreciated.
The names of the elements of your list of data (data) should match the names of the variables in your model.
You have:
data = list(x=Birthweight, y=Age, N=24)
so JAGS is looking for variables called x and y in your model. However, in your model, you have:
mu[i] <- beta0 + beta1 * Age[i]
Birthweight[i] ~ dnorm(mu[i], 1/sigma^2)
That is, your variables are called Age and Birthweight.
So, either change your list to:
data <- list(Birthweight=Birthweight, Age=Age, N=24)
or change your model to:
mu[i] <- beta0 + beta1 * y[i]
x[i] ~ dnorm(mu[i], 1/sigma^2)
Had you done readLines('model.temp') (or opened model.temp in a text editor), you would have seen that line 11 of that file refers to the line that contains mu[i] <- beta0 + beta1 * Age[i], which is the first error that JAGS encountered due to the reference to Age, for which neither data nor a prior was provided.