HOWTO · R
R で因子を数値に変換する
R の因子を安全に数値ラベルへ変換し、内部コードと値を区別して、無効なラベルを処理する方法を解説します。
このページの内容
因子 f に数値ラベルが含まれ、そのラベルを数値として取得したい場合は、as.numeric(as.character(f)) を使用します。as.numeric(f) を直接呼び出すと、代わりに因子の内部整数コードが返されます。直接変換が適切なのは、そのコードをカテゴリ ID として意図的に使用する場合だけです。
因子に対して as.numeric が返す値を理解する
R の因子は、整数コードと、それとは別の文字列レベルの集合を保持しています。コードは、並べ替えられた順序または明示的に指定された順序でレベルを参照するもので、元の測定値そのものとは限りません。levels() と unclass() を使えば、両方を確認できます。
as.numeric(f) の出力は、2 1 2 3 のようなコード列です。元の値が 2、1、2、3 だったという意味ではありません。数値に見える列がデータフレームに因子として読み込まれた場合、この違いが重要になります。
数値に見える因子ラベルを数値へ変換する
最初に因子を文字列へ変換し、次にラベルを数値へ変換します。
f <- factor(c("3", "2", "3", "4"))
values <- as.numeric(as.character(f))
values
レベルが数値であることが分かっている因子では、as.numeric(levels(f))[f] も効率的な方法です。どちらの方法も内部コードではなくラベルを復元します。先に文字列へ変換する形は通常読みやすく、2 段階の変換が明確です。
小数や負数の数値ラベルも同じように処理できます。インポートまたはデータクリーニングの近くで変換し、計算に使う前に str() や class() で結果を確認してください。
カテゴリラベルを意図どおりに符号化する
ラベルがカテゴリを表す場合、そのコードを測定値として扱わないでください。安定した ID が必要なら、カテゴリの順序を明示的に指定します。
grade <- factor(c("low", "high", "low"), levels = c("low", "high"))
codes <- as.numeric(grade)
codes
ここで 1 と 2 がカテゴリコードになるのは、順序を明示的に選んだからです。high が low の 2 倍という意味ではありません。業務やモデルに固有の対応付けには、名前付きの参照ベクトルの方が明確です。
grade <- c("low", "high", "low")
score <- c(low = 10, high = 20)[grade]
score
この方法なら各数値の意味が見える形で保たれ、因子レベルの既定の順序に依存しません。
数値でないラベル、欠損値、警告を処理する
文字列を経由する変換でも、任意のラベルを数値にはできません。数値でない文字列は NA になり、R は型変換の警告を出します。元から欠損している値は欠損のままです。
f <- factor(c("12.5", "oops", NA))
values <- as.numeric(as.character(f))
values
is.na(values)
予期しない NA は、データ品質に問題がある可能性を示すものとして扱ってください。元のラベルを確認し、必要に応じて空白を除去または正規化し、分析前に無効なレコードの扱いを決めます。黙ってゼロに置き換えてはいけません。ラベルが数値ではなくカテゴリなら、明示的な対応付けか、順序を明示した因子を使用します。
変換結果を確認する
結果を利用する前に、変換元のクラス、レベル、変換後の値、警告の有無を確認します。要点は次のとおりです。
- 意図した因子コードには
as.numeric(f)を使う。 - 数値ラベルには
as.numeric(as.character(f))を使う。 - カテゴリには明示的な順序または名前付きの対応付けを使う。
- インポートした文字列を変換した後は
NAを確認する。
現在の R コードでは、文字列が因子になるかどうかという過去の既定動作に頼らず、インポート時の型や因子レベルを意図的に指定するべきです。これらを確認することで、各数値結果が何を意味するのかが明確になります。