2009-11-16 47 views
31

我在寫R代碼來創建一個方形矩陣。所以,我的做法是:在R中分配矩陣的最佳方法,NULL vs NA?

  1. 分配正確的尺寸
  2. 循環矩陣通過我的矩陣中的每個元素,並用適當的值

我的問題填充它是非常簡單的:什麼是預先分配此矩陣的最佳方式是什麼?到目前爲止,我有兩個途徑:

> x <- matrix(data=NA,nrow=3,ncol=3) 
> x 
    [,1] [,2] [,3] 
[1,] NA NA NA 
[2,] NA NA NA 
[3,] NA NA NA 

> x <- list() 
> length(x) <- 3^2 
> dim(x) <- c(3,3) 
> x 
    [,1] [,2] [,3] 
[1,] NULL NULL NULL 
[2,] NULL NULL NULL 
[3,] NULL NULL NULL 

據我所看到的,前者比後者更簡潔的方法。另外,前者用NAs填充矩陣,而後者用NULL填充。

哪種「更好」的方式來做到這一點?在這種情況下,我將「更好」定義爲「更好的性能」,因爲這是統計計算,而且此操作將與大型數據集一起進行。

雖然前者更簡潔,但並不令人驚訝地容易理解,所以我覺得這樣做可能無論如何。

另外,R中的NA和NULL有什麼區別? ?NA和?NULL告訴我,「NA」的長度爲「1」,而NULL的長度爲「0」 - 但這裏有更多嗎?還是最佳做法?這將影響我用來創建矩陣的方法。

+1

不問,是爲什麼你想*循環*在矩陣的元素上?是否有可能使用矢量化操作?這應該是你的下一個問題! :) – Harlan 2009-11-17 14:17:09

+0

@Harlan這基本上是我在這個問題在這裏:http://stackoverflow.com/questions/1719447/outer-equivalent-for-non-vector-lists-in-r。如果您有建議,我很樂意聽到它! – poundifdef 2009-11-17 15:03:59

回答

44

如有疑問,請測試一下自己。第一種方法既簡單又快捷。

> create.matrix <- function(size) { 
+ x <- matrix() 
+ length(x) <- size^2 
+ dim(x) <- c(size,size) 
+ x 
+ } 
> 
> system.time(x <- matrix(data=NA,nrow=10000,ncol=10000)) 
    user system elapsed 
    4.59 0.23 4.84 
> system.time(y <- create.matrix(size=10000)) 
    user system elapsed 
    0.59 0.97 15.81 
> identical(x,y) 
[1] TRUE 

關於NA和NULL之間的區別:

實際上有四個特殊的常量。

另外,還有四個特殊的常量,NULL,NA,Inf和NaN。

NULL用於指示空對象。 NA用於不存在(「不可用」)數據值。 Inf表示無窮大,並且NaN在IEEE浮點演算中不是數字(例如,分別爲1/0和0/0的操作的結果)。

你可以在the R manual on language definition瞭解更多。

+0

呵呵,也不知道system.time。非常感謝! – poundifdef 2009-11-17 02:12:37

+0

如果你將要比較的方法不應該包裝在一個函數中的兩個方法?通過函數調用添加開銷。 – Dason 2012-02-04 17:11:43

+0

@Dason在實踐中,如果一個人經常使用較長的方法,是不是可能被封裝在一個函數中呢?而「矩陣」將保持原樣。 – Gregor 2012-08-31 18:04:10

3

根據this article我們可以做得比預先分配NA預先分配NA_real_更好。從文章:

只要您爲'x'中的任何單元格指定一個數值,矩陣將首先必須被強制轉換爲數值,當分配新值時。最初分配的邏輯矩陣是徒勞無功的,只是增加了不必要的內存佔用和垃圾收集器的額外工作。 使用NA_real_(或NA_integer_爲整數)

根據建議相反,它分配:讓我們來測試它。

testfloat = function(mat){ 
    n=nrow(mat) 
    for(i in 1:n){ 
    mat[i,] = 1.2 
    } 
} 

>system.time(testfloat(matrix(data=NA,nrow=1e4,ncol=1e4))) 
user system elapsed 
3.08 0.24 3.32 
> system.time(testfloat(matrix(data=NA_real_,nrow=1e4,ncol=1e4))) 
user system elapsed 
2.91 0.23 3.14 

而對於整數:

testint = function(mat){ 
    n=nrow(mat) 
    for(i in 1:n){ 
    mat[i,] = 3 
    } 
} 

> system.time(testint(matrix(data=NA,nrow=1e4,ncol=1e4))) 
user system elapsed 
2.96 0.29 3.31 
> system.time(testint(matrix(data=NA_integer_,nrow=1e4,ncol=1e4))) 
user system elapsed 
2.92 0.35 3.28 

所不同的是在我的測試例小,但它的存在。

+1

'3'屬於'numeric'類,你可能意思是3L。儘管如此,我並沒有看到僅僅使用NA的任何可衡量的性能影響(即使每次測量20s並確保gc完成其工作) – 2015-08-16 10:22:06

0
rows<-3 
cols<-3  
x<-rep(NA, rows*cols) 
x1 <- matrix(x,nrow=rows,ncol=cols)