8

我写了一个函数,它的输出是一个列表。我想将我的函数放入一个循环中,并且我想将每次迭代的输出(当然是一个列表)存储到一个更大的列表中。换句话说,这个 BIG 列表的每个元素也是一个列表。c() 没有做我想做的事。有没有办法做到这一点?

为了更好地理解我的要求,请考虑以下示例:

iter1 <- list(item1 = 1, item2 = "a")
iter2 <- list(item1 = 1, item2 = "b")
All <- list(iter1 = iter1, iter2 = iter2)

我希望能够在循环中执行类似于上面代码的操作。我怎样才能做到这一点?

谢谢你的帮助,

4

4 回答 4

9

还有另一种分配给列表的方法,使用my_list[[name or number]] <-. 如果您真的想循环执行此操作,只需遍历名称为 iter1、iter2、...

A <- list()
n_iter <- 2
for (i in 1:n_iter){
    iname <- paste("iter",i,sep="")
    A[[iname]] <- get(iname)
}

正如@mnel 指出的那样,动态增长列表效率低下。我认为,另一种方法是使用lapply

n_iter <- 2
inames <- paste("iter",1:n_iter,sep="")
names(inames) <- inames
A <- lapply(inames,get)

这也可以使用数据框来完成,如果您的子列表总是有两个元素,每个元素都有一个一致的类(item1 是数字,item 2 是字符),这将是一种更好的格式。

n_iter <- 2
DF <- data.frame(item1=rep(0,n_iter),item2=rep("",n_iter),stringsAsFactors=FALSE)
for (i in 1:n_iter){
     iname <- paste("iter",i,sep="")
     DF[i,] <- get(iname)
     rownames(DF)[i] <- iname
}

#       item1 item2
# iter1     1     a
# iter2     1     b

但是,这是一种非常丑陋的做事方式。使用时,事情很快就会变得一团糟get。使用您的数据结构,也许您想在循环中创建 iter1 和 iter2 并立即将它们嵌入到父列表或数据框中?

n_iter = 10
DF <- data.frame(item1 = rep(0,n_iter), item2 = rep("",n_iter))
for (i in 1:n_iter){
    ... do stuff to make anum and achar ...
    DF[i,"item1"] <- anum
    DF[i,"item2"] <- achar
}

其中 anum 和 achar 是您要从该迭代中存储的 item1 和 item2 的值。在 SO 的其他地方,他们说使用该data.table包的替代方案几乎是这种数据帧分配的 10 倍快/高效。

哦,最后一个想法:如果您想先将它们放入列表中,您可以稍后轻松转换为数据框

DF <- do.call(rbind.data.frame,A)
于 2013-05-17T05:52:19.570 回答
5

这让你相当于你的All

c(iter1=list(iter1), iter2=list(iter2))

> identical(c(iter1=list(iter1), iter2=list(iter2)), All)
[1] TRUE

假设您想将第三个列表添加到All

c(All, list(iter3=iter3))

如果您不关心列表名称,它看起来会更干净一些

 c(list(iter1), list(iter2))
于 2013-05-17T06:33:34.823 回答
1

我认为@Frank 的答案在这里是正确的,但他给出的第一个例子似乎有点奇怪。我想你想这样做...

bigLL <- list()
for( i in 1:3 ){

  ll <- list( item1 = i , item2 = letters[i] )
  bigLL[[i]] <- ll

}

bigLL
#[[1]]
#[[1]]$item1
#[1] 1

#[[1]]$item2
#[1] "a"


#[[2]]
#[[2]]$item1
#[1] 2

#[[2]]$item2
#[1] "b"


#[[3]]
#[[3]]$item1
#[1] 3

#[[3]]$item2
#[1] "c"

但如果可能,您应该考虑 Frank 的替代方案。

于 2013-05-17T09:27:43.533 回答
-1

这对我很有用,希望它有所帮助。

  data = list()

  for(i in 1:3)
  {
    tmp = c(1,2,3)
    data = rbind(data, tmp)
  }
于 2015-05-22T01:18:41.643 回答