2009-11-16 30 views
31

Tôi đang viết mã R để tạo một ma trận vuông. Vì vậy, cách tiếp cận của tôi là:Cách tốt nhất để phân bổ ma trận trong R, NULL vs NA?

  1. Phân bổ một ma trận kích thước chính xác
  2. Vòng qua mỗi phần tử của ma trận của tôi và điền nó với một giá trị thích hợp

Câu hỏi của tôi là thực sự đơn giản: là những gì cách tốt nhất để phân bổ trước ma trận này là gì? Như vậy đến nay, tôi có hai cách:

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

hoặc

> 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 

Theo như tôi thấy, trước đây là một phương pháp ngắn gọn hơn sau này. Ngoài ra, trước đây điền vào ma trận với NA, trong khi sau đó được lấp đầy với NULL.

Cách nào "tốt hơn" để thực hiện việc này? Trong trường hợp này, tôi xác định "tốt hơn" là "hiệu suất tốt hơn", bởi vì đây là tính toán thống kê và hoạt động này sẽ diễn ra với các tập dữ liệu lớn.

Trong khi trước đây ngắn gọn hơn, nó không phải là dễ hiểu hơn, vì vậy tôi cảm thấy như thế này có thể đi theo một trong hai cách.

Ngoài ra, sự khác biệt giữa NA và NULL trong R là gì? ? NA và? NULL cho tôi biết rằng "NA" có độ dài "1" trong khi NULL có độ dài là "0" - nhưng có nhiều hơn ở đây không? Hoặc một thực hành tốt nhất? Điều này sẽ ảnh hưởng đến phương pháp nào tôi sử dụng để tạo ma trận của mình.

+1

Không được hỏi, tại sao bạn muốn * lặp * qua các phần tử của ma trận? Có thể bạn có thể sử dụng một hoạt động vectorized thay thế? Đó sẽ là câu hỏi tiếp theo của bạn ở đây! :) – Harlan

+0

@ Harlan đó là cơ bản những gì tôi nhận được trong câu hỏi này ở đây: http://stackoverflow.com/questions/1719447/outer-equivalent-for-non-vector-lists-in-r. Nếu bạn có một gợi ý, tôi rất muốn nghe nó! – poundifdef

Trả lời

44

Khi nghi ngờ, hãy tự kiểm tra. Cách tiếp cận đầu tiên dễ dàng hơn và nhanh hơn.

> 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 

Về sự khác biệt giữa NA và NULL:

Có thực sự bốn hằng số đặc biệt.

Ngoài ra, có bốn hằng số đặc biệt, NULL, NA, Inf và NaN.

NULL được sử dụng để biểu thị đối tượng trống. NA được sử dụng cho các giá trị dữ liệu không có sẵn ("Không khả dụng"). Inf biểu thị vô cùng và NaN không phải là một số trong phép tính điểm nổi IEEE (kết quả của các phép toán tương ứng 1/0 và 0/0, chẳng hạn).

Bạn có thể đọc thêm trong the R manual on language definition.

+0

huh, cũng không biết về system.time. cảm ơn bạn rất nhiều! – poundifdef

+0

Nếu bạn đang so sánh các phương pháp không nên bạn đã bọc cả hai phương thức trong một hàm? Có phí được thêm vào với cuộc gọi hàm. – Dason

+0

@ Dason Trong thực tế, nếu một người sử dụng phương pháp dài hơn thường xuyên, có lẽ nó sẽ không được bọc trong một chức năng? Trong khi 'ma trận' sẽ vẫn như cũ. – Gregor

3

Theo số this article chúng tôi có thể làm tốt hơn so với preallocating với NA bằng cách preallocating với NA_real_. Từ bài viết:

ngay sau khi bạn chỉ định giá trị số cho bất kỳ ô nào trong 'x', ma trận trước tiên sẽ phải bị ép buộc thành số khi giá trị mới được gán. Ma trận logic được phân bổ ban đầu được cấp phát vô ích và chỉ thêm một dấu chân bộ nhớ không cần thiết và công việc bổ sung cho bộ thu gom rác. Thay vào đó hãy phân bổ nó bằng cách sử dụng NA_real_ (hoặc NA_integer_ cho số nguyên)

Như đã đề nghị: hãy thử nghiệm nó.

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 

Và đối với số nguyên:

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 

Sự khác biệt là nhỏ trong các trường hợp thử nghiệm của tôi, nhưng nó ở đó.

+1

'3' là của lớp' số' bạn có thể có nghĩa là 3L. Tuy nhiên tôi không thấy bất kỳ tác động hiệu suất đo lường nào khi sử dụng chỉ NA (ngay cả khi đo 20 giây và đảm bảo gc thực hiện công việc của mình) –

0
rows<-3 
cols<-3  
x<-rep(NA, rows*cols) 
x1 <- matrix(x,nrow=rows,ncol=cols) 
Các vấn đề liên quan