将数组拆分为子数组

时间:2015-09-02 13:51:58

标签: r matrix split

我有一个数组,例如arr = cbind(c(1,1,2,2,3), c(1,2,3,4,5)),我想聚集具有相同第一个元素的行,并将结果存储为列表。有办法吗?此示例result = list( cbind(c(1,1), c(1,2)), cbind(c(2,2), c(3,4)), cbind(c(3), c(5)) )

的预期输出

2 个答案:

答案 0 :(得分:3)

我们可以循环(lapply)通过unique第一列的arr值,并根据第一列的匹配元素和唯一元素对行进行子集化。

lapply(unique(arr[,1]), function(i) arr[arr[,1]==i,,drop=FALSE])

或者我们split' arr'行的序列第一栏是#arr'并使用行索引对' arr'

进行子集化
lapply(split(1:nrow(arr), arr[,1]), function(i) arr[i,, drop=FALSE])

或者@Jota在评论中提到,我们可以split' arr'在第一列中将vector作为list元素。我们使用lapply循环并将vector转换为matrix

lapply(split(arr, arr[,1]), matrix, ncol=2)

基准

arr1 <- cbind(rep(seq(1000), each=1000), seq(1e6))
system.time(res1 <- lapply(unique(arr1[,1]), function(i) 
                arr1[arr1[,1]==i,,drop=FALSE]))
# user  system elapsed 
# 18.980   0.000  15.906 


system.time(res2 <- lapply(split(1:nrow(arr1), arr1[,1]), 
                  function(i) arr1[i,, drop=FALSE]))
#  user  system elapsed 
#   0.00    0.00    0.07 
names(res2) <- NULL
 identical(res1, res2)
#[1] TRUE

system.time(res3 <- lapply(split(arr1, arr1[,1]), matrix, ncol=2))
# user  system elapsed 
#  0.000   0.000   0.186 
names(res3) <- NULL
identical(res1, res3)
#[1] TRUE

system.time(res4 <- split(data.frame(arr1), arr1[,1]))
#  user  system elapsed 
#  1.151   0.000   1.039 

根据上述基准,split方法更好。

答案 1 :(得分:1)

为什么不采用这种较短的方法:

split(data.frame(arr), arr[,1])
#$`1`
#  X1 X2
#1  1  1
#2  1  2

#$`2`
#  X1 X2
#3  2  3
#4  2  4

#$`3`
#  X1 X2
#5  3  5