Я хочу применить образец функции к вложенному списку (я назову этот список bb
), и у меня также есть список чисел (я назову этот список k
), который будет предоставлен в образце функции. Я хотел бы, чтобы каждое из чисел в k перебирало все значения каждого списка в bb. Как это сделать с помощью mapply
или lapply
?
Вот данные:
k <- list(1,2,4,3) #this is the list of numbers to be supplied in the `sample.int` function
b1 <- list(c(1,2,3),c(2,3,4),c(3,4,5),c(4,5,6)) #The first list of bb
b2 <- list(c(1,2),c(2,3),c(3,4),c(4,5), c(5,6)) #The second list of bb
bb <- list(b1,b2) #This is list bb containing b1 and b2 whose values are to be iterated through
Я создал эту функцию mapply
, но она не дала ожидаемого результата:
mapply(function(x, y) {
x[sample.int(y,y, replace = TRUE)]
}, bb,k, SIMPLIFY = FALSE)
Это возвращает только 10 выходных значений, но я хотел бы, чтобы каждое число k перебирало все значения двух списков в bb
, поэтому для двух списков в bb
должно быть 10 * 2 выходных данных. Возможно, я неправильно использую mapply
, поэтому буду признателен, если кто-нибудь укажет мне правильное направление!
outer
твой друг. Обычно он используется для вычисления произведения внешней матрицы. Учитывать:
outer(1:3, 2:4)
1:3 %o% 2:4 ## or
# [,1] [,2] [,3]
# [1,] 2 3 4
# [2,] 4 6 8
# [3,] 6 9 12
Он также имеет аргумент FUN=
, который по умолчанию равен "*"
. Однако он позволяет вам вычислять любую функцию для комбинаций x
и y
крест-накрест, то есть x[1] X y[1], x[1] X y[2], ...
, тогда как *apply
функции вычисляют только x[1] X y[1], x[2] X y[2], ...
. Итак, давайте сделаем это:
FUN <- Vectorize(function(x, y) x[sample.int(y, y)])
set.seed(42)
res <- outer(bb, k, FUN)
res
# [,1] [,2] [,3] [,4]
# [1,] List,1 List,2 List,4 List,3
# [2,] List,1 List,2 List,4 List,3
Этот результат выглядит немного странно, но мы легко можем его unlist
.
res <- unlist(res, recursive=F)
res
# [[1]]
# [1] 1 2 3
#
# [[2]]
# [1] 1 2
#
# [[3]]
# [1] 1 2 3
#
# [[4]]
# [1] 2 3 4
#
# [[5]]
# [1] 2 3
#
# [[6]]
# [1] 1 2
#
# [[7]]
# [1] 2 3 4
#
# [[8]]
# [1] 4 5 6
#
# [[9]]
# [1] 1 2 3
#
# [[10]]
# [1] 3 4 5
#
# [[11]]
# [1] 3 4
#
# [[12]]
# [1] 4 5
#
# [[13]]
# [1] 2 3
#
# [[14]]
# [1] 1 2
#
# [[15]]
# [1] 1 2 3
#
# [[16]]
# [1] 2 3 4
#
# [[17]]
# [1] 3 4 5
#
# [[18]]
# [1] 2 3
#
# [[19]]
# [1] 3 4
#
# [[20]]
# [1] 1 2
Вуаля, 20 результатов.
Спасибо @jay.sf. Действительно,
outer
— редко запрашиваемая, но очень полезная функция. Как вы сказали, функцияmapply
перебирает оба списка одновременно, поэтому она исчерпывает все элементы, даже когда я пробовал это:Map(function(i) mapply(function(x, y) { x[sample.int(y,y, replace = TRUE)] }, bb,k, SIMPLIFY = FALSE), seq_along(bb))