require(rstan)
Ntot <- 50 #Sample size
dom <- c(1,1,1,2,2) #Outcome domains indicators
Nvar <- length(dom)
x <- rnorm(Ntot, 0, 1)
y <- sapply(1:Nvar, function(i) x + rnorm(Ntot, 0, dom[i]))
y[,3] <- y[,1] + y[,2] #Create highly correlated variables
zx <- scale(x)
zy <- apply(y, 2, scale)
Ndom <- length(unique(dom))
dataList <- list(x=zx[,1], y=t(zy), Nvar=Nvar, Ntot=Ntot, id=1:Ntot, dom=dom, Ndom = Ndom)
mstr<- '
data {
int Ntot;
int Nvar;
int Ndom;
int dom[Nvar];
int id[Ntot];
vector[Ntot] x;
matrix[Nvar, Ntot] y;
}
parameters {
real<lower=0,upper=10> sd[Nvar]; //SD per y variable
real b1; //Overarching beta
vector[Nvar] e1b; //MTrick for Ind Outcome betas
real<lower=0> b1sd;
vector[Ndom] e1d; //MTrick for Domain betas
real<lower=0> b1dsd;
vector[Ntot] e0bs; //MTrick for participant random intercepts
real<lower=0,upper=10> sd0s;
matrix[Ndom, Ntot] e0bds; //MTrick for participant:Domain random intercepts
real<lower=0,upper=10> sd0d[Ndom];
}
transformed parameters{
vector[Nvar] B1O; //Output for each individual beta
vector[Nvar] b1o; //Outcome betas
vector[Ndom] b1d; //Domain betas
vector[Ntot] b0s; //Participant intercepts
matrix[Ndom, Ntot] b0ds; //Participant:Domain intercepts
matrix[Nvar, Ntot] mu;
b1o <- e1b * b1sd;
b1d <- e1d * b1dsd;
b0s <- e0bs * sd0s;
for(d in 1:Ndom){
b0ds[d] <- e0bds[d] * sd0d[d];
}
for(np in 1:Nvar){
for(i in 1:Ntot){
mu[np, i] <- b0s[id[i]] + b0ds[dom[np], id[i]] + (b1 + b1d[dom[np]] + b1o[np]) * x[i];
}
}
//Output
for(np in 1:Nvar){
B1O[np] <- b1 + b1d[dom[np]] + b1o[np];
}
}
model {
b1 ~ normal(0, 10);
e1b ~ normal(0, 1);
e1d ~ normal(0, 1);
e0bs ~ normal(0, 1);
for(d in 1:Ndom){
e0bds[d] ~ normal(0, 1);
}
b1sd ~ cauchy(0, 10);
b1dsd ~ cauchy(0, 10);
// Likelihood
for(np in 1:Nvar){
y[np] ~ normal(mu[np], sd[np]);
}
}
'
seed = 69
f1 <- stan(model_code = mstr, data = dataList, chains = 4, iter=100,
seed = seed, chain_id = 1,# nondiag_mass = T,# delta = 0.9,
pars = c("b1", "b1o", "b1d", "sd", "b1sd", "b1dsd", "sd0d", "B1O"))
f2 <- stan(fit=f1, data = dataList, chains = 4, iter=2500,
seed = seed, chain_id = 1, #nondiag_mass = T, delta = 0.9,
pars = c("b1", "b1o", "b1d", "sd", "b1sd", "b1dsd", "sd0d", "B1O"))