Aquí es un ejemplo de la implementación de un macro básico de sustitución del sistema de EXIGENCIAS de secuencias de comandos.
Explicación del sistema
- Definir una función que toma como argumentos opcionales de elementos de la secuencia de comandos.
- Para cualquiera de los aspectos de la secuencia de comandos que varían a través de los valores de los argumentos, grabar una macro token. Esto debe ser algo único texto. Empezando y terminando con algunos símbolos pueden ayudar a hacer esto sin ambigüedades.
- Para cada macro token de incluir el código de lo que la cadena de reemplazo debe ser bajo todas las combinaciones posibles de los argumentos de la función.
- Reemplace la macro fichas con la colocación adecuada de texto basado en argumentos.
- El código a continuación se proporciona un ejemplo de cómo las macros se pueden especificar y cómo aplicar las macros para el raw de secuencia de comandos (sugerencias para hacerlo más elegante son bienvenidos).
- La función devuelve un sustituye el modelo de cadena que puede, si es necesario pasarse a una
textConnection
función para su uso con rjags.
Me gusta este sistema para un par de razones:
- la cruda script es fácil de leer
- la secuencia de comandos resultante tiene sangría adecuada
- usted no tiene que preocuparse acerca de los errores relacionados con los comandos que aparecen en la misma línea
Ejemplo
Específicamente, en este ejemplo, tiene por objetivo permitir que el usuario ajuste a un tipo particular de multinivel no lineales del modelo. Está diseñado para permitir tres formas funcionales: una de dos parámetros de potencia, tres parámetros de potencia, y un de tres parámetro exponencial.
La macro estructuras de sección de macros como una lista de listas. El nivel superior de la lista contiene un elemento por cada macro token. Para cada macro token, no es la macro token de texto, y el condicional texto de reemplazo.
Finalmente, un bucle for se aplica a todos los macro reemplazos para el raw de secuencia de comandos.
Vea a continuación (el desplazamiento es necesario):
jags_model <- function (f=c('power2', 'power3', 'exp3')) {
f <- match.arg(f)
# raw script
script <-
"model {
# Model
for (i in 1:length(y)) {
$FUNCTION
y[i] ~ dnorm(mu[i], tau[subject[i]])
}
# Random coefficients
for (i in 1:N) {
theta1[i] ~ dnorm(theta1.mu, theta1.tau)T(0, 1000)
theta2[i] ~ dnorm(theta2.mu, theta2.tau)T(-10, 0)
$THETA3DISTRIBUTION
sigma[i] ~ dnorm(sigma.mu, sigma.tau)T(0, 100);
tau[i] <- 1/(sigma[i]^2)
}
theta1.mu ~ dunif(0, 100)
theta2.mu ~ dunif(-2, 0)
$THETA3PRIOR.MU
sigma.mu ~ dunif(0, 20)
theta1.sigma ~ dunif(0, 100)
theta2.sigma ~ dunif(0, 2)
$THETA3PRIOR.SIGMA
sigma.sigma ~ dunif(0, 10)
# Transformations
theta1.tau <- 1/(theta1.sigma^2)
theta2.tau <- 1/(theta2.sigma^2)
$THETA3.TAU
sigma.tau <- 1/(sigma.sigma^2)
}"
# define macros
macros <- list(list("$FUNCTION",
switch(f,
power2="mu[i] <- theta1[subject[i]] * pow(trial[i], theta2[subject[i]])",
power3="mu[i] <- theta1[subject[i]] * pow(trial[i], theta2[subject[i]]) + theta3[subject[i]];",
exp3="mu[i] <- theta1[subject[i]] * exp(theta2[subject[i]] * (trial[i] - 1)) + theta3[subject[i]];") ),
list("$THETA3DISTRIBUTION",
switch(f,
power3=, exp3= "theta3[i] ~ dnorm(theta3.mu, theta3.tau)T(0, 1000)",
power2="") ),
list("$THETA3PRIOR.MU",
switch(f,
power3=, exp3= "theta3.mu ~ dunif(0, 100)",
power2="") ),
list("$THETA3PRIOR.SIGMA",
switch(f,
power3=, exp3= "theta3.sigma ~ dunif(0, 100)",
power2="") ),
list("$THETA3.TAU",
switch(f,
power3=, exp3= "theta3.tau <- 1/(theta3.sigma^2)",
power2="") )
)
# apply macros
for (m in seq(macros)) {
script <- gsub(macros[[m]][1], macros[[m]][2], script, fixed=TRUE)
}
script
}
Demostración
Por lo tanto, podemos producir el procesado ENTRECORTADO modelo con
x <- jags_model(f='power3')
Y si queremos ver el modelo resultante, que podemos hacer
cat(x)
que se traduce en
model {
# Model
for (i in 1:length(y)) {
mu[i] <- theta1[subject[i]] * pow(trial[i], theta2[subject[i]]) + theta3[subject[i]];
y[i] ~ dnorm(mu[i], tau[subject[i]])
}
# Random coefficients
for (i in 1:N) {
theta1[i] ~ dnorm(theta1.mu, theta1.tau)T(0, 1000)
theta2[i] ~ dnorm(theta2.mu, theta2.tau)T(-10, 0)
theta3[i] ~ dnorm(theta3.mu, theta3.tau)T(0, 1000)
sigma[i] ~ dnorm(sigma.mu, sigma.tau)T(0, 100);
tau[i] <- 1/(sigma[i]^2)
}
theta1.mu ~ dunif(0, 100)
theta2.mu ~ dunif(-2, 0)
theta3.mu ~ dunif(0, 100)
sigma.mu ~ dunif(0, 20)
theta1.sigma ~ dunif(0, 100)
theta2.sigma ~ dunif(0, 2)
theta3.sigma ~ dunif(0, 100)
sigma.sigma ~ dunif(0, 10)
# Transformations
theta1.tau <- 1/(theta1.sigma^2)
theta2.tau <- 1/(theta2.sigma^2)
theta3.tau <- 1/(theta3.sigma^2)
sigma.tau <- 1/(sigma.sigma^2)
}