【问题标题】:Trying to create and loop through matrix of unbalanced data in R尝试在R中创建和循环不平衡数据矩阵
【发布时间】:2011-12-17 00:19:15
【问题描述】:

我正在尝试进行分层贝叶斯分析,但在使用 R 和 WinBUGS 代码时遇到了一点问题。我没有平衡的数据,并且正在努力编码。我每天使用 iButtons(温度记录设备)在横断面上收集温度数据,并试图生成一个将其与遥感数据相关联的模型。不幸的是,每个样带都有不同数量的 iButton,因此在样带 (j) 中创建按钮 (i) 的 3D 矩阵,在第 (t) 天重复“采样”对我来说是个问题。

最终,我的模型将类似于:

1 级 Temp[ijk] ~ N(theta[ijk], tau) theta[ijk] = b0 + b1*x1 + . . . + bn*xn

2 级 b0 = a00 + a01*y1 + 。 . .安*因 b1 = a10 + a11*y1 ...

3 级(也许?) - 2 级随机拦截

通常我会这样做: Wide

J <- length(unique(Data$block))
I <- length(unique(Data$iButton))
Ti <- length(unique(Data$julian))

Temp <- array(NA, dim = c(I, Ti, J))

for(t in 1:Ti) {
sel.rows <- Wide$block == t
Temp[,,t] <- as.matrix(Wide)[sel.rows, 3:Ti]
}

然后我可以有一个 3D 矩阵,我可以像这样在 WinBUGS 或 OpenBUGS 中循环:

for(i in 1:J) {          # Loop over transects/blocks
  for(j in 1:I) {        # Loop over buttons
    for(t in 1:Ti) {     # Loop over days
    Temp[i,j,t] ~ dnorm(theta[i,j,t])    
    theta[i,j,t] <- alpha.lam[i] + blam1*radiation[i,j] + blam2*cwd[i,j] + blam3*swd[i,j]
}}}

不管怎样,不用担心上面代码的细节,它只是从其他分析中作为示例放在一起。我的主要问题是,当我没有平衡设计且每个样带具有相同数量的 iButton 时,如何进行此类分析?任何帮助将不胜感激。我显然是 R 和 WinBUGS 的新手,之前没有太多的计算机编码经验。

谢谢!

哦,这是长(堆叠)格式的数据:

    > Data[1:15, 1:4]
   iButton julian block       aveT
1        1      1     1 -4.5000000
2        1      2     1 -5.7500000
3        1      3     1 -3.5833333
4        1      4     1 -4.6666667
5        1      5     1 -2.5833333
6        1      6     1 -3.0833333
7        1      7     1 -1.5833333
8        1      8     1 -8.3333333
9        1      9     1 -5.0000000
10       1     10     1 -2.4166667
11       1     11     1 -1.7500000
12       1     12     1 -3.2500000
13       1     13     1 -3.4166667
14       1     14     1 -2.0833333
15       1     15     1 -1.7500000

【问题讨论】:

  • 现在没时间写一个完整的答案但是...如果您有一个矩阵 theta 并且您希望在每个点都使用 dnorm,请尝试...Temp
  • 我没有矩阵 theta。我会使用 WinBUGS 作为 MCMC 机器来估计 theta 和 beta 项。基本上我的问题是我在 i、j、t 处有 Temp 数据,但是每个 j 的 i 长度不同,所以我不知道如何将 Temp 编码为正确的形式来循环遍历它。我能想到的唯一另一件事是,我目前糟糕的编码技能将允许拥有一个 [i,t] 矩阵,然后使用块 (j) 作为使用虚拟变量的协变量。如果设计是平衡的,我会按照上面的代码进行编码,但在这种情况下不会起作用。

标签: r for-loop hierarchical reshape winbugs


【解决方案1】:

创建一个向量或长度数组并使用子索引。 使用您的示例:

J <- length(unique(Data$block))
I <- tapply(Data$iButton, Data$block, function(x) length(unique(x))
Ti <- tapply(Data$julian, list(Data$iButton, Data$block), function(x) length(unique(x))


for(i in 1:J) {          # Loop over transects/blocks
  for(j in 1:I[i]) {        # Loop over buttons
    for(t in 1:Ti[i, j]) {     # Loop over days
    Temp[i,j,t] ~ dnorm(theta[i,j,t])    
    theta[i,j,t] <- alpha.lam[i] + blam1*radiation[i,j] + blam2*cwd[i,j] + blam3*swd[i,j]
}}}

我认为它会起作用,但我没有测试,因为没有数据。

【讨论】:

  • @Iselzer - 谢谢,我认为这会奏效。我以前从未使用过子索引(就像我说的,我是新手)。明天我将不得不更多地考虑如何将我的温度数据 (Temp) 转换为正确的格式。一个挑战是 WinBUGS 无法处理数据中的任何 NA,因此我的 Temp[i,j,t] 矩阵对于块 J 的每个级别都必须具有不同大小的 2D 矩阵。
  • @Iselzer - 我会的,但它不会让我,因为我的声誉只有 11 并且必须是 15 才能投票。
  • @djhocking:但如果这是一个有效的答案,那么您肯定可以在您提出问题后对其进行“勾选”。
【解决方案2】:

您可以尝试改用list 吗?

这允许列表中每个项目的长度可变,其中每个索引对应于横断面。

所以是这样的:

theta <- list()

for(i in unique(Data$block)) {
  ibuttons <- unique(Data$iButton[Data$block==i])
  days <- unique(Data$julian[Data$block==i])
  theta[[i]] <- matrix(NA, length(ibuttons), length(days)) # Empty matrix with NA's
    for(j in 1:length(ibuttons)) {
      for(t in 1:length(days)) {
        theta[[i]][j,t] <- fn(i, ibuttons[j], days[t])
      }
    }
  }

【讨论】:

  • 谢谢,我是一个没有经验的程序员,我从来没有想过要创建一个矩阵列表来循环遍历。如果我在 R 中进行 MCMC,这肯定会起作用。我不知道 BUGS 语言是否以这种方式处理索引。我使用 R2WinBUGS 将我的数据传递给 WinBUGS,以利用它简单、透明的语言并使用它的 Gibbs 采样器。如果 WinBUGS 由于某种原因无法处理这个问题,我可能会尝试在 R 中进行 MCMC 采样。有很多包,编写自己的采样器对于简单模型来说不会太糟糕。
  • 我对 WinBUGS 的经验有限,但在处理多个不同维度的矩阵时,在 R 中处理 list 对象肯定会派上用场。
猜你喜欢
  • 2014-09-03
  • 2017-05-07
  • 2021-10-30
  • 1970-01-01
  • 2018-07-01
  • 1970-01-01
  • 2018-08-07
  • 1970-01-01
  • 2013-02-02
相关资源
最近更新 更多