Hi Zoe,
OK, I'm taking a more thorough look and running your code. It looks like there's something of a misconception about the model language. The BUGS language is unusual in that it is declarative, not imperative as most languages are. Each line of code in BUGS creates one or more node relationships in a graphical model. Once a node has been declared, the same node can't be declared again. The order of code does not matter, because the lines declare nodes and relationships rather than steps to follow in order (as most code does).
This means that the following won't work:
for (i in 1:n_middle) {
idx <- middle[i]
R[idx] ~ dbinom(size=1, prob=frac)
}
Once idx is declared once, it has its graphical relationship established and can't be declared again in another iteration of the for loop. This is not a for loop for steps to be taken in order repeatedly as in imperative programming, but rather a for loop to declare multiple nodes. You would want instead:
for (i in 1:n_middle) {
R[middle[i] ] ~ dbinom(size=1, prob=frac)
}
where the vector middle should not have any repeated values.
Another example that will not work is this:
for (i in 1:n_rest) {
indicator[1:4] <- c(R[FID[rowx,1]],R[FID[rowx,2]],R[FID[rowx,3]],R[FID[rowx,4]])
out[1:4] <- imputation(geno=x_raw[],FID=FID[,],indicator=indicator[1:4],rowx=rowx,colx=colx,maf=maf)
idx <- rest[i]
x[idx] <- out[1]
x[idx] ~ dcat(prob=out[2:4])
}
I think you could for example do what you want like this:
for (i in 1:n_rest) {
indicator[i, 1:4] <- c(R[FID[row_idx[i],1]],R[FID[row_idx[i],2]],R[FID[rowx,3]],R[FID[row_idx[i],4]])
out[i, 1:4] <- imputation(geno=x_raw[],FID=FID[,],indicator=indicator[i, 1:4],rowx=row_idx[i],colx=col_idx[i],maf=maf)
x[rest[i]] <- out[1]
x[rest[i]] ~ dcat(prob=out[2:4])
}
I've removed some of the nodes you were trying to re-declare, and for others I've added an i index to make each one unique.
However I might not be following the intent of your model entirely, so I can't be sure I've captured it.
And a last example is that you can't do this:
yf[1:4] <- c(y[members[1]],y[members[2]],y[members[3]],y[members[4]])
yf ~ dmnorm(mu[1:4],cov=Xi[1:4,1:4])
because you can't declare the same node as deterministic and stochastic (and it should be "y[1:4]" if the second line is wanted). Often when people have a need to do that, it arises from flawed probability logic. Sometimes it really is what one wants, and then there are tricks to make it happen. However, I am thinking that you will benefit from finding some more introductory material on the BUGS language, either examples from our web site and user manual and/or material from BUGS and JAGS. Once you are more oriented with how to use the language, I would be happy to help with this trick if you need it.
Also there were a few issues with your imputation nimbleFunction (but see below). I tried compiling it separately:
Cimputation <- compileNimble(imputation)
This revealed that the argument to rcat should be "prob", not "probs", that p and out need to be created before assigning into them using indexing (this is true in R as well, and it is helpful to try using a nimbleFunction uncompiled, which will use R execution), and that you are using a j that is not defined anywhere. For p and out, you can create them by:
p <- numeric(length = 3)
out <- numeric(length = 4)
For out you could also do
out <- c(x,p)
instead of
out[1:4] <- c(x,p)
because when creating a whole object, it can be created by assignment.
A final and potentially vital comment is that you may encounter strange behavior having deterministic nodes (e.g. out[i, 1:4], where I've inserted i so you have unique nodes) assigned from a function that makes random draws (your imputation function). If you aren't sure you know what you're doing in nimble, that could break nimble's MCMC system because the MCMC system caches values of intermediate calculations. If those calculations are stochastic, what is cached may change, and the logic of the MCMC might break. I would have to grasp more of what you are trying to do to be sure, but my guess is it won't work correctly. However, what we usually see when people want to impute missing values is they let those be handled by nimble's MCMC engine. The stochastic declarations are included in the model code, and if the data is provided as NA, it is treated as missing and the node is sampled by MCMC. If you need a different kind of imputation to happen, it might be helpful to dig deeper into how things are working in nimble, and we're happy to answer questions if we can.
-Perry