我正在关注线程2d matrix to 3d stacked array in r,并对精子功能进行了澄清。
1)我得到解决方案的第一部分,但不理解函数中使用的c(2,1,3)。你能澄清一下吗?
2)此外,我正在尝试该线程中的示例略有变化。
我的情况如下: 对于示例中的类似矩阵:
set.seed(1)
mat <- matrix(sample(100, 12 * 5, TRUE), ncol = 5)
[,1] [,2] [,3] [,4] [,5]
[1,] 27 69 27 80 74
[2,] 38 39 39 11 70
[3,] 58 77 2 73 48
[4,] 91 50 39 42 87
[5,] 21 72 87 83 44
[6,] 90 100 35 65 25
[7,] 95 39 49 79 8
[8,] 67 78 60 56 10
[9,] 63 94 50 53 32
[10,] 7 22 19 79 52
[11,] 21 66 83 3 67
[12,] 18 13 67 48 41
我正在尝试重新排列,以便我有一个3(行)X 5(col)x 11(第三个暗淡)数组。 因此,基本上行会重叠并显示如下内容:
,,1
27 69 27 80 74
38 39 39 11 70
58 77 2 73 48
,,2
38 39 39 11 70
58 77 2 73 48
91 50 39 42 87
,,3
58 77 2 73 48
91 50 39 42 87
21 72 87 83 44
and so on until we hit ,,11
有人有这方面的经验吗? 谢谢!
答案 0 :(得分:1)
偶然发现了这个问题。虽然答案有点晚,但这里有两种选择。
首先,您需要以它的行重叠的方式扩展mat
。我们可以使用这个向量进行行索引。
#[1] 1 2 3 2 3 4 3 4 5 4 5 6 5 6 7 6 7 8 7 8 9 8 9 10 9 10 11 10 11 12
我使用了rollapply
包中的zoo
来创建它,如下所示:
library(zoo)
row_nums <- c(t(rollapply(1:nrow(mat), width = 3, FUN = rep, 1)))
mat <- mat[row_nums, ]
dim(mat)
#[1] 30 5
现在使用@Mr.Flick提供的matsplitter
函数in this answer(请考虑提出他的回答)以获得所需的输出:
matsplitter(mat, 3, 5)
#, , 1
#
# [,1] [,2] [,3] [,4] [,5]
#[1,] 27 69 27 80 74
#[2,] 38 39 39 11 70
#[3,] 58 77 2 73 48
#
#, , 2
#
# [,1] [,2] [,3] [,4] [,5]
#[1,] 38 39 39 11 70
#[2,] 58 77 2 73 48
#[3,] 91 50 39 42 87
#
#, , 3
#
# [,1] [,2] [,3] [,4] [,5]
#[1,] 58 77 2 73 48
#[2,] 91 50 39 42 87
#[3,] 21 72 87 83 44
#
#, , 4
# ...
请注意,您最终会得到一个尺寸为3 x 5 x 10 的数组,而不是 11 。
matsplitter <- function(M, r, c) {
rg <- (row(M) - 1) %/% r + 1
cg <- (col(M) - 1) %/% c + 1
rci <- (rg - 1) * max(cg) + cg
N <- prod(dim(M)) / r / c
cv <- unlist(lapply(1:N, function(x)
M[rci == x]))
dim(cv) <- c(r, c, N)
cv
}
以下是在链接答案中使用aperm
的解决方案(假设mat
如上所述进行了扩展,尺寸为30 x 5)。
aperm(`dim<-`(t(mat), list(5, 3, 10)), c(2, 1, 3))
t(mat)
:转置mat
(新维度:5 x 30)`dim<-`(t(mat), list(5, 3, 10))
:将t(mat)
的维度从5 X 30更改为5 x 3 x 10 aperm(..., c(2, 1, 3))
将数组`dim<-`(t(mat), list(5, 3, 10))
的维度从5 x 3 x 10置换为3 x 5 x 10,即第二维成为第一维,第一维
维度变为第二维度,第三维度保持不变。