0

我在 R 方面没有太多经验。我正在尝试编写一个 Gibbs 采样器,其中我有一个这样的 for 循环:

for (iNum in 1:totNum) {
    rateNum <- Y3[iNum]
    if(Y3[iNum] > 0) {
        yStar3[iNum] <- rtnorm(1, mean = Mean3[iNum], sd = sqrt(Var3), 
                 lower = gz[rateNum], upper = gz[rateNum + 1])
    } else if(Y3[iNum] == 0) {
    yStar3[iNum] <- rtnorm(1, mean = Mean3[iNum], sd = sqrt(Var3), 
                  lower = -Inf, upper = Inf);
    }
}

这需要太多时间。我尝试使用lapply,但这也不够快。有没有办法向量化这个循环?

感谢你并致以真诚的问候!!

4

3 回答 3

2

因此,迭代之间似乎没有依赖关系,这使得向量化变得非常简单

  lhs = rtnorm(length(Y3), mean = Mean3, sd = sqrt(Var3), lower = gz[Y3],
              upper = gz[Y3 + 1])
  rhs = rtnorm(length(Y3), mean=Mean3, sd = sqrt(Var3), lower=-Inf, upper=Inf)

  ifelse(Y3 > 0, lhs, rhs) 

这里的问题是 rtnorm 必须在其输入参数均值、下限和上限上进行矢量化。情况可能并非如此,在这种情况下,您将不得不做更多的工作。

于 2013-02-21T20:00:24.827 回答
2

最简单的方法是生成条件的两半并选择你想要的。该mean参数将采用向量均值,因此您会得到如下信息:

yStar3 <- ifelse(
  Y3 > 0,
    rtnorm(totNum, mean=Mean3, sd=sqrt(Var3), lower=gz[ratenum], upper=gz[rateNum+1]),
    rtnorm(totNum, mean=Mean3, sd=sqrt(Var3), lower=-Inf, upper=Inf))

ifelse对于 Y3 小于零的情况,您必须改进, 可能还有一个附加条件,但这是一般的想法。

更新:@hadley 建议在 rtnorm 中移动 ifelse:

yStar3 <- rtnorm(totNum, mean=Mean3, sd=sqrt(Var3),
  lower=ifelse(Y3>0,gz[rateNum], -Inf),
  upper=ifelse(Y3>0,gz[rateNum+1], Inf))

现在基本上零不必要的计算正在进行。

更新:当然,1 是错误的,正如评论者指出的那样;它应该是 totNum 。

于 2013-02-21T20:02:28.223 回答
1

如果您的变量没有一些值,这有点问题,但是您想要做的是相当直截了当的。为此,您要坚持使用所有矢量化语句,并尽量不要占用太多内存。这是基本策略:

第 1 步:弄清楚如何计算所有数字。

# The number of values you need from 'rtnorm'
sum(Y3 > 0)
sum(Y3 == 0)

# The means you need from the 'Mean3' array
Mean3[Y3 > 0]
Mean3[Y3 == 0]

# Lower and upper limits for Y3 > 0
gz[Y3[Y3 > 0]]
gz[Y3[Y3 > 0] + 1]

第 2 步:在 yStar3 的矢量滤波器上使用这些值。如果没有一些示例数据和变量值,我不能绝对确定我的所有语法都是完美的,但它应该看起来像这样:

yStar3[Y3 > 0] <- rtnorm(
  sum(Y3 > 0), 
  mean = Mean3[Y3 > 0], 
  sd = sqrt(Var3), 
  lower = gz[Y3[Y3 > 0]], 
  upper = gz[Y3[Y3 > 0] + 1])

yStar3[Y3 == 0] <- rtnorm(
  sum(Y3 == 0), 
  mean = Mean3[Y3 == 0], 
  sd = sqrt(Var3), 
  lower = -Inf, 
  upper = Inf)
于 2013-02-21T20:25:46.543 回答