始めにヌルを含むCSVファイルを作成する。
> ch1 <- c(0x41:0x43, 0x2c, 0x00, 0x2c, 0x47:0x49, 0x0d, 0x0a)
> ch1 <- c(0x41:0x43, 0x2c, 0x00, 0x2c, 0x47:0x49, 0x0d, 0x0a)
> ch2 <- c(0x61, 0x00, 0x63, 0x2c, 0x64:0x66, 0x2c, 0x67:0x69, 0x0d, 0x0a)
> ra <- as.raw(c(ch1, ch2))
> writeBin(ra, "temp.csv")
ファイルをメモ帳で開くと以下のようになる。1行目の2列目は値自体がヌルで、2行目の1列は「a」と「c」の間は空白(0x20)ではなくヌル(0x00)である。
ABC, ,GHI
a c,def,ghi
標準で搭載されているread.tableは、skipNulオプションにTRUEを指定しないと、ヌルだけの列は列とは認識されず、行によってフィールド数が異なることになるため、エラーが発生して読み込みに失敗する。skipNulオプションにTRUEを指定と、ヌルは完全に無視して他はすべて読み込まれる。ヌルの次の「c」もきちんと読み込まれている。
> dtf <- read.table("temp.csv", header = FALSE, sep = ",")
scan(file = file, what = what, sep = sep, quote = quote, dec = dec, でエラー:
line 2 did not have 2 elements
追加情報: 警告メッセージ:
1: read.table("temp.csv", header = FALSE, sep = ",") で:
line 1 appears to contain embedded nulls
2: read.table("temp.csv", header = FALSE, sep = ",") で:
line 2 appears to contain embedded nulls
> print(dtf)
エラー: オブジェクト 'dtf' がありません
> dtf <- read.table("temp.csv", header = FALSE, sep = ",", skipNul = TRUE)
> print(dtf)
V1 V2 V3
1 ABC GHI
2 ac def ghi
readrパッケージのread_delim関数を試してみる。ヌルだけの列はきちんと処理されているようだが、ヌルを含む列は、ヌル以降は読み込まれていない(「c」が表示されない)。
> library(readr)
> tib <- read_delim("temp.csv", delim = ",", col_names = FALSE, progress = FALSE, show_col_types = FALSE)
警告メッセージ:
One or more parsing issues, call `problems()` on your data frame for details, e.g.:
dat <- vroom(...)
problems(dat)
> print(data.frame(tib))
X1 X2 X3
1 ABC GHI
2 a def ghi
data.tableパッケージのfread関数を使う。これはヌルを完全に無視して読み込むし、ヌルだけの列は空欄(NA)ということで処理できているし、ヌル以降の文字もきちんと読み込まれている。
> library(data.table)
> dtt <- fread("temp.csv", header = FALSE, sep = ",", showProgress = FALSE)
> print(dtt)
V1 V2 V3
1: ABC GHI
2: ac def ghi