2013-02-12 85 views
4

我有一个列表,其中每个列表元素本身都拥有包含多个名称对象的另一个列表。这些命名对象中的每一个都是具有相同长度的向量。我的目标是通过串联矢量将相关对象(同名的对象)有效地组合成一个矩阵。将相关的嵌套列表元素向量组合到矩阵中

下面是我正在使用的结构类型的示例。然而,在目前的应用程序中,它来自mclapply,因为它是一个并行化的多级模型,我不认为有办法让列表返回列表。

> test=lapply(1:2,function(x){out = list(); out$t=rnorm(3)+x; out$p =rnorm(3)+ x+.1; return(out)}) 
> test 
[[1]] 
[[1]]$t 
[1] 0.5950165 0.8827352 0.5614947 

[[1]]$p 
[1] 2.6144102 1.9688743 0.6241944 


[[2]] 
[[2]]$t 
[1] 2.562030 1.832571 3.018756 

[[2]]$p 
[1] 1.7431969 0.5305784 2.6935106 

下面就来完成我想要

> t.matrix = cbind(test[[1]]$t,test[[2]]$t) 
> t.matrix 
      [,1]  [,2] 
[1,] 2.2094525 2.634907 
[2,] -0.2822453 2.440666 
[3,] 1.1704518 2.483424 

一个粗暴的方式,而是我希望能够在很长的列表(约1万台)做到这一点,我现在的解决方案不能缩放。

我想我可以使用for循环,但似乎必须有更好的方法来使用reduce或unlist或sapply或类似的东西来实现它。

+1

我总是很高兴,当你分享这些题型使用'set.seed()',以便我们可以比较我们得到的输出和你打算得到的结果。 – A5C1D2H2I1M1N2O1R2T1 2013-02-12 18:59:05

+0

感谢您的指针!我一定会在将来做到这一点。 – 2013-02-12 19:39:46

回答

5
test <- lapply(1:4, function(x) { 
      out = list(); out$t=rnorm(3)+x; out$p =rnorm(3)+ x+.1; return(out)}) 

do.call(cbind, lapply(test, function(X) X[["t"]])) 
## do.call(cbind, lapply(test, "[[", "t"))   ## Or, equivalently 
#   [,1]  [,2]  [,3]  [,4] 
# [1,] 0.7382887 0.9248296 4.205222 5.847823 
# [2,] 3.69 3.6806652 3.324739 3.695195 
# [3,] 2.3611483 1.9305901 1.574586 4.287534 

或者,要同时处理两组列表中的元素:关于使用unlist(test, recursive = FALSE)

elems <- c("t", "p") 
sapply(elems, function(E) { 
    do.call(cbind, 
      lapply(test, function(X) { 
       X[[E]] 
      })) 
}, simplify=FALSE) 
# $t 
#   [,1]  [,2]  [,3]  [,4] 
# [1,] 1.9226614 0.66463844 2.558517 2.743381 
# [2,] 3.0026400 0.03238983 2.195404 3.824127 
# [3,] 0.9371057 3.54638107 2.968717 2.434471 
# 
# $p 
#   [,1]  [,2]  [,3]  [,4] 
# [1,] 0.8544413 2.942780 4.693698 4.158212 
# [2,] 0.7172070 2.381438 4.869630 3.503361 
# [3,] 3.1369674 2.464447 2.484968 3.626174 
3

什么。如果你想要“p”和“t”分开,它需要在多个步骤中完成。在这里,他们是一起的:

temp <- do.call(cbind, unlist(test, recursive = FALSE)) 
temp 
      t   p  t  p 
[1,] 0.3735462 2.6952808 2.487429 1.794612 
[2,] 1.1836433 1.4295078 2.738325 3.611781 
[3,] 0.1643714 0.2795316 2.575781 2.489843 

它们分离出来是非常简单的:

temp[, colnames(temp) %in% "t"] 
#    t  t 
# [1,] 0.3735462 2.487429 
# [2,] 1.1836433 2.738325 
# [3,] 0.1643714 2.575781 
temp[, colnames(temp) %in% "p"] 
#    p  p 
# [1,] 2.6952808 1.794612 
# [2,] 1.4295078 3.611781 
# [3,] 0.2795316 2.489843 

这是我使用的数据:

set.seed(1) 
test <- lapply(1:2, function(x) { 
    out = list() 
    out$t=rnorm(3)+x 
    out$p =rnorm(3)+ x+.1 
    return(out) 
}) 
+0

感谢您的答复,upvote为你。然而,我有一个犹豫是,我看到[这里](http://stackoverflow.com/a/4013388/288545)的基准测试表明,使用unlist打开的名字要慢得多。我想我可以使用你的解决方案,并关闭useNames标志,但这会使重建有点棘手。 – 2013-02-12 19:42:34

+0

@DanielKessler,感谢您分享该链接。我不知道在使用unlist时保留名字使得函数慢得多!如果你知道你的数据组织得很好,那么我想一个解决方法是在最后选择奇数列和偶数列,但这可能很容易出错。我认为乔希的做法绝对是最合适的。 – A5C1D2H2I1M1N2O1R2T1 2013-02-13 08:02:05