メインコンテンツにスキップ

読み込み済みのデータの型を再度推定する

read.csv()の内部の型推定は type.convert() で行われている
R
公開

2026年11月7日

Rはファイルを読み込むときに、変数型の推定をしてデータフレームを作っています。このとき、実数として扱いたい列に数値として変換できない文字が1つでも混ざっていると、その列は丸ごと文字列型として推定されます。

その場合の基本手順は、列を数値変換できる値になるように加工した上で、as.double() などで型を変換することです。ただ、実際には列ごとに細かく加工しなくても、文字を含む数行だけ削除すれば十分なこともあります。その場合に困るのは実数型への変換です。なぜなら、 列によって実数にしたいか文字列のままにしたいかが異なるので、一括でループを回せない からです。

そこで、一括ループではなく「ファイル読み込みのように、データフレームを列ごとに適切に変換する処理」を行えると便利です。この記事では、その方法を紹介します。

実数に変換できない列が残る問題

例として、実数にしたいはずの列に文字が混ざっているデータがあるとします。

example <- matrix(
  c("A-01", "ページビュー", "100", "200",
  "A-02", "イベント数", "2500", "300",
  "A-03", "継続割合", "0.8", "0.2",
  "B-01", "参照", "N/A", "ok"),
  ncol = 4
)
example
     [,1]           [,2]         [,3]       [,4]  
[1,] "A-01"         "A-02"       "A-03"     "B-01"
[2,] "ページビュー" "イベント数" "継続割合" "参照"
[3,] "100"          "2500"       "0.8"      "N/A" 
[4,] "200"          "300"        "0.2"      "ok"  

2行目に説明のための行が入っているため、全ての列が文字列型になってしまいます。

一括でループを回せない(列ごとに型が異なる)

2行目だけを削除した後、as.double()で実数型にしようとすると、列をそれぞれ指定する必要が出てきます。A-01〜A-03は実数型にしてよいですが、B-01は文字列のままにしたいからです。そのため全ての列を一括で変換することができませんが、列ごとの分岐を書くのも面倒です。

このようなとき、read.csv() がやっているような「列ごとに型を判断する変換」ができると便利です。

読み込み時の型推定を流用する

そこで、単純に「再度read.csv()を実行すればよい」という発想から、加工済みのデータを一時ファイルに書き出し、read.csv() で読み直すという方法が思い付きます。

example_df <- read.csv("文字を含むデータ.csv")
chr_df <- example_df[-1, ]  # 1行目を削除(ヘッダーを含む実際のデータでは2行目)

temp <- tempfile()  # Rのtempフォルダに一時ファイルを作成
write.csv(chr_df, temp, row.names = FALSE)
type_df <- read.csv(temp)

ところがこの方法だとデータと同じサイズの一時ファイルができてしまいますし、ファイル入出力を繰り返すのも効率が悪いので、もっと良いやり方がありそうです。

type.convert() で型推定を行う

実はファイル読み込み時の型推定は type.convert() が行っています。この関数はベクトルやデータフレームに対して列ごとに型を推定するので、加工済みのデータに対してそのまま呼ぶことができます。

type_df <- type.convert(chr_df, as.is = TRUE)

全要素が数値に変換できる列は numeric に、それ以外は character のままで返ります。as.is = TRUE にすると文字列は character のままになり、FALSEにするとfactorになります。(指定しないと警告が出ます)。

NA という文字は既定で NA に変換されますが、N/A のような表記は対象外です。それらをも欠損として扱いたい場合は na.strings 引数で指定できます。

type.convert(chr_df, na.strings = c("NA", "N/A"), as.is = TRUE)

変換後の型は str() で確認する

type.convert() の結果は列ごとの値に依存するため、変換後の型は必ず確認するのがおすすめです。

type_df <- type.convert(chr_df, as.is = TRUE)
str(type_df)

Rに列ごとの変換を任せられるのは便利ですが、意図しない型の推定が行われるリスクが伴います。

  • 2026-01-01 のような日付文字列は Date に推定されず、character のまま
  • 00123 のような先頭に0を持つ文字列は numeric になり、0 が失われる
  • 1e5 のような指数表記も numeric になる
  • 全要素が TRUE や FALSE の場合、logical になる

データを読み込むときの基本ではありますが、意図しない推定が行われていないか常に確認しましょう。

まとめ

read.csv()の内部では型推定をtype.convert()で行っています。メモリ上のデータフレームの型を直したいときは、列ごとに型変換コードを書くのではなく、type.convert() で丸ごと処理するのが簡単です。

特に、いったんRにデータを取り込んでから行削除などして使いたい場合には有用です。似たような場面が出てきたら、使ってみてはいかがでしょうか。