[英]Convert a matrix into a specific list in R
"a" is a matrix and "b" is a numeric. “ a”是矩阵,“ b”是数字。 The row number of "a" is the same with the length of "b".
行号“ a”与长度“ b”相同。
a<-matrix(1:24,6,4,byrow = T)
b<-c(3,1,2)
I want to convert "a" into a list of which the number of elements in each object is the same with "b". 我想将“ a”转换为列表,其中每个对象中的元素数量与“ b”相同。 The expected result is as follows:
预期结果如下:
[[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
Thank you so much for your help! 非常感谢你的帮助!
Here's an option that will split a
according to b
and since that will return a list of atomic vectors, we lapply
over it to convert to matrix
again. 这是一个根据
b
拆分a
的选项,由于这将返回原子向量列表,因此我们lapply
遍历以再次转换为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
Or if you didn't mind a list of data.frame
s it could be: 或者,如果您不介意
data.frame
的列表,则可能是:
split(as.data.frame(a), rep(seq_along(b),b))
You could also use mapply()
like this: 您也可以像这样使用
mapply()
:
id <- mapply(seq, to=cumsum(b), length.out =b)
lapply(id, function(i) a[i,, drop = FALSE])
Or, if you want to do everything in one go: 或者,如果您想一次完成所有操作:
mapply(function(i,j){a[seq(to=i, length.out = j),,drop=FALSE]},
i = cumsum(b),
j = b)
Compared to using lapply(split(...)), this solution is about 1.5 times faster. 与使用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
)
gives 给
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
We could use split
我们可以使用
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.