从R中的foreach循环返回列表的列表

6yjfywim  于 2023-01-06  发布在  其他
关注(0)|答案(3)|浏览(147)

我有一个返回两个对象列表的函数(列表l和数字n),我想在foreach循环中遍历这个函数。

create_lists <- function(){
l = sample(100, 5)
n = sample(100, 1)
return(list(l=l, n=n))}

因为create_lists有一个列表作为输出,this post告诉我使用一个合并函数,如下所示:

combine_custom <- function(list1, list2){
  ls = c(list1$l, list2$l)
  ns = c(list1$n, list2$n)
  return(list(l = ls, n = ns))
}

现在我的foreach循环看起来像这样:

m = foreach(i=1:5, .combine = combine_custom)%do%{
   create_lists()}

我期望的输出是:

m$l
[[1]]
[1] 100  25  86  21  28

[[2]]
[1] 78 37 79 41 61

[[3]]
[1] 73 22 78 94 13

[[4]]
[1] 15 28 76 78 52

[[5]]
[1] 32 93 92  2  1

m$n
[1] 52 56 3 79 82

但我得到的是这样的东西:

$l
 [1] 84 28 75 59 68 84 28 75 59 68

$n
[1] 31 91 18 98 39

所以我有两个问题:1)为什么除了两个l列表之外的所有内容都被删除了?2)如何使m$l成为列表的列表?
编辑:我尝试了从here中得到的另一种方法,它不使用c

combine_custom <- function(list1, list2){
      ls = list1$l[[length(list1$l)+1]] = list(list2$l)
      ns = c(list1$n, list2$n)
      return(list(l = ls, n = ns))
    }

但是,确切地说,这给出了与上述相同的结果:

$l
$l[[1]]
[1] 65 84 48 81 82

$n
[1] 88 79 92 36 71
rt4zxlrg

rt4zxlrg1#

我发现了另一种避免上述问题的方法,即combine必须先创建一个新列表,然后再追加列表。另外,我使用的真实的函数实际上返回了一个列表的列表,所以下面的代码很有用:

combine_custom <- function(list1, list2) {
     if (plotrix::listDepth(list1$l) > plotrix::listDepth(list2$l)) {
        ls  <- c(list1$l, list(list2$l))
    } else {
        ls <- c(list(list1$l), list(list2$l))
     }
     ns <- c(list1$n, list2$n)
     return(list(l = ls, n = ns))
}

如果函数可以返回不同嵌套深度的列表,这就不是完美的,但是在我的例子中它是有效的。

o2rvlv0m

o2rvlv0m2#

combine部分带来了很多麻烦,因为在第一次迭代时,它需要从两个列表中生成一个列表,但在第二次迭代时,它需要将一个列表作为元素附加到列表的列表中。
另一种方法(可能有效也可能无效,取决于实际数据/问题的大小)是使用purrr包来处理列表:

> m <- foreach(i=1:3)%do%{create_lists()}
> m
[[1]]
[[1]]$l
[1] 21 33 12 50 36

[[1]]$n
[1] 74

[[2]]
[[2]]$l
[1] 12 80 39 78  6

[[2]]$n
[1] 74

[[3]]
[[3]]$l
[1]  9 61 75 63 94

[[3]]$n
[1] 2

> purrr::transpose(m)
$l
$l[[1]]
[1] 21 33 12 50 36

$l[[2]]
[1] 12 80 39 78  6

$l[[3]]
[1]  9 61 75 63 94

$n
$n[[1]]
[1] 74

$n[[2]]
[1] 74

$n[[3]]
[1] 2

希望能有所帮助!

e4eetjau

e4eetjau3#

谢谢你@Maria H.,你解决了我的问题!“plotrix”软件包对我不起作用,但我用了“collapse”,它工作得很好:

combine_custom1 <- function(a, b) {

  if (collapse::ldepth(a) > collapse::ldepth(b)) {

    ls <- c(a, list(b))

  } else {

    ls <- c(list(a), list(b))

  }

  return(ls)

}

相关问题