# NOT RUN {
library(rethinking)
data(chimpanzees)
# don't want any variables with NAs
# also recode condition to an index {1,0} -> {1,2}
d <- list(
pulled_left = chimpanzees$pulled_left ,
prosoc_left = chimpanzees$prosoc_left ,
condition = as.integer( 2 - chimpanzees$condition ) ,
actor = as.integer( chimpanzees$actor ) ,
blockid = as.integer( chimpanzees$block )
)
# simple logistic regression
m1 <- ulam(
alist(
pulled_left ~ bernoulli(theta),
logit(theta) <- a + bp[condition]*prosoc_left ,
a ~ normal(0,4),
bp[condition] ~ normal(0,1)
) ,
data=d, chains=2, cores=1 , sample=TRUE )
precis(m1,depth=2)
plot(m1,depth=2)
pairs(m1)
# same model, but save theta so it is return in samples
# note 'save>' in second line of formula
m1b <- ulam(
alist(
pulled_left ~ bernoulli(theta),
save> logit(theta) <- a + bp[condition]*prosoc_left ,
a ~ normal(0,4),
bp[condition] ~ normal(0,1)
) ,
data=d, chains=2, cores=1 , sample=TRUE )
# same model, but use gq to compute contrast between conditions
# note that order does matter. bp_diff should come before bp[] is defined
m1c <- ulam(
alist(
pulled_left ~ bernoulli(theta),
logit(theta) <- a + bp[condition]*prosoc_left ,
gq> bp_diff <- bp[1] - bp[2],
a ~ normal(0,4),
bp[condition] ~ normal(0,1)
) ,
data=d, chains=2, cores=1 , sample=TRUE )
# can also transform data inside model, using transdata> tag.
# this is more efficient, because it only evaluates once, not during sampling.
# for example, this constructs prosoc_right variable:
m1d <- ulam(
alist(
pulled_left ~ bernoulli(theta),
logit(theta) <- a + bp[condition]*prosoc_right ,
transdata> prosoc_right <- 1 - prosoc_left,
a ~ normal(0,4),
bp[condition] ~ normal(0,1)
) ,
data=d, chains=2, cores=1 , sample=TRUE )
# now model with varying intercepts on actor
m2 <- ulam(
alist(
pulled_left ~ bernoulli(theta),
logit(theta) <- a + aj[actor] + bp[condition]*prosoc_left,
aj[actor] ~ normal( 0 , sigma_actor ),
a ~ normal(0,4),
bp[condition] ~ normal(0,1),
sigma_actor ~ exponential(1)
) ,
data=d, chains=2 , cores=1 , sample=TRUE )
precis(m2)
plot(m2)
# varying intercepts on actor and experimental block
m3 <- ulam(
alist(
pulled_left ~ bernoulli(theta),
logit(theta) <- a + aj[actor] + ak[blockid] + bp[condition]*prosoc_left,
aj[actor] ~ normal( 0 , sigma_actor ),
ak[blockid] ~ normal( 0 , sigma_block ),
a ~ dnorm(0,4),
bp[condition] ~ dnorm(0,1),
sigma_actor ~ exponential(1),
sigma_block ~ exponential(1)
) ,
data=d, chains=2 , cores=1 , sample=TRUE )
precis(m3)
summary(m3)
plot(m3)
###########
# varying slopes models
# varying slopes on actor
# also demonstrates use of multiple linear models
# see Chapter 13 for discussion
m3 <- ulam(
alist(
# likeliood
pulled_left ~ bernoulli(theta),
# linear models
logit(theta) <- A + BP*prosoc_left,
A <- a + v[actor,1],
BP <- bp + v[actor,condition+1],
# adaptive prior
vector[3]: v[actor] ~ multi_normal( 0 , Rho_actor , sigma_actor ),
# fixed priors
c(a,bp) ~ normal(0,1),
sigma_actor ~ exponential(1),
Rho_actor ~ lkjcorr(4)
) , data=d , chains=3 , cores=1 , sample=TRUE )
# same model but with non-centered parameterization
# see Chapter 13 for explanation and more elaborate example
m4 <- ulam(
alist(
# likeliood
pulled_left ~ bernoulli(theta),
# linear models
logit(theta) <- A + BP*prosoc_left,
A <- a + v[actor,1],
BP <- bp + v[actor,condition+1],
# adaptive prior
matrix[actor,3]: v <- compose_noncentered( sigma_actor , L_Rho_actor , z ),
matrix[3,actor]: z ~ normal( 0 , 1 ),
# fixed priors
c(a,bp) ~ normal(0,1),
vector[3]: sigma_actor ~ exponential(1),
cholesky_factor_corr[3]: L_Rho_actor ~ lkj_corr_cholesky( 4 )
) , data=d , chains=3 , cores=1 , sample=TRUE )
# same as m5, but without hiding the construction of v
m5 <- ulam(
alist(
# likeliood
pulled_left ~ bernoulli(theta),
# linear models
logit(theta) <- A + BP*prosoc_left,
A <- a + v[actor,1],
BP <- bp + v[actor,condition+1],
# adaptive prior
matrix[actor,3]: v <- t(diag_pre_multiply( sigma_actor , L_Rho_actor ) * z),
matrix[3,actor]: z ~ normal( 0 , 1 ),
# fixed priors
c(a,bp,bpc) ~ normal(0,1),
vector[3]: sigma_actor ~ exponential(1),
cholesky_factor_corr[3]: L_Rho_actor ~ lkj_corr_cholesky( 4 )
) , data=d , chains=3 , cores=1 , sample=TRUE )
# }
Run the code above in your browser using DataLab