我有一个数据框data
在DIM 120000行乘以5列的R中。二维矩阵到3d堆栈数组r
每300线是在不同的时间间隔测量的帧(即400帧)
行动
我尝试使用array(data, c(300, 5, 400))
预期
使此数据帧到一个3d阵列,每300行分割data
,并将这400个矩阵放在后面彼此。
实际
读取值沿向下的data
第一列,并把这些成阵列的所述第一部分。
我有一个数据框data
在DIM 120000行乘以5列的R中。二维矩阵到3d堆栈数组r
每300线是在不同的时间间隔测量的帧(即400帧)
行动
我尝试使用array(data, c(300, 5, 400))
预期
使此数据帧到一个3d阵列,每300行分割data
,并将这400个矩阵放在后面彼此。
实际
读取值沿向下的data
第一列,并把这些成阵列的所述第一部分。
另一种选择是:
m1 <- matrix(1:(300*400*5), nrow=300*400, ncol=5)
lst <- lapply(split(seq_len(nrow(m1)),(seq_len(nrow(m1))-1) %/%300 +1),
function(i) m1[i,])
arr1 <- array(0, dim=c(300,5,400))
for(i in 1:400){
arr1[,,i] <- lst[[i]]
}
m1[297:300,]
# [,1] [,2] [,3] [,4] [,5]
#[1,] 297 120297 240297 360297 480297
#[2,] 298 120298 240298 360298 480298
#[3,] 299 120299 240299 360299 480299
#[4,] 300 120300 240300 360300 480300
tail(arr1[,,1],4)
# [,1] [,2] [,3] [,4] [,5]
#[297,] 297 120297 240297 360297 480297
#[298,] 298 120298 240298 360298 480298
#[299,] 299 120299 240299 360299 480299
#[300,] 300 120300 240300 360300 480300
或者通过@Ananda Mahto的建议
library(abind)
arr2 <- abind(lapply(split(seq_len(nrow(m1)),
(seq_len(nrow(m1))-1) %/% 300 + 1), function(x) m1[x, ]), along = 3)
稍微慢一点,但是少一些手工工作,会是'abind(lapply(split(seq_len(nrow(m1))) (seq_len(nrow(m1))-1)%/%300 + 1),函数(x)m1 [x,]),沿着= 3)'(其中'abind'来自“abind”包)。 +1。 – A5C1D2H2I1M1N2O1R2T1 2014-09-29 19:33:52
@Ananda Mahto谢谢我考虑过'abind',然后我就开始玩'for'循环。另外,因为基于你的例子的“aperm”没有得到预期的结果。我正在使用'list(300,5,400)'而不是'list(5,300,400)''的顺序错误。 :-) – akrun 2014-09-29 19:39:46
下面是使用dim<-
和aperm
的方法:
的样本数据:
set.seed(1)
mat <- matrix(sample(100, 12 * 5, TRUE), ncol = 5)
mat
# [,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
切片和切块:
Sliced <- aperm(`dim<-`(t(mat), list(5, 3, 4)), c(2, 1, 3))
Sliced
# , , 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,] 91 50 39 42 87
# [2,] 21 72 87 83 44
# [3,] 90 100 35 65 25
#
# , , 3
#
# [,1] [,2] [,3] [,4] [,5]
# [1,] 95 39 49 79 8
# [2,] 67 78 60 56 10
# [3,] 63 94 50 53 32
#
# , , 4
#
# [,1] [,2] [,3] [,4] [,5]
# [1,] 7 22 19 79 52
# [2,] 21 66 83 3 67
# [3,] 18 13 67 48 41
调节,以满足您的数据的数量。除了
破事,我们得到:
t(mat)
:调换你的矩阵(所以我们现在有5×12)。dim<-(..., list(...))
:将其转换为一个数组,在这种情况下,5(行)x 3(col)x 4(第三维)。aperm
:最后一步的结果是逐行的,所以我们需要将它转换为列,所以这就像一个t
,但涉及多个维度。这些也都是非常高效的运营。下面是这种方法的使用@ akrun的比较:
m1 <- matrix(1:(300*400*5), nrow=300*400, ncol=5)
am <- function() {
aperm(`dim<-`(t(m1), list(5, 300, 400)), c(2, 1, 3))
}
ak <- function() {
lst <- lapply(split(seq_len(nrow(m1)),(seq_len(nrow(m1))-1) %/%300 +1),
function(i) m1[i,])
arr1 <- array(0, dim=c(300,5,400))
for(i in 1:400){
arr1[,,i] <- lst[[i]]
}
arr1
}
library(microbenchmark)
microbenchmark(am(), ak(), times = 20)
# Unit: milliseconds
# expr min lq median uq max neval
# am() 19.09133 27.63269 31.18292 67.12434 146.2673 20
# ak() 496.11494 518.71223 550.02215 591.27266 699.9834 20
你尝试通过建立解决问题一个*小*可重现的例子? – A5C1D2H2I1M1N2O1R2T1 2014-09-29 17:27:00
不是现在,我的主要问题是让数组读取变量而不是列。我认为这将是一个快速解决方案。 – 2014-09-29 17:39:36
通常,使用一个可重复的小例子来帮助识别问题的根源。看看'aperm'。 – A5C1D2H2I1M1N2O1R2T1 2014-09-29 17:41:22