R:使用带有附加列表的 mapply 作为参数

R: Using mapply with additional lists as arguments

我有以下参数列表和向量:

myList <- list(c(3, 0, 1), c(2, 2, 2))
vPar1 <- c(1, 5, 100)
vPar2 <- c(100, 5, 1)

我正在尝试从形状参数为 shape1 = vPar1shape2 = vPar2(逐元素)的 3 Beta 分布中抽取样本。

预期结果将是一个包含两个元素的列表:第一个元素将包含 4 个随机数(3 个来自 Beta(1, 100) 分布,1 个来自 Beta(100, 1) 分布),而第二个列表元素将由总共 6 个随机数组成(每个 Beta(1, 100)Beta(5, 5)Beta(100, 1) 分布的 2 个随机数)。

我尝试使用 mapply 生成所需的结果,即循环遍历 3 个参数的元素,但我不知道应该如何使用它:

mapply(function(x, shape1, shape2) {unlist(rbeta(x, shape1, shape2))}, 
          myList, 
          MoreArgs = list(shape1 = vPar1, shape2 = vPar2), 
          SIMPLIFY = FALSE)

这会产生一个包含两个元素的列表,但每个元素都有 3 个随机数,分别插入预期的 4 个和 6 个数字。如有任何建议,我将不胜感激!谢谢。

一个选项是用 lapply 遍历 list,然后将 'vPar1' 和 'vPar2' 作为参数应用到lapply

lapply(myList, function(x) unlist(Map(rbeta, n = x, shape1 = vPar1, shape2 = vPar2)))
#[[1]]
#[1] 0.031955823 0.001533638 0.012877288 0.998004973

#[[2]]
#[1] 0.021860350 0.002145949 0.514477229 0.479578366 0.996876238 0.992356962

也可以写成

lapply(Map(Vectorize(rbeta), myList, MoreArgs = list(shape1 = vPar1, 
        shape2 = vPar2)), unlist)

出于好奇,我想看看你是否可以在没有嵌套 lapply/Map 的情况下做到这一点。我认为这样做没有任何好处,但就是这样。使用 Vectorize 这样您就不必在 lapply 中使用 Map (好吧,至少不必输入它),然后使用 compose 这样您就不必' 必须再执行一次 lapply 传递才能取消列出。

set.seed(1)
lapply(myList, purrr::compose(unlist, Vectorize(rbeta, SIMP = F)), 
       shape1 = vPar1, shape2 = vPar2)

# [[1]]
# [1] 0.0269188825 0.0074012868 0.0005853054 0.9941391825
# 
# [[2]]
# [1] 0.037118765 0.004534898 0.631806102 0.602790723 0.983948500 0.999301928