このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

NULLと「存在しない」は違うんだってば!

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) で回避できますが、「特殊だが単なるデータ」「存在しないこと」という異なる解釈を混ぜているので、他にもホコロビは出るでしょう。だから、最初から表示的意味論が必要なんですよ。