""是一个矩阵和" b"是一个数字。 " a"的行号与" b"的长度相同。
a<-matrix(1:24,6,4,byrow = T)
b<-c(3,1,2)
我想转换&#34; a&#34;到列表中,每个对象中的元素数量与&#34; b&#34;相同。预期结果如下:
[[1]]
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
[3,] 9 10 11 12
[[2]]
[,1] [,2] [,3] [,4]
[1,] 13 14 15 16
[[3]]
[,1] [,2] [,3] [,4]
[1,] 17 18 19 20
[2,] 21 22 23 24
非常感谢你的帮助!
答案 0 :(得分:6)
这是一个根据a
分割b
的选项,因为这将返回一个原子矢量列表,我们lapply
将其转换为{{1}再次。
matrix
或者,如果您没有考虑lapply(split(a, rep(seq_along(b),b)), matrix, ncol = ncol(a))
#$`1`
# [,1] [,2] [,3] [,4]
#[1,] 1 2 3 4
#[2,] 5 6 7 8
#[3,] 9 10 11 12
#
#$`2`
# [,1] [,2] [,3] [,4]
#[1,] 13 14 15 16
#
#$`3`
# [,1] [,2] [,3] [,4]
#[1,] 17 18 19 20
#[2,] 21 22 23 24
的列表,可能是:
data.frame
答案 1 :(得分:3)
你也可以像这样使用mapply()
:
id <- mapply(seq, to=cumsum(b), length.out =b)
lapply(id, function(i) a[i,, drop = FALSE])
或者,如果你想一气呵成:
mapply(function(i,j){a[seq(to=i, length.out = j),,drop=FALSE]},
i = cumsum(b),
j = b)
与使用lapply(split(...))相比,此解决方案的速度提高了约1.5倍。
a<-matrix(1:(87*400),87,400,byrow = TRUE)
b<-c(3, 1, 2, 5, 2, 2, 1, 11, 19, 12, 9, 20)
benchmark(
{
id <- mapply(seq, to=cumsum(b), length.out =b)
lapply(id, function(i)a[i,, drop = FALSE])
},
{
lapply(split(a, rep(seq_along(b),b)), matrix, ncol = ncol(a))
},
replications = 10000
)
给出
replications elapsed relative user.self sys.self user.child sys.child
1 10000 3.53 1.000 3.53 0 NA NA
2 10000 6.02 1.705 5.95 0 NA NA
答案 2 :(得分:1)
我们可以使用split
split(as.data.frame(a),cumsum(c(TRUE,diff(sequence(b))!=1)))
#$`1`
# V1 V2 V3 V4
#1 1 2 3 4
#2 5 6 7 8
#3 9 10 11 12
#$`2`
# V1 V2 V3 V4
#4 13 14 15 16
#$`3`
# V1 V2 V3 V4
#5 17 18 19 20
#6 21 22 23 24