Подтвердить что ты не робот

Лучший способ выделить матрицу в R, NULL vs NA?

Я пишу R-код для создания квадратной матрицы. Поэтому мой подход:

  • Выделите матрицу нужного размера
  • Прокрутите каждый элемент моей матрицы и заполните его соответствующим значением

Мой вопрос очень прост: каков наилучший способ предварительно выделить эту матрицу? До сих пор у меня есть два пути:

> 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.

Каков "лучший" способ сделать это? В этом случае я определяю "лучше" как "лучшую производительность", потому что это статистические вычисления, и эта операция будет выполняться с большими наборами данных.

В то время как первый более сжатый, это не удивительно легко понять, поэтому я чувствую, что это может пойти в любом случае.

Кроме того, в чем разница между NA и NULL в R?? NA и? NULL скажите мне, что "NA" имеет длину "1", тогда как NULL имеет длину "0" - но есть ли здесь больше? Или лучшая практика? Это повлияет на метод, который я использую для создания моей матрицы.

4b9b3361

Ответ 1

Если вы сомневаетесь, проверьте себя. Первый подход проще и быстрее.

> 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).

Вы можете прочитать в руководство R по определению языка.

Ответ 2

В соответствии с этой статьей мы можем сделать лучше, чем предварительное распределение с помощью 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 

В моих тестовых случаях разница небольшая, но она там.

Ответ 3

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