R でのデータインポート: 高速・正確・再現可能な読み込み
問題
ファイル読み込みの遅さや文字化けが、分析が始まる前にプロジェクトを頓挫させてしまう。チームは CSV や Excel ファイルが届くたびに、毎回インポートコードを書き直す羽目になっている。
問題の深刻化
エンコーディング設定が誤っていると非 ASCII 文字が壊れ、ID から先頭ゼロが消え、大きな CSV はメモリを圧迫する。実行のたびに結果が変わることで、データセットへの信頼は失われ、モデリングやレポーティングの開始がどんどん遅れていく。
解決策
用途別に設計された R のリーダー関数を使い、ロケール・区切り文字・型を明示的に制御する。以下のパターンを使えば、読み込みは高速で、型は安定し、マシンが変わっても再現可能なインポートが実現できる。
CSV と TSV: readr のデフォルト + ロケールの明示
library(readr)
orders <- read_csv(
"data/orders.csv",
locale = locale(encoding = "UTF-8", decimal_mark = ".", grouping_mark = ","),
col_types = cols(
order_id = col_character(),
order_date = col_date(format = "%Y-%m-%d"),
revenue = col_double(),
region = col_character()
)
)col_typesを指定して、R が勝手に factor を推測したり ID をトリムしたりしないようにする。- タブ区切りファイルには
read_tsv()、セミコロン区切りにはread_delim(delim = ";")を使う。
Excel: xls/xlsx には readxl
library(readxl)
budget <- read_excel(
"data/budget.xlsx",
sheet = "FY24",
range = "A1:G200",
col_types = c("text", "numeric", "numeric", "date", "text", "numeric", "numeric")
)readxlは Java を必要とせず、セルのフォーマットを安定して扱える。skip =でヘッダ行を間引き、rangeで必要な範囲だけを読むことで高速化できる。
大きな CSV: data.table::fread
library(data.table)
clicks <- fread(
"data/clicks.csv",
encoding = "UTF-8",
colClasses = list(character = "user_id"),
nThread = 4
)- 区切り文字は自動検出されるが、必要なら
sep = "\t"のように上書きできる。 select =を使って必要な列だけ読み込めば、メモリ消費を抑えられる。
列指向 & 多言語データ: arrow
library(arrow)
events <- read_parquet("data/events.parquet", as_data_frame = TRUE)
# 大規模データセットをバッチでストリーミングする場合
ds <- open_dataset("s3://bucket/events/") # ローカルのフォルダにも同様に使える
events_summary <- ds %>%
filter(country %in% c("DE", "FR")) %>%
group_by(country) %>%
summarise(count = n())- Arrow は型を保持し、デフォルトで UTF-8 を扱う。
- Python/SQL エンジンとの相互運用や、メモリに載せきれないデータのフィルタリングに向いている。
エンコーディングと区切り文字の扱い
- 多言語データでは常に
encodingを明示し、可能ならエンドツーエンドで UTF-8 を採用する。 - ヨーロッパ圏の CSV では、
locale(decimal_mark = ",", grouping_mark = ".")を指定する。 - 区切り文字が一定でない場合は、
read_delim(..., n_max = 20)で一部だけ読み、パース結果を確認する。
簡易ベンチマーク(100 万行・8 列・SSD)
| Reader | File type | Approx. load time | Memory footprint | Notes |
|---|---|---|---|---|
data.table::fread | CSV | 約 3–4 秒 | 低 | フラットファイルで最速クラス。型推測も良好。 |
readr::read_csv | CSV | 約 6–8 秒 | 低〜中 | パースエラーが分かりやすく、ロケール制御が優秀。 |
arrow::read_parquet | Parquet | 約 2–3 秒 | 低 | 列指向。遅延フィルタリングや複数ファイルのデータセットに対応。 |
readxl::read_excel | XLSX | 約 8–12 秒 | 中 | ビジネス用途のワークブックに最適だが、非常に横に広いシートではやや遅い。 |
時間はハードウェアによって変わるため、この表は相対的な目安として扱う。
再現可能なインポートのチェックリスト
col_typesやcolClassesで列型を固定する。localeとencodingを明示し、見えない文字化けを防ぐ。- スキーマは「薄く」保ち、インポート時に不要な列は落とす。
- 読み込み後すぐに
nrow()とsummary()を記録し、異常を早期検知する。
関連ガイド
- インポート後の整形: R dplyr Data Wrangling Pipeline
- クイックプロットレシピ: R ggplot2 Quickstart
- 手作業で tidy なデータフレームを作る: How to Create a Dataframe in R