
カテゴリカル変数って数値に変換できないの?
とあるアンケートを実施したのですが、回答データの「性別」「年代」などのいわゆる数値ではないカテゴリカル変数を、数値に変換する方法がまったく分からず、手間取ってしまいました。
数値ではない場合には、ヒストグラムを作成するのにもエラーで返ってきてしまいます。
Error in hist.default(dataset$age) : 'x' must be numeric
そんなわけで今回は、データの中のcharacter型の値を、numeric型の数値に変換する方法をお伝えしていきます。
今回はdatasetというデータの中のageというカラムを使って説明しています。
課題:character型をnumeric型に変換したい
例えば、以下のような数値ではない文字列をどう数値に置き換えるべきなのか。


文字列のままヒストグラムを作ろうとしても、返ってくるのは以下のようなエラーだけです。


エラーの内容にも書いているとおり、numeric型にする必要があるようです。
as.numericを使うとすべての値がNAになる
ここでsummary関数でデータの要約を見てみます。


character型であることが確認できました。
検索で調べてみると、numeric型に変換するためには、as.numericという関数を使うとのことで試してみます。


しかし全ての値がNAになってしまいました。
結論としては、2つの手順を踏むことで、無事にnumeric型に変更ができました。
step1:まずはcharacter型をnumeric型に変換
まずはfactor型に変換
まずはcharcter型をfactor関数を使い、factor型に変換します。
dataset$age <- factor(dataset$age,levels=c("10代","20代","30代","40代","50代","60代","70代以上"))


factor型になると、levels関数でfactorを取り出すことが可能です。確認してみましょう。
levels(dataset$age)
そうすると以下のようなレスポンスが返ってきました。


factor型に変更しないとlevels関数を使ってもNULLが返ってくるので注意してください。


これでfactor型になっていることが確認できました。
ちなみにfactor型は配列の順番を考慮する型なので、そこだけ注意してください。
またclass関数でも型だけを確認することもできます。
今回の場合だと、以下です。
class(dataset$age)
step2:変換したfactor型を、numeric型の数値に置き換える
文字列をどう数値に置き換えるか分かりやすく、mappingという変数に情報を入れていきます。
当たり前ですが、変更前は文字列(factor型)、変更後にはnumeric型になるよう数値を入れていきます。
mapping <- c("10代"=1, "20代"=2, "30代"=3, "40代"=4, "50代"=5, "60代"=6, "70代以上"=7)


準備ができたので、いよいよfactore型をnumeric型に置き換えていきます。
dataset$age <- as.numeric(dataset$age,mapping)


実際に変更ができているか確認してみましょう。





やった年代がnumeric型に置き換わった!
モザイクで情報を隠していますが、すべて数値に置き換わったのが確認できました。
おつかれさまでした。
参考までにですが、numeric型に変更すると、さきほどまでのlevels関数は使えなくなります。


まとめ
性別や年代のようなカテゴリカル変数がcharacter型の場合は、まずfactor型にしてから、numeric型に変換することでうまく数値に変化することができました。
これだけの処理に数時間もかかってしまったのですが、同じような課題を抱えている方のお役に立てば嬉しいです。
他にもいい処理の仕方があるような気がするのですが、ご存じの場合はご一報いただけたらそれまた嬉しいです。
コメント