使用runjags、parallel库时动态调整每次模拟观测数的方案咨询
解决方案
不需要每次重写tempModel.txt,最优方案是将样本量N作为数据变量传入JAGS模型,JAGS本身支持循环上限使用传入的动态变量,改动很小:
步骤1:修改模型字符串,将硬编码的1000替换为变量N
把原来模型里的for (i in 1:1000)改成for (i in 1:N)即可,修改后的模型字符串如下:
modelString <- " model{ #Model specification for (i in 1:N) { # 这里把硬编码1000换成变量N y[i]~dnorm(muy[i], Inv_sig2_e) muy[i]<-b0+b1*x1[i]+b2*x2[i] } #priors b0~dnorm(0, 1.0E-6) b1~dnorm(0, 1.0E-6) b2~dnorm(0, 1.0E-6) Inv_sig2_e~dgamma(1.0E-3, 1.0E-3) #parameter transformation Sig2_e<-1/Inv_sig2_e } " # 这行只需要执行一次即可,不用每次循环重写 writeLines(modelString, "tempModel.txt")
步骤2:在lapply循环中给每个子集追加N值到传入数据里
每次处理子集x的时候,把当前子集的行数作为N加入model_data,JAGS会自动识别模型里的N变量,匹配传入的数据:
output_models <- lapply(subsetdata, function(x){ # 给数据追加当前子集的样本量N model_data = c(x, list(N = nrow(x))) initsList1 <- list(b0=1, b1=1, b2=1, Inv_sig2_e=1) initsList2 <- list(b0=1, b1=2, b2=3, Inv_sig2_e=1) initsList3 <- list(b0=2, b1=3, b2=4, Inv_sig2_e=1) runJagsOut <- run.jags(method = "parallel", model = "tempModel.txt", monitor = c( "b0","b1","b2","Sig2_e"), data = model_data, inits = list(initsList1, initsList2, initsList3), n.chains = 3, adapt = 500, burnin = 2500, sample = 2500, thin = 1, summarise = FALSE, plots = FALSE) return(runJagsOut) })
补充说明
如果有特殊场景必须修改模型本身的内容,也可以用paste0或者glue包动态生成模型字符串,每次循环重写临时txt文件,但上面的传参方案效率更高、代码更简洁,是更推荐的做法。
内容的提问来源于stack exchange,提问作者thewan
相关产品推荐
相关产品推荐

