2011-08-24 8 views
15

リストのNULL値が時々trip人になることがあります。特定のインスタンスでlapplyrapplyNULLの値を異なる方法で扱うように見えるのはなぜかと私は不思議です。rapplyとlapplyはなぜNULLを異なる方法で扱うのですか?

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

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

$c 
[1] TRUE 

$d 
[1] FALSE 

これまでのところとても良いです。 rapplyと全く同じことをすればどうですか?

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

$c 
list() 

$d 
[1] FALSE 

この例は非常に単純かつ非再帰的ですが、ネストされたリストとrapplyで同じ動作を参照してください。

私の質問はなぜですか? ?rapplyで宣伝されているように、それが 'lapplyの再帰的なバージョン'である場合、なぜこのように動作するのでしょうか?

答えて

18

私はあなた自身の質問に答えたと思います。それは再帰的なものだからです。

あなたは、多くの場合、これを見ていないが、それは(スキーム中()リストを終了する方法と似ています。内部的には、Rのような非常にスキームである)空pairlistあるのでNULLは、実際には、空のシーケンスを示すために使用することができます。

したがって、rapplyは空のリストに再帰しますが、完了したらペアリストに戻すのは面倒ではありません。あなたは通常の空のリストを取得します。

> lapply(NULL, identity) 
list() 

をそして、あなたは、これは正確にpairlistsが動作するように意図されている方法であることをRのソースコード(memory.c)で見ることができます:

実は、rapplylapplyは本当に違っNULLを扱うことはありません

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「NULL」は空の 'pairlist'であることを指摘しています。だから、 'rapply'は' NULL'と 'pairlist()'を区別することはできません。 – joran

+1

@joran '同一(pairlist()、NULL)' :) – Owen

関連する問題