[R]文字列型ベクトルの文字列を簡単にテキストファイルに高速で書き込む
標準で搭載されているwrite関数やwrite.table関数を使ってもよいが、readrパッケージのwrite_delim関数、data.tableパッケージのfwrite関数を使うと、書き込む速度が断然速いため、こちらの使用を推奨する。ただし、デフォルトの動作やオプションの指定が関数によって異なるので注意。
以下は、write関数、write.table関数、write_delim関数、fwrite関数でそれぞれ文字型ベクトルの中身をファイルtemp.txtに書き込んだ例。最初に1回書き出した後に、それぞれ2回ずつ、書き込みに要した時間をsystem.time関数で計測している。Windows環境で文字符号化方式はUTF-8で行っている。UTF-8では漢字は一文字当たり3バイト。改行コードはCR+LFで、100万行出力しているため、ファイルサイズが(16×3+2)×10^6=50,000,000バイト≒47.7MBのファイルを出力している。
> .Platform$OS.type
[1] "windows"
> Sys.getlocale("LC_CTYPE")
[1] "Japanese_Japan.utf8"
> library(data.table)
> library(tidyverse)
> tempfile <- "temp.txt"
> s <- "アストラ役の遠藤綾さん、かわいい"
> s <- c(s, "ヴィタ役の日笠陽子さん、かわいい")
> s <- c(s, "松雀役の高森奈津美さん、かわいい")
> s <- c(s, "リフ役の瀬戸麻沙美さん、かわいい")
> nchar(s)
[1] 16 16 16 16
> ss <- sample(s, 10 ^ 6, replace = TRUE)
> length(ss)
[1] 1000000
> head(ss)
[1] "リフ役の瀬戸麻沙美さん、かわいい" "松雀役の高森奈津美さん、かわいい"
[3] "アストラ役の遠藤綾さん、かわいい" "松雀役の高森奈津美さん、かわいい"
[5] "リフ役の瀬戸麻沙美さん、かわいい" "リフ役の瀬戸麻沙美さん、かわいい"
data.tableパッケージのfwrite関数を使用した例。書き込む文字列をベクトルで与えることはできないため、データフレームに変換して引数に与えている。
> dtf <- data.frame(ss)
> fwrite(dtf, tempfile, col.names = FALSE, showProgress = FALSE)
> sprintf("%d", file.info(tempfile)$size)
[1] "50000000"
> system.time(
+ fwrite(dtf, tempfile, col.names = FALSE, showProgress = FALSE)
+ )
ユーザ システム 経過
0.04 0.02 0.03
> system.time(
+ fwrite(dtf, tempfile, col.names = FALSE, showProgress = FALSE)
+ )
ユーザ システム 経過
0.05 0.05 0.05
readrパッケージのwrite_delim関数を使用した例。同様にベクトルを扱えないため、データフレームに変換して引数に与えている。
> dtf <- data.frame(ss)
> write_delim(dtf, tempfile, col_names = FALSE, progress = FALSE, eol = "\r\n")
> sprintf("%d", file.info(tempfile)$size)
[1] "50000000"
> system.time(
+ write_delim(dtf, tempfile, col_names = FALSE, progress = FALSE, eol = "\r\n")
+ )
ユーザ システム 経過
0.24 0.21 0.19
> system.time(
+ write_delim(dtf, tempfile, col_names = FALSE, progress = FALSE, eol = "\r\n")
+ )
ユーザ システム 経過
0.36 0.36 0.14
write_table関数を使用した例。
> write.table(ss, tempfile, row.names = FALSE, col.names = FALSE, quote = FALSE)
> sprintf("%d", file.info(tempfile)$size)
[1] "50000000"
> system.time(
+ write.table(ss, tempfile, row.names = FALSE, col.names = FALSE, quote = FALSE)
+ )
ユーザ システム 経過
1.03 0.06 1.11
> system.time(
+ write.table(ss, tempfile, row.names = FALSE, col.names = FALSE, quote = FALSE)
+ )
ユーザ システム 経過
0.94 0.06 1.03
write関数を使用した例。
> write(ss, tempfile)
> sprintf("%d", file.info(tempfile)$size)
[1] "50000000"
> system.time(
+ write(ss, tempfile)
+ )
ユーザ システム 経過
1.32 3.17 4.58
> system.time(
+ write(ss, tempfile)
+ )
ユーザ システム 経過
1.34 3.32 4.72
2回しか試行していないものの、書き込む速度は、おおよそfwrite関数、write_delim関数、write_table関数、write関数の順に早いことがわかる。
