【问题标题】:Using mapply to select from elements from a nested list using multiple arguments使用 mapply 从使用多个参数的嵌套列表中选择元素
【发布时间】:2020-10-14 12:13:12
【问题描述】:

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

我想使用 apply 函数从嵌套在列表中的列表中选择元素。我想从子列表中选择的元素因单独列表中包含的参数而异。这是一些示例代码来说明我正在尝试做的事情:

# 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 中的子列表中选择元素,使用来自 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 时遇到过类似的问题,但一直无法弄清楚为什么它有时会失败。

非常感谢!

【问题讨论】:

    标签: r nested-lists mapply


    【解决方案1】:

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

    #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
    

    【讨论】:

    • @27ϕ9 我会在帖子中添加积分给你!等一下!
    • 非常感谢@Duck 和@27ϕ9 的快速贡献!老实说,我不完全确定这个解决方案是如何工作的,但这很好,因为希望我可以使用它来了解更多关于列表结构和应用函数的信息。再次感谢:)
    【解决方案2】:

    如果您查看for 循环,则只有一个变量正在发生变化,即i。所以在这种情况下,你可以使用lapply 甚至sapply,因为你得到的是一个单一的号码。

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

    【讨论】:

    • 非常感谢@Ronak Shah!这是一个没有想到的解决方案,但它非常有用。我以后肯定会用它:)
    猜你喜欢
    • 2012-09-22
    • 1970-01-01
    • 2021-03-31
    • 1970-01-01
    • 1970-01-01
    • 2019-07-27
    • 2023-01-26
    • 1970-01-01
    • 2013-12-24
    相关资源
    最近更新 更多