2014-09-29 59 views
3

我有一个数据框data在DIM 120000行乘以5列的R中。二维矩阵到3d堆栈数组r

每300线是在不同的时间间隔测量的帧(即400帧)

行动

我尝试使用array(data, c(300, 5, 400))

预期

使此数据帧到一个3d阵列,每300行分割data,并将这400个矩阵放在后面彼此。

实际

读取值沿向下的data第一列,并把这些成阵列的所述第一部分。

+1

你尝试通过建立解决问题一个*小*可重现的例子? – A5C1D2H2I1M1N2O1R2T1 2014-09-29 17:27:00

+0

不是现在,我的主要问题是让数组读取变量而不是列。我认为这将是一个快速解决方案。 – 2014-09-29 17:39:36

+0

通常,使用一个可重复的小例子来帮助识别问题的根源。看看'aperm'。 – A5C1D2H2I1M1N2O1R2T1 2014-09-29 17:41:22

回答

4

另一种选择是:

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) 
+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

+0

@Ananda Mahto谢谢我考虑过'abind',然后我就开始玩'for'循环。另外,因为基于你的例子的“aperm”没有得到预期的结果。我正在使用'list(300,5,400)'而不是'list(5,300,400)''的顺序错误。 :-) – akrun 2014-09-29 19:39:46

5

下面是使用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