2014-09-29 53 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