null, nil, noneとかの特殊な値は、しっかりした意味論と使用法を決めておかないと、ほんとにロクでもないことになります。
R言語のNULLは、さほど明確な意味論を持たず、「なんにもないことを表す値」程度で割と安易に使用されています。的確な値を決めかねるときのデフォルト値とかによく使われます。NULLに関する整合しない解釈と使用法で困った事態に出会いました。
Rの関数list()は、リストを作るコンストラクタ関数です。list()は、NULLを通常のデータとして扱います。
> listA <- list(1, 2, NULL, "hello") > listA [[1]] [1] 1 [[2]] [1] 2 [[3]] NULL [[4]] [1] "hello" >
リストのi番目の成分(要素)には、listA[[i]] のようにしてアクセスします。listA[i] もありますが、これは別な意味なので今は使いません。ちなみに、番号iは1から始まります。
> listA[[1]] [1] 1 > listA[[2]] [1] 2 > listA[[3]] NULL > listA[[4]] [1] "hello" >
リストのi番目の成分を変更するには、listA[[i]] <- value という形を使います。
> listA[[2]] <- 100 > listA [[1]] [1] 1 [[2]] [1] 100 [[3]] NULL [[4]] [1] "hello" >
listAの2番目の値をNULLにしましょう。
> listA[[2]] <- NULL > listA [[1]] [1] 1 [[2]] NULL [[3]] [1] "hello" >
えっ!? 長さが3になってしまった。
> listA[[2]] <- NULL > listA [[1]] [1] 1 [[2]] [1] "hello" >
あらっ、もっと短くなった。
リストの成分にNULLを代入すると、その成分をリストから削除する、という仕様なんです。「NULLは存在しないことを表す」という解釈による操作ですが、リストの成分にNULLを入れるなんて普通のことなので、整合性がなくミスをしやすい状況となっています。
とりあえずここは、listA[2] <- list(NULL) で回避できますが、「特殊だが単なるデータ」「存在しないこと」という異なる解釈を混ぜているので、他にもホコロビは出るでしょう。だから、最初から表示的意味論が必要なんですよ。