有没有办法在 JAGS 中获取和存储矩阵元素的位置?
Is there a way to obtain and store positions of matrix element in JAGS?
我正在用 JAGS 中的 BUGS 代码在 R 中开发贝叶斯层次模型。
在我的模型中,我有两个矩阵,它们在完全相同的矩阵位置包含彼此的相关信息。我的信息按行构建。我按行对第一个矩阵 Distmat 应用数学运算:
diffmat[i,j] <- abs(Distmat[birthterr[i],j] - Dist[i])
我有兴趣在新向量中记录diffmat每一行中每个最小值的列位置,然后将此向量应用于第二个矩阵。这在使用函数“which”或“which.min”的常规 R 代码中相对容易:
a <- numeric()
for (i in 1:dim(diffmat)[1])
for (j in 1:dim(diffmat)[2])
a[i] <- which.min(diffmat[i,])
然后将向量“a”应用于第二个矩阵 (terrmat) 以获得与 Distmat 位置关联的值:
b <- numeric(0)
for (i in 1:dim(diffmat)[1])
for (j in 1:dim(diffmat)[2])
b[i] <- terrmat[i, a[i]]
但是,显然 BUGS 代码无法识别 which.min() 或 which.min(),我正在努力寻找一种方法将这些矩阵行位置存储在向量中。也许有一个非常简单的解决方案,但我真的被困在那里了。希望我的信息足够清楚。
如有任何建议,我们将不胜感激。感谢您的宝贵时间!
这是一个最小的工作示例。这里的类比是 x
就是你的 diffmat
。我在这里随机绘制它,但如果您以其他方式定义它,它应该仍然有效。本质上,您在每一行中对 x
的值进行排序,并创建一个新矩阵 e
,如果 x[i,j]
排名为 1,则该矩阵为编码为 1 的虚拟矩阵,否则为 0。然后,假设 terrmat
和 diffmat
具有相同的维度,然后取它的内积和来自 1:ncol(terrmat)
的值向量。然后,这将为您提供观察值排名第一的列索引 i
。下面示例中的 ymat
就是您的 terrmat
所在的位置。我认为它在任何实际大小的问题上都会很慢,但从下面的输出来看它似乎有效。
dl <- list(
ymat = matrix(1:3, ncol=3, nrow=5, byrow=TRUE),
yinds = 1:3
)
mods <- "model{
for(i in 1:5){
for(j in 1:3){
x[i,j] ~ dnorm(0,1)
e[i,j] <- equals(rx[i,j], 1)
}
rx[i,1:3] <- rank(x[i,1:3])
ind[i] <- inprod(e[i,], yinds)
yval[i] <- ymat[i,ind[i]]
}
}"
library(runjags)
out <- run.jags(mods, data=dl, monitor="yval")
out
#
# JAGS model summary statistics from 20000 samples (chains = 2; adapt+burnin = 5000):
#
# Lower95 Median Upper95 Mean SD Mode MCerr MC%ofSD SSeff AC.10 psrf
# yval[1] 1 2 3 1.9973 0.8139 2 0.0058421 0.7 19409 -0.0077146 0.99996
# yval[2] 1 2 3 2.0067 0.81605 3 0.0057704 0.7 20000 0.00049096 1.0003
# yval[3] 1 2 3 1.9895 0.8142 2 0.0057573 0.7 20000 0.00066309 1
# yval[4] 1 2 3 1.9973 0.81638 1 0.0057727 0.7 20000 -0.00040016 0.99998
# yval[5] 1 2 3 1.993 0.81611 1 0.0057708 0.7 20000 -0.0027988 0.99996
#
# Total time taken: 0.7 seconds
我正在用 JAGS 中的 BUGS 代码在 R 中开发贝叶斯层次模型。
在我的模型中,我有两个矩阵,它们在完全相同的矩阵位置包含彼此的相关信息。我的信息按行构建。我按行对第一个矩阵 Distmat 应用数学运算:
diffmat[i,j] <- abs(Distmat[birthterr[i],j] - Dist[i])
我有兴趣在新向量中记录diffmat每一行中每个最小值的列位置,然后将此向量应用于第二个矩阵。这在使用函数“which”或“which.min”的常规 R 代码中相对容易:
a <- numeric()
for (i in 1:dim(diffmat)[1])
for (j in 1:dim(diffmat)[2])
a[i] <- which.min(diffmat[i,])
然后将向量“a”应用于第二个矩阵 (terrmat) 以获得与 Distmat 位置关联的值:
b <- numeric(0)
for (i in 1:dim(diffmat)[1])
for (j in 1:dim(diffmat)[2])
b[i] <- terrmat[i, a[i]]
但是,显然 BUGS 代码无法识别 which.min() 或 which.min(),我正在努力寻找一种方法将这些矩阵行位置存储在向量中。也许有一个非常简单的解决方案,但我真的被困在那里了。希望我的信息足够清楚。
如有任何建议,我们将不胜感激。感谢您的宝贵时间!
这是一个最小的工作示例。这里的类比是 x
就是你的 diffmat
。我在这里随机绘制它,但如果您以其他方式定义它,它应该仍然有效。本质上,您在每一行中对 x
的值进行排序,并创建一个新矩阵 e
,如果 x[i,j]
排名为 1,则该矩阵为编码为 1 的虚拟矩阵,否则为 0。然后,假设 terrmat
和 diffmat
具有相同的维度,然后取它的内积和来自 1:ncol(terrmat)
的值向量。然后,这将为您提供观察值排名第一的列索引 i
。下面示例中的 ymat
就是您的 terrmat
所在的位置。我认为它在任何实际大小的问题上都会很慢,但从下面的输出来看它似乎有效。
dl <- list(
ymat = matrix(1:3, ncol=3, nrow=5, byrow=TRUE),
yinds = 1:3
)
mods <- "model{
for(i in 1:5){
for(j in 1:3){
x[i,j] ~ dnorm(0,1)
e[i,j] <- equals(rx[i,j], 1)
}
rx[i,1:3] <- rank(x[i,1:3])
ind[i] <- inprod(e[i,], yinds)
yval[i] <- ymat[i,ind[i]]
}
}"
library(runjags)
out <- run.jags(mods, data=dl, monitor="yval")
out
#
# JAGS model summary statistics from 20000 samples (chains = 2; adapt+burnin = 5000):
#
# Lower95 Median Upper95 Mean SD Mode MCerr MC%ofSD SSeff AC.10 psrf
# yval[1] 1 2 3 1.9973 0.8139 2 0.0058421 0.7 19409 -0.0077146 0.99996
# yval[2] 1 2 3 2.0067 0.81605 3 0.0057704 0.7 20000 0.00049096 1.0003
# yval[3] 1 2 3 1.9895 0.8142 2 0.0057573 0.7 20000 0.00066309 1
# yval[4] 1 2 3 1.9973 0.81638 1 0.0057727 0.7 20000 -0.00040016 0.99998
# yval[5] 1 2 3 1.993 0.81611 1 0.0057708 0.7 20000 -0.0027988 0.99996
#
# Total time taken: 0.7 seconds