多くの言語には、存在しない値を表すためにnullやnoneといった仕組みがあります。Rは大量の(しばしば乱雑な)データを扱うように設計されているため、何もなさを表す形がいくつも用意されています。
全体のねらいは、欠けている値や疑わしい値を見つけたらそれに印を付け、例外を発生させずに処理を続けることです。
値が本当に存在しない場合は、NULLで表します。これはおそらく、CやPythonのやり方に最も近いものです。
v <- c() # zero-length vector
v
#> NULL
is.null(v)
#> [1] TRUE
多くの場面で、NULLの値は単に無視されます。
c(2, 3, NULL, 5)
#> [1] 2 3 5
値は存在するものの、それが何なのかわからないという状況では、NAを使います。たとえば、道路を走る車を数えるとき、人間の観測者が病気で休んだり、自動センサーが故障したりすることがありますが、交通の流れは続いています。
v <- c(1, 2, NA, 4, 5)
v
#> [1] 1 2 NA 4 5
is.na(v) # test for data gaps
#> [1] FALSE FALSE TRUE FALSE FALSE
このように、NAはプレースホルダーであり、これをどう扱うかを決める必要があると人間に警告します。
統計関数は通常、NAの値が含まれていると、既定でNAを返します。これらの値を無視したい場合は、na.rm(NA remove)の入力を使って、そのことを明示します。
v <- c(1, 2, NA, 4, 5)
mean(v)
#> [1] NA
mean(v, na.rm = TRUE)
#> [1] 3
「Not a Number」の略で、NaNは、数値が期待される場面で計算に問題が起きたことを示します。
n <- c(0, 2, 4)
d <- c(0, 1, 2)
n / d
#> [1] NaN 2 2 # 0/0 is mathematically undefined
is.nan(n / d)
#> [1] TRUE FALSE FALSE
「無効な」計算の結果は、これだけではありません。0で割ると、分子が0でなければ、エラーを発生させずにInfまたは-Infを返します。
1 / 0
#> [1] Inf
意外に思われるかもしれませんが、Rには空かどうかを調べる標準的な方法がありません。ただし、一部のサードパーティパッケージはis.empty()のような独自の関数を実装しています。
空のベクトルを生成することさえ、それほど自明ではありません。引数なしのc()は、ベクトルではなくNULLを返すことは、前のセクションで見ました。
is.vector(c())
#> [1] FALSE
logical()やinteger()といった関数では、希望する長さを指定します。長さには0も指定できます。
z <- logical(0)
is.vector(z)
#> [1] TRUE
length(z)
#> [1] 0
ベクトルの概念で説明したように、ベクトルを生成してからすべての要素を削除することもできます。すると、適切な型の長さ0のベクトルになります。
v <- 5
v[-1] # delete the first element
#> numeric(0)