2011-08-24 5 views
15

Tôi biết rằng các giá trị NULL trong danh sách đôi khi có thể là trip mọi người. Tôi tò mò tại sao trong một ví dụ cụ thể lapplyrapply dường như đối xử với các giá trị NULL khác nhau.Tại sao lại xử lý rapply và lapply NULL một cách khác nhau?

l <- list(a = 1, c = NULL, d = 3) 

lapply(l,is.null) 
$a 
[1] FALSE 

$c 
[1] TRUE 

$d 
[1] FALSE 

Cho đến nay rất tốt. Làm thế nào về nếu chúng ta làm điều tương tự với rapply?

rapply(l, is.null, how = "replace") 
$a 
[1] FALSE 

$c 
list() 

$d 
[1] FALSE 

Ví dụ này rất đơn giản và không đệ quy, nhưng bạn thấy cùng một hành vi trong rapply với danh sách lồng nhau.

Câu hỏi của tôi là lý do tại sao? Nếu, như được quảng cáo trong ?rapply, đó là 'phiên bản đệ quy của lapply', tại sao chúng hoạt động rất khác trong trường hợp này?

Trả lời

18

Tôi nghĩ bạn đã trả lời câu hỏi của riêng bạn: bởi vì nó đệ quy.

Bạn không thường thấy điều này, nhưng NULL thực sự có thể được sử dụng để biểu thị một chuỗi trống, vì nó là trống pairlist (tương tự như cách () trong Đề án chấm dứt danh sách. Trong nội bộ, R rất giống nhau).

Vì vậy, rapply đệ quy vào danh sách trống, nhưng không bận tâm khi quay trở lại danh sách cặp khi hoàn thành; bạn nhận được một danh sách trống thường xuyên.

Trên thực tế, rapplylapply không thực sự điều trị NULL mà khác nhau:

> lapply(NULL, identity) 
list() 

Và bạn có thể thấy trong mã nguồn R (memory.c) rằng đây là chính xác có bao pairlists có nghĩa là để làm việc:

SEXP allocList(int n) 
{ 
    int i; 
    SEXP result; 
    result = R_NilValue; 
    for (i = 0; i < n; i++) 
     result = CONS(R_NilValue, result); 
    return result; 
} 
+1

+1 Để chỉ ra rằng 'NULL' là một' danh sách cặp đôi trống '. Vì vậy, có vẻ như bạn đang nói rằng 'rapply' không thể (hoặc không) phân biệt giữa' NULL' và 'pairlist()'. – joran

+1

@joran 'giống hệt nhau (pairlist(), NULL)' :) – Owen