2015-09-26 39 views
2

我具有矩陣VMAT的每n列:堆的矩陣,而不應用中的R

v1 = c(4 , 8 , 3 , 5 , 9)  
    v2 = c(5 , 6 , 6 , 11 , 6) 
    v3 = c(5 , 6 , 6 , 11 , 6) 
    v4= c(8, 6, 4, 4, 3) 
    v5 = c(4 , 8 , 3 , 5 , 9) 
    v6= c(8 , 6 , 4 , 4 , 3) 
    v7 = c(3 , 2 , 7 , 7 , 4) 
    v8= c(3 , 2 , 7 , 7 , 4) 

row1 = c(v1,v2) 
row2 = c(v3,v4) 

row3 = c(v5,v6) 

row4 = c(v7,v8) 

Vmat = rbind(row1,row2,row3,row4) 


Vmat 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] 
row1 4 8 3 5 9 5 6 6 11  6 
row2 5 6 6 11 6 8 6 4 4  3 
row3 4 8 3 5 9 8 6 4 4  3 
row4 3 2 7 7 4 3 2 7 7  4 

我想通過將其分成2(N = NcoI位(VMAT)/ 2來堆疊矩陣=每5列)。

所以輸出:

[,1] [,2] [,3] [,4] [,5] 
    4 8 3 5 9 
    5 6 6 11 6 
    4 8 3 5 9  
    3 2 7 7 4 
    5 6 6 11  6 
    8 6 4 4  3 
    8 6 4 4  3 
    3 2 7 7  4 
+0

爲什麼可以申請不能用? – Heroka

+0

因爲它太慢,矩陣很大,我在計算上要求很高的東西 – robertevansanders

+0

海量有多大? – Heroka

回答

1

我們可以轉換到matrixarray,然後調換陣列aperm,並更改尺寸。

n <- 5 
ar1 <- array(Vmat, dim=c(nrow(Vmat),n,ncol(Vmat)/n)) 
ar2 <- aperm(ar1, c(1,3,2)) 
dim(ar2) <- c(prod(dim(ar1)[c(1,3)]),n) 
ar2 
#  [,1] [,2] [,3] [,4] [,5] 
#[1,] 4 8 3 5 9 
#[2,] 5 6 6 11 6 
#[3,] 4 8 3 5 9 
#[4,] 3 2 7 7 4 
#[5,] 5 6 6 11 6 
#[6,] 8 6 4 4 3 
#[7,] 8 6 4 4 3 
#[8,] 3 2 7 7 4 

使用@ jlhoward的數據,

system.time({ 
    n <- 5 
    ar1 <- array(Vmat, dim=c(nrow(Vmat),n,ncol(Vmat)/n)) 
    ar2 <- aperm(ar1, c(1,3,2)) 
dim(ar2) <- c(prod(dim(ar1)[c(1,3)]),n) 
}) 
# user system elapsed 
# 0.265 0.015 0.279 
+0

這是不是使用apply?如果矩陣是巨大的,這將是緩慢的權利? – robertevansanders

+0

您無法比較系統間的執行時間。您的方法在我的系統中以0.38秒運行,速度減慢大約25%。 – jlhoward

+0

@jlhoward我沒有比較你的方法。我試圖估計我的appraoch運行速度有多快。它或多或少是相似的。 – akrun

2

這裏有一個潛在的data.table解決方案:

# install.packages("data.table", type="source") # requires 1.9.6+ 
library(data.table) 
vm <- ncol(Vmat)/2 
lst <- lapply(1:vm,function(i)c(i,i+vm)) 
result <- melt(as.data.table(Vmat),measure=lst)[,variable:=NULL] 
result 
# value1 value2 value3 value4 value5 
# 1:  4  8  3  5  9 
# 2:  5  6  6  11  6 
# 3:  4  8  3  5  9 
# 4:  3  2  7  7  4 
# 5:  5  6  6  11  6 
# 6:  8  6  4  4  3 
# 7:  8  6  4  4  3 
# 8:  3  2  7  7  4 

使用更現實的例子:

set.seed(1) 
Vmat <- matrix(sample(0:9,16e3*1000,replace=TRUE),nr=16e3) 
library(data.table) 
system.time({ 
    vm <- ncol(Vmat)/2 
    lst <- lapply(1:vm,function(i)c(i,i+vm)) 
    result <- melt(as.data.table(Vmat),measure=lst)[,variable:=NULL] 
    }) 
# user system elapsed 
#  0.3  0.0  0.3 

所以16000行X 1000 cols需要約0.3秒。請注意,雖然此「使用lapply(...)」,它只是用於創建measure.vars列表melt(...),它完成所有工作。

@ Akrun的解決方案(同一系統):

system.time({ 
    n <- ncol(Vmat)/2 
    ar1 <- array(Vmat, dim=c(nrow(Vmat),n,ncol(Vmat)/n)) 
    ar2 <- aperm(ar1, c(1,3,2)) 
    dim(ar2) <- c(prod(dim(ar1)[c(1,3)]),n) 
}) 
# user system elapsed 
# 0.38 0.00 0.37 

all.equal(as.matrix(result),ar2,check.attributes=F) 
# [1] TRUE 
+0

順便說一句,檢查你的輸出暗淡,你有更多的專欄。 – akrun

+0

那麼爲什麼'all.equal(...)'返回TRUE? – jlhoward

+0

dim(result)# [1] 32000 500; dim(ar2)# [1] 3200000 5'。如果你使用'check.attributes = FALSE',我認爲它不會檢查尺寸。 – akrun