与 cbind() 函数 R 相反
Inverse to cbind() function R
假设我有一个矩阵列表:
matrix <- matrix(1:4, nrow = 2, ncol = 2)
list <- list(matrix, matrix, matrix)
以及由函数 cbind()
:
创建的矩阵
long.matrix <- do.call(cbind, list)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 3 1 3 1 3
[2,] 2 4 2 4 2 4
我想反转过程以从 long.matrix
中获取 list
个矩阵。
我可以使用 for
循环手动执行此操作,但我正在搜索类似的内容: function(long.matrix, 3)
我认为应该存在。有这种东西吗?
暴力破解:
f <- function(long.matrix, num)
lapply(split(long.matrix,
rep(seq(num), each=(ncol(long.matrix)/num)*nrow(long.matrix))),
function(x) matrix(x, nrow=nrow(long.matrix))
)
f(long.matrix, 3)
## $`1`
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
##
## $`2`
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
##
## $`3`
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
rep
为 split
构建类别以拆分数据。由于 R 是列优先的,这里我们取前四个、后四个、第三个四个条目。
填写示例当前维度的值 long.matrix
和 3
,函数缩减为:
lapply(split(long.matrix, rep(seq(3), each=4)), function(x) matrix(x, nrow=2))
注:
(r <- rep(seq(3), each=4) )
## [1] 1 1 1 1 2 2 2 2 3 3 3 3
split(long.matrix, r)
## $`1`
## [1] 1 2 3 4
##
## $`2`
## [1] 1 2 3 4
##
## $`3`
## [1] 1 2 3 4
然后将其中的每一个传递给 matrix
以获得所需的格式。
这样做:
listm=list() #i=1
for(i in 1:3)listm[[i]]=long.matrix[,(2*i-1):(i*2)]
lapply版本
lapply(1:3,function(ii)long.matrix[,(2*ii-1):(ii*2)])
[[1]]
[,1] [,2]
[1,] 1 3
[2,] 2 4
[[2]]
[,1] [,2]
[1,] 1 3
[2,] 2 4
[[3]]
[,1] [,2]
[1,] 1 3
[2,] 2 4
我更喜欢为此使用数组维度。然后,您可以为矩阵定义一个 split
方法:
split.matrix <- function(x, rslice = 1, cslice = 1) {
if (ncol(x) %% cslice) stop("cslice not divisor of number of columns")
if (nrow(x) %% rslice) stop("rslice not divisor of number of rows")
x <- t(x)
dim(x) <- c(dim(x)[1],
dim(x)[2] / rslice,
rslice)
x <- lapply(seq_len(rslice), function(k, a) t(a[,,k]), a = x)
if (cslice > 1) {
x <- lapply(x, function(y, k) {
dim(y) <- c(dim(y)[1],
dim(y)[2] / k,
k)
y <- lapply(seq_len(k), function(k, a) a[,,k], a = y)
y
}, k = cslice)
}
if(length(x) == 1L) x <- x[[1]]
x
}
split(long.matrix, 1, 3)
#[[1]]
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
#
#[[2]]
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
#
#[[3]]
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
split(long.matrix, 1, 1)
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 1 3 1 3 1 3
#[2,] 2 4 2 4 2 4
split(long.matrix, 2, 1)
#[[1]]
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 1 3 1 3 1 3
#
#[[2]]
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 2 4 2 4 2 4
split(long.matrix, 2, 3)
#[[1]]
#[[1]][[1]]
#[1] 1 3
#
#[[1]][[2]]
#[1] 1 3
#
#[[1]][[3]]
#[1] 1 3
#
#
#[[2]]
#[[2]][[1]]
#[1] 2 4
#
#[[2]][[2]]
#[1] 2 4
#
#[[2]][[3]]
#[1] 2 4
假设我有一个矩阵列表:
matrix <- matrix(1:4, nrow = 2, ncol = 2)
list <- list(matrix, matrix, matrix)
以及由函数 cbind()
:
long.matrix <- do.call(cbind, list)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 3 1 3 1 3
[2,] 2 4 2 4 2 4
我想反转过程以从 long.matrix
中获取 list
个矩阵。
我可以使用 for
循环手动执行此操作,但我正在搜索类似的内容: function(long.matrix, 3)
我认为应该存在。有这种东西吗?
暴力破解:
f <- function(long.matrix, num)
lapply(split(long.matrix,
rep(seq(num), each=(ncol(long.matrix)/num)*nrow(long.matrix))),
function(x) matrix(x, nrow=nrow(long.matrix))
)
f(long.matrix, 3)
## $`1`
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
##
## $`2`
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
##
## $`3`
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
rep
为 split
构建类别以拆分数据。由于 R 是列优先的,这里我们取前四个、后四个、第三个四个条目。
填写示例当前维度的值 long.matrix
和 3
,函数缩减为:
lapply(split(long.matrix, rep(seq(3), each=4)), function(x) matrix(x, nrow=2))
注:
(r <- rep(seq(3), each=4) )
## [1] 1 1 1 1 2 2 2 2 3 3 3 3
split(long.matrix, r)
## $`1`
## [1] 1 2 3 4
##
## $`2`
## [1] 1 2 3 4
##
## $`3`
## [1] 1 2 3 4
然后将其中的每一个传递给 matrix
以获得所需的格式。
这样做:
listm=list() #i=1
for(i in 1:3)listm[[i]]=long.matrix[,(2*i-1):(i*2)]
lapply版本
lapply(1:3,function(ii)long.matrix[,(2*ii-1):(ii*2)])
[[1]]
[,1] [,2]
[1,] 1 3
[2,] 2 4
[[2]]
[,1] [,2]
[1,] 1 3
[2,] 2 4
[[3]]
[,1] [,2]
[1,] 1 3
[2,] 2 4
我更喜欢为此使用数组维度。然后,您可以为矩阵定义一个 split
方法:
split.matrix <- function(x, rslice = 1, cslice = 1) {
if (ncol(x) %% cslice) stop("cslice not divisor of number of columns")
if (nrow(x) %% rslice) stop("rslice not divisor of number of rows")
x <- t(x)
dim(x) <- c(dim(x)[1],
dim(x)[2] / rslice,
rslice)
x <- lapply(seq_len(rslice), function(k, a) t(a[,,k]), a = x)
if (cslice > 1) {
x <- lapply(x, function(y, k) {
dim(y) <- c(dim(y)[1],
dim(y)[2] / k,
k)
y <- lapply(seq_len(k), function(k, a) a[,,k], a = y)
y
}, k = cslice)
}
if(length(x) == 1L) x <- x[[1]]
x
}
split(long.matrix, 1, 3)
#[[1]]
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
#
#[[2]]
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
#
#[[3]]
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
split(long.matrix, 1, 1)
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 1 3 1 3 1 3
#[2,] 2 4 2 4 2 4
split(long.matrix, 2, 1)
#[[1]]
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 1 3 1 3 1 3
#
#[[2]]
# [,1] [,2] [,3] [,4] [,5] [,6]
#[1,] 2 4 2 4 2 4
split(long.matrix, 2, 3)
#[[1]]
#[[1]][[1]]
#[1] 1 3
#
#[[1]][[2]]
#[1] 1 3
#
#[[1]][[3]]
#[1] 1 3
#
#
#[[2]]
#[[2]][[1]]
#[1] 2 4
#
#[[2]][[2]]
#[1] 2 4
#
#[[2]][[3]]
#[1] 2 4