简体   繁体   中英

R: Using mapply with additional lists as arguments

I have the following list and vectors of parameters:

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

and I'm trying to draw samples from 3 Beta distributions with shape parameters shape1 = vPar1 and shape2 = vPar2 (element-wise).

The expected result would be a list with two elements: the first element would consist of 4 random numbers (3 from a Beta(1, 100) and 1 from a Beta(100, 1) distribution) whereas the second list element would consist of a total of 6 random numbers (2 random numbers of a Beta(1, 100) , Beta(5, 5) and Beta(100, 1) distributions each).

I tried to produce the required result using mapply ie cycling through the elements of the 3 arguments, but I can't figure how it should be used exactly:

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

This results in a list of two elements but with 3 random numbers each, insetad of the expected 4 and 6 numbers respectively. I'd be grateful for any suggestions! Thanks.

One option is to loop over the list with lapply and then apply the 'vPar1' and 'vPar2' as arguments in a nested Map within the 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

It can also be written as

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

Out of curiosity, I wanted to see if you could do this without nested lapply / Map . I don't think there's any benefit to doing it this way, but here it is. Use Vectorize so you don't have to use Map inside lapply (well, don't have to type it out at least), then use compose so you don't have to do another lapply pass to unlist.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM