使用多个参数从嵌套列表中的元素使用 mapply to select

Using mapply to select from elements from a nested list using multiple arguments

很抱歉,如果这个问题已经在某处得到解答,但我检查了所有我能找到的页面,但找不到解决这个特定问题的方法。

我想对列表中嵌套的列表中的 select 元素使用应用函数。我想从子列表中 select 的元素因单独列表中包含的参数而异。下面是一些示例代码来说明我正在尝试做什么:

# Set seed for replicable results
set.seed(123)

# Create list of lists populated with randomly generated numbers
list1 <- list()
for (i in 1:10) {
  list1[[i]] <- as.list(sample.int(20, 10))
}

# Create second randomly generated list
list2 <- as.list(sample.int(10, 10))

# For loop with uses values from list 2 to call specific elements from sub-lists within list1
for (i in 1:10){
  print(list1[[i]][[list2[[i]]]])
}

####################################################################################

[1] 4
[1] 8
[1] 5
[1] 8
[1] 15
[1] 17
[1] 12
[1] 15
[1] 3
[1] 15

如您所见,我可以使用 for 循环成功地从嵌套在 list1 中的子列表中获取 select 元素,使用 list2 中的值并结合迭代值 i。 为此类问题提供的解决方案 (R apply function with multiple parameters) 建议我应该能够使用 mapply 函数实现相同的结果。但是,当我尝试这样做时,出现以下错误:

# Attempt to replicate output using mapply
mapply(function(x,y,z) x <- x[[z]][[y[[z]]]], x=list1, y=list2, z=1:10 )

####################################################################################

Error in x[[z]][[y[[z]]]] : subscript out of bounds

我的问题是:

  1. 如何修改我的代码才能达到预期的结果?

  2. 是什么导致了这个错误?过去我在 mapply 上遇到过类似的问题,当时我试图在向量旁边输入一个或多个列表,但一直无法弄清楚为什么它有时会失败。

非常感谢!

试试这个。最好使用函数来捕获所需的值。出现错误的原因是因为使用索引时函数的工作方式不同。最好直接在 *apply() sketch 中设置函数以达到预期的结果。这里的代码:

#Code
unlist(mapply(function(x,y) x[y],x=list1,y=list2))

输出:

[1]  4  8  5  8 15 17 12 15  3 15

或者如果您想要列表中的输出:

#Code 2
List <- mapply(function(x,y) x[y],x=list1,y=list2)

输出:

List
[[1]]
[1] 4

[[2]]
[1] 8

[[3]]
[1] 5

[[4]]
[1] 8

[[5]]
[1] 15

[[6]]
[1] 17

[[7]]
[1] 12

[[8]]
[1] 15

[[9]]
[1] 3

[[10]]
[1] 15

另一个简化的选项可以是(非常感谢,所有功劳都归功于@27ϕ9):

#Code3
mapply(`[[`, list1, list2)

输出:

[1]  4  8  5  8 15 17 12 15  3 15

或:

#Code4
mapply(`[`, list1, list2)

输出:

[[1]]
[1] 4

[[2]]
[1] 8

[[3]]
[1] 5

[[4]]
[1] 8

[[5]]
[1] 15

[[6]]
[1] 17

[[7]]
[1] 12

[[8]]
[1] 15

[[9]]
[1] 3

[[10]]
[1] 15

如果您查看 for 循环,就会发现只有一个变量在变化,即 i。因此,在这种情况下,您可以使用 lapply 甚至 sapply,因为您得到的是一个数字。

sapply(1:10, function(i) list1[[i]][[list2[[i]]]])
#[1]  4  8  5  8 15 17 12 15  3 15