ちょいちょい忘れては調べることになるのでメモ。
一時ファイル
一時ファイルとは一時的なデータを保持しておくファイルで、通常さくっと作られて用が済めば削除されるものです。Rでも自分で準備して利用することが可能で、ちょっとデータなどを預けておいたりするのに重宝します。今回はこれの基本的なところを確認。
tempfile関数とtempdir関数
Rの場合、作成した一時ファイルは一時ディレクトリに置かれます。そしてこの一時ディレクトリはそのRsessinoで準備されています。その一時ディレクトリへのパスを取得する関数がtempdir()
です:
tempdir()
#> [1] "/tmp/RtmpLapPwK"
ルートからのパスはOSや環境に依存しますが、一時ディレクトリ名はRtmp*
という名前になるようです。
では今度は一時ファイルを作成してみたいと思います。一時ファイルを作成する関数はtempfile()
関数です:
tempfile()
#> [1] "/tmp/RtmpLapPwK/file9403432469"
上のtempdir()
で出てきたディレクトリにfile*
というファイルが作成されて、そのファイルへのパスが返ってきます。通常はこのようにするのではなく、返り値をオブジェクトに預けます:
tmpf <- tempfile()
tmpf
#> [1] "/tmp/RtmpLapPwK/file940709780f0"
class(tmpf)
#> [1] "character"
このように預けておくと、このパスを利用してファイル操作ができるようになります:
kosaki <- c("kosaki", "yappari", "saikou!")
writeLines(kosaki, tmpf)
readLines(tmpf)
#> [1] "kosaki" "yappari" "saikou!"
Usage
tempdir()
関数には引数はありません。単に一時ディレクトリのパスを返すのみです。tempfile()
のUsageは以下のとおりです:
tempfile(pattern = "file", tmpdir = tempdir(), fileext = "")
- pattern
- 空ではない文字列ベクトルを指定
- 一時ファイル名の最初の部分がこれになります
- 初期値は"file"なので、上述のように
file*
という名に
- tmpdir
- 空ではない文字列ベクトルを指定
- 一時ファイルを設置するディレクトリ名を指定
- 初期値は
tempdir()
であり、上述した一時ディレクトリに格納される
- fileexit
- 空ではない文字列ベクトルを指定
- 一時ファイルの拡張子を設定
- 初期値は空の文字列で、つまりは拡張子なしのファイル
ということで、内容はシンプルです。ポイントは以下のようなところ:
- 文字列ベクトルを受け付ける、すなわち一度にたくさん作れる
- 一時ファイル名でも
pattern
である程度は付与できる -
.csv
や.txt
、あるいは.html
や.md
などいろいろできる
いろいろ試してみる
てことで遊んでみます。まずは複数作成。
tempfs <- tempfile(paste("kosaki", 1:3, sep = "_"))
tempfs
#> [1] "/tmp/RtmpLapPwK/kosaki_194012d6e993"
#> [2] "/tmp/RtmpLapPwK/kosaki_2940a2bce14"
#> [3] "/tmp/RtmpLapPwK/kosaki_394076b5137c"
文字列ベクトルで与えると、それに合わせて準備してくれました。
次はいろんな拡張子を与えてみます:
tempfs <- tempfile("kosaki", fileext = c("", ".txt", ".csv", ".html"))
tempfs
#> [1] "/tmp/RtmpLapPwK/kosaki9407c1cc7d4"
#> [2] "/tmp/RtmpLapPwK/kosaki9401f98b725.txt"
#> [3] "/tmp/RtmpLapPwK/kosaki9403cda92a8.csv"
#> [4] "/tmp/RtmpLapPwK/kosaki940179b1fe6.html"
こんな感じですね。実用性はほぼ無いですがテストしました。
では、ちょっと長いですが応用です:
# 前準備: 独自でRコードをマークアップした文字列を準備
hoge <- paste(
"最初",
"<s>",
"paste('kosaki', 'No.1')",
"<e>",
"終わり",
"",
sep = "\n"
)
# 手順1: ターゲットを一時ファイルへ格納
tmp <- tempfile(fileext = c(".txt", ".R"))
write(hoge, tmp[1])
# 手順2: 一時ファイルから文字列ベクトルとして読みだす
xx <- readLines(tmp[1])
# 手順3: 読みだした文字列ベクトルからRコードの位置を特定して一時ファイル(.R)へ
chunk_start <- grep("<s>", xx)
chunk_end <- grep("<e>", xx)
r_chunk <- xx[chunk_start:chunk_end]
r_code <- r_chunk[!grepl("<s>|<e>", r_chunk)]
write(r_code, file = tmp[2])
# 手順4: 一時ファイルのコードを評価
out <- eval(parse(tmp[2]))
# 手順5: 出力を元のテキストに埋め込む
finish <- c(
xx[1:chunk_end],
"<out_s>",
print(out),
"<out_e>",
xx[(chunk_end + 1):length(xx)]
)
# 手順6: ファイルとして出力
write(paste(finish, collapse = "\n"), file = "output.txt")
file.copy(paste(tmp[2], collapse = "\n"), "r_code.R")
伝わる人には伝わると思いますが、これはknitをイメージした処理です。実際の処理はもっと細やかにやるものなのですが、あくまで一時ファイルを使った例なのでざっくりやりました。
この一時ファイルはいろんなところで使われていて、パッケージの関数内処理で作成しているとかよく見かけます。ぜひ活用してみてください。
Enjoy!