R のデータ読み込み時の問題について
データ分析において、最初に行われることがread.csv関数などを利用したデータの読み込みです。ですが、初学者はその時点でもつまづき、挫折しがちです。 そこで、read.csv関数を用いたデータ読み込みの時点においての、挫折ポイントやエラーについていくつか紹介するとともに、便利なオプションも紹介したいと思います。
- 不正なマルチバイト
- 型について
- 欠損値について
準備
今回は以下のような、購入データのサンプルを使用します。データはsample_purchase_data.csvという名前で保存されているものとします。
日付 | 購入商品 | 購入者ID | 商品ID | 金額 | 購入回数 |
---|---|---|---|---|---|
20170601 | よもぎ饅頭 | 00220101 | aab | 130 | 1 |
20170601 | いちご大福 | 03440101 | aac | 210 | 1 |
20170601 | よもぎ饅頭 | 11020441 | aab | 130 | 2 |
20170601 | みたらしだんご | 13026761 | aaa | データなし | 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 | よもぎ饅頭 | 220101 | aab | 130 | 1 |
20170601 | いちご大福 | 3440101 | aac | 210 | 1 |
20170601 | よもぎ饅頭 | 11020441 | aab | 130 | 2 |
20170601 | みたらしだんご | 13026761 | aaa | データなし | 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 | よもぎ饅頭 | 00220101 | aab | 1 | 1 |
20170601 | いちご大福 | 03440101 | aac | 2 | 1 |
20170601 | よもぎ饅頭 | 11020441 | aab | 1 | 2 |
20170601 | みたらしだんご | 13026761 | aaa | データなし | 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 | よもぎ饅頭 | 00220101 | aab | 130 | 1 |
20170601 | いちご大福 | 03440101 | aac | 210 | 1 |
20170601 | よもぎ饅頭 | 11020441 | aab | 130 | 2 |
20170601 | みたらしだんご | 13026761 | aaa | NA | 1 |
金額を正しい値で、数値に変換することができました。
まとめ
read.csv関数は、パラメーターを適切に指定することでデータを正しく読み込むことができます。 実はread.csv関数のヘルプを見るても指定できるパラメーターは少ないようにみえるのですが、実はread.csv関数はread.table関数の一部パラメーターを指定しているだけなので、どのようなパラメーターがあるかは、read.table関数のヘルプを見ると良いです。
DATUM STUDIOは、クライアントの事業成長と経営課題解決を最適な形でサポートする、データ・ビジネスパートナーです。
データ分析の分野でお客様に最適なソリューションをご提供します。まずはご相談ください。
Contact
Explore Jobs
関連記事