我有一個數據框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