RTech Blogプログラミング 

R のデータ読み込み時の問題について

データ分析において、最初に行われることがread.csv関数などを利用したデータの読み込みです。ですが、初学者はその時点でもつまづき、挫折しがちです。 そこで、read.csv関数を用いたデータ読み込みの時点においての、挫折ポイントやエラーについていくつか紹介するとともに、便利なオプションも紹介したいと思います。

  1. 不正なマルチバイト
  2. 型について
  3. 欠損値について

準備

今回は以下のような、購入データのサンプルを使用します。データはsample_purchase_data.csvという名前で保存されているものとします。

日付購入商品購入者ID商品ID金額購入回数
20170601よもぎ饅頭00220101aab1301
20170601いちご大福03440101aac2101
20170601よもぎ饅頭11020441aab1302
20170601みたらしだんご13026761aaaデータなし1

また、少しデータを加工するので、以下を実行しておいてください。

install.packages("dplyr")
library(dplyr)

それでは早速、読み込みをしましょう。

不正なマルチバイト

実行と問題

まずは何もオプションに指定せず、読み込んでみましょう。

#データの読み込み
sample_data <- read.csv("sample_purchase_data.csv")

#以下のエラーが出てしまう
make.names(col.names, unique = TRUE) でエラー:
   '<93><95>t' に不正なマルチバイト文字があります

これは、ファイル自体の文字コードと、read.csvが読み込みを予定している文字コードが異なる故に出現するエラーです。

解決方法

Rでは文字コードがOSのデフォルトになるため、Windowsで作成されたSJISのファイルはmacOSで文字コードを指定しないと読み込むことができません。どの文字コードで読み込みたいのか(ファイル自体の文字コード)を指定をすることで解決できます。 read.csv関数では、読み込み時の文字コードは、fileEncodingパラメーターで指定します。

#fileEncoding の後に文字コードを指定
sample_data1 <- read.csv(
  "sample_purchase_data.csv",
  fileEncoding = "SJIS"
  )

型について

実行と問題

まずは、先ほど読み込んだデータの中身を見てみましょう。 購入者IDの先頭にあった0が消えています。それでは、データの各列の型を確認してみましょう。

#中のデータの構成と型を確認
str(sample_data)
日付購入商品購入者ID商品ID金額購入回数
20170601よもぎ饅頭220101aab1301
20170601いちご大福3440101aac2101
20170601よもぎ饅頭11020441aab1302
20170601みたらしだんご13026761aaaデータなし1

購入者IDがint型になっていますね。IDの先頭に0が含まれているような場合、数値として扱われるとその0が消えてしまうという問題が起こることがあるため、character型などで保持していることが望ましいです。

解決方法

読み込み時に各カラムの型を指定してあげましょう。ここではあえて、購入者ID以外の列はデフォルトと同じ形式を指定しています。 read.csv関数では、各カラムの型は、fileEncodingパラメーターで指定します。

#colClassesに、各々のカラムの型を指定しておくと、指定通りの型で読み込まれる
sample_data2 <- read.csv(
  "sample_purchase_data.csv",
  fileEncoding = "SJIS",
  colClasses = c("integer", "factor", "character", "factor", "factor", "integer")
  )

読み込んだ後から型変更することも可能ですが、読み込む時点で型を指定しておく方が、スクリプトがまとまって、すっきりします。

欠損値について

実行と問題

金額列を計算したいので、文字が入っている行を削除し、数値に変換したいと思います。まずは、先ほど型指定をして読み込んだデータの構成と型を確認します。

#文字列が入っている行を除いて、intに変換しようとすると、うまく変換できない
sample_data3 <- sample_data2 %>%
  filter(金額 != "データなし") %>% #金額が入っている行のみを選択
  mutate(金額 = as.integer(金額)) #数値に変換
日付購入商品購入者ID商品ID金額購入回数
20170601よもぎ饅頭00220101aab11
20170601いちご大福03440101aac21
20170601よもぎ饅頭11020441aab12
20170601みたらしだんご13026761aaaデータなし1

なんと、金額列が意図しない値に変化してしまいました。factor型から、integer型に変換しようとするとうまくいかないことが多いです。

解決方法

欠損値に「データなし」という文字列が含まれているため、Rは金額カラムを文字列として認識しています。これを欠損値として認識させる必要があります。 read.csv関数では、欠損値を表現するのには、na.stringsパラメーターを指定します。

#na.stringsを指定して欠損値データをNAにする
sample_data3 <- read.csv(
  "sample_purchase_data.csv",
  fileEncoding = "SJIS",
  colClasses = c("integer", "factor", "character", "factor", "integer", "integer"),
  na.strings = "データなし"
)
日付購入商品購入者ID商品ID金額購入回数
20170601よもぎ饅頭00220101aab1301
20170601いちご大福03440101aac2101
20170601よもぎ饅頭11020441aab1302
20170601みたらしだんご13026761aaaNA1

金額を正しい値で、数値に変換することができました。

まとめ

read.csv関数は、パラメーターを適切に指定することでデータを正しく読み込むことができます。 実はread.csv関数のヘルプを見るても指定できるパラメーターは少ないようにみえるのですが、実はread.csv関数はread.table関数の一部パラメーターを指定しているだけなので、どのようなパラメーターがあるかは、read.table関数のヘルプを見ると良いです。

このページをシェアする:



DATUM STUDIOは、クライアントの事業成長と経営課題解決を最適な形でサポートする、データ・ビジネスパートナーです。
データ分析の分野でお客様に最適なソリューションをご提供します。まずはご相談ください。