dnorm()如何与sapply循环中的分位数向量一起使用

时间:2019-01-19 20:18:38

标签: r

我正在研究Richard McElreath的 Statistical Rethinking ,并对他在p.84上使用的某些代码的工作方式感到困惑。该代码使用贝叶斯网格逼近来推导两个模型参数musigma,以估计样本中高度的分布。

这是代码

首先,我们列出候选mu

mu.list <- seq(from = 140, to = 160, length.out = 200) 

然后列出sigma个候选值

sigma.list <- seq(from = 4, to = 9, length.out = 200) # grid of candidate sigma values

然后,我们使用musigma的每种可能组合制作一个数据帧。

post <- expand.grid(mu = mu.list, sigma = sigma.list) # expand grid so every mu is matched with every sigma

这是一个具有40000行的数据集。

nrow(post)

[1] 40000

现在说我们有一个测量高度的样本,其中包含5个测量值。

heights <- c(151.76, 139.70, 136.52, 156.84, 145.41)

对于我不了解的部分,现在有一个合理的复杂sapply循环,该循环基于musigma的40000个候选组合中的每一个计算对数似然五个高度测量值的样本。

postVec <- sapply(1:nrow(post), function (i) sum( dnorm( 
      heights, # vector of heights
      mean = post$mu[i], # candidate mean height value from corresponding position in grid
      sd = post$sigma[i], # candidate sigma value from corresponding position in the grid
      log = TRUE) ) # make values logs
)

我们从中得到的是一个循环,该循环是一个长度为40000个值的向量,post数据帧的每一行都有一个值。

length(postVec)

[1] 40000

我不明白的是,如果我们将dnorm()从循环中取出,并使用均值和sd的单个值,但是在第一个参数中传递相同的高度的5值样本矢量,像这样

dnorm( heights, mean = 140, sd = 4, log = TRUE )

我们得到五个值

[1]  -6.627033  -2.308045  -2.683683 -11.167283  -3.219861

所以我的问题是:为什么将sapply循环传递到 postVec 上面的向量会产生40000个值,而不是5 x 40000 = 200000个值? < / p>

为什么dnorm()函数在sapply()循环之外返回五个值,但(似乎)在其中只返回一个值?

1 个答案:

答案 0 :(得分:2)

您在sum之前缺少dnorm:在这40000种情况中,每种情况都将这5个值相加,以计算整个heights的对数似然性,而不仅仅是单个观察值。

例如,我们只有两个组合而没有sum

sapply(1:2, function (i) dnorm( 
  heights,
  mean = post$mu[i],
  sd = post$sigma[i],
  log = TRUE)
)
#            [,1]       [,2]
# [1,]  -6.627033  -6.553479
# [2,]  -2.308045  -2.310245
# [3,]  -2.683683  -2.705858
# [4,] -11.167283 -11.061820
# [5,]  -3.219861  -3.186194

在使用sum时,我们得到上述矩阵的列总和:

sapply(1:2, function (i) sum(dnorm( 
  heights,
  mean = post$mu[i],
  sd = post$sigma[i],
  log = TRUE)
))
# [1] -26.00591 -25.81760