我有一个数组,例如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)) )
答案 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