web-dev-qa-db-ja.com

R、NULL vs NAに行列を割り当てる最良の方法は?

正方行列を作成するRコードを書いています。だから私のアプローチは:

  1. 正しいサイズの行列を割り当てます
  2. マトリックスの各要素をループし、適切な値を入力します

私の質問は本当に簡単です:この行列を事前に割り当てる最良の方法は何ですか?これまでのところ、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

私が見る限り、前者は後者よりも簡潔な方法です。また、前者はマトリックスをNAで埋めますが、後者はNULLで埋められます。

これを行うための「より良い」方法はどれですか?この場合、これは統計計算であり、この操作は大規模なデータセットで実行されるため、「より良い」を「より良いパフォーマンス」と定義しています。

前者のほうが簡潔ですが、息をのむほど簡単に理解できるわけではないので、どちらにしてもいいと思います。

また、RのNAとNULLの違いは何ですか? ?NAおよび?NULLは、「NA」の長さが「1」であるのに対し、NULLの長さは「0」であることを教えてくれます。またはベストプラクティスですか?これは、マトリックスの作成に使用する方法に影響します。

33
poundifdef

疑わしいときは、自分でテストしてください。最初のアプローチは、より簡単で高速です。

> 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の違いについて:

実際には、4つの特別な定数があります。

さらに、4つの特別な定数、NULL、NA、Inf、およびNaNがあります。

NULLは、空のオブジェクトを示すために使用されます。 NAは、不在(「使用不可」)データ値に使用されます。 Infは無限を表し、NaNはIEEE浮動小数点計算の非数です(たとえば、それぞれ1/0と0/0の演算の結果)。

詳細は 言語定義に関するRマニュアル をご覧ください。

46
Shane

この記事 によれば、NA_real_で事前に割り当てることで、NAで事前に割り当てるよりもうまくいくことができます。記事から:

「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 

私のテストケースでは違いはわずかですが、そこにあります。

4
David Marx
rows<-3
cols<-3    
x<-rep(NA, rows*cols)
x1 <- matrix(x,nrow=rows,ncol=cols)
0
Odysseus Ithaca