从R

时间:2018-12-06 13:53:21

标签: r list foreach

我有一个函数,该函数返回两个对象的列表(列表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函数:

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

2 个答案:

答案 0 :(得分:0)

Dim XMLRqst As New STKReservedStock_insertrow(User, Company) Rqst._pdt = If(IsDBNull(drStock.Item("pdt")), "", drStock.Item("pdt").ToString) Rqst._whse = If(IsDBNull(drStock.Item("whse")), "", drStock.Item("whse").ToString) Rqst._traceNumber = If(IsDBNull(drStock.Item("traceNumber")), 0, CInt(drStock.Item("traceNumber"))) Rqst._bin = If(IsDBNull(drStock.Item("bin")), "", drStock.Item("bin").ToString) Rqst._lotref = If(IsDBNull(drStock.Item("lotref")), "", drStock.Item("lotref").ToString) Rqst._packUOM = If(IsDBNull(drStock.Item("packUOM")), "", drStock.Item("packUOM").ToString) Rqst._grade = If(IsDBNull(drStock.Item("grade")), "", drStock.Item("grade").ToString) Rqst._shpLabel = If(IsDBNull(drStock.Item("shpLabel")), 0, CInt(drStock.Item("shpLabel"))) Rqst._countLoc = If(IsDBNull(drStock.Item("countLoc")), "", drStock.Item("countLoc").ToString) Rqst._palletType = If(IsDBNull(drStock.Item("palletType")), "", drStock.Item("palletType").ToString) Rqst._subPdt = If(IsDBNull(drStock.Item("subPdt")), "", drStock.Item("subPdt").ToString) Rqst._subTn = If(IsDBNull(drStock.Item("subTn")), 0, CInt(drStock.Item("subTn"))) Rqst._origReserved = reservedqty Rqst._reserved = reservedqty Rqst._dateReserved = Now Rqst._reservedBy = User Rqst._reason = reason Rqst._party = party Rqst._Cancelled = "f" Rqst._CancelledByUsr = "" Rqst._RsvQty = reservedqty Send(XMLRqst.toxml) 部分带来了很多麻烦,因为在第一次迭代中,它需要从两个列表中创建一个列表,但是在第二次迭代中,它需要将一个列表作为元素附加到列表列表。

另一种方法(取决于实际数据/问题的大小,是否可以起作用)是使用combine软件包来处理列表:

purrr

希望有帮助!

答案 1 :(得分:0)

我发现了另一种避免上述问题的方法,即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))
}

如果该函数可以返回不同嵌套深度的列表,则这不是完美的方法,但对我而言适用。