アメリエフの技術ブログ

Amelieff Staff Blog

(Rで)ディレクトリやファイルのパスを扱う方法

こんにちは😄

バイオインフォマティクスデータ解析では、統計解析ソフトRは欠かせません。

Rで図を保存するときなどに、ディレクトリやファイルのパスを扱うことがありますね。
最初から使える関数たち(base package)や、追加の fsパッケージでは、そうしたパスについての関数を扱うことができます。
fs パッケージの方は、少し出来ることが多いのと、痒い所に手が届く洗練された設計になっていると感じます。

今回は、活用例を2つ紹介します。

関数の一覧は、fsパッケージのドキュメントで公開されている早見表が便利です。
シェルのコマンドとの対応も書いてあってわかりやすいです。
vignettes | Comparison of fs functions, base R, and shell commands

一部引用

fs base shell
dir_ls("path") list.files("path") ls path
dir_info("path") do.call(rbind, lapply(list.files("path"), file.info)) ls -al path
path("top_dir", "nested_dir", "file", ext = "ext") file.path("top_dir", "nested_dir", "file.ext") top_dir/nested_dir/file.ext

ファイルパスを書くとき、頑張れば文字列操作でも出来ますが、こうしたパス専用の関数を使うとエラーが減って効率的です。
特に自作関数やプログラムを作るときには、途中でエラーが起きるとその後のコードも実行されず終了してしまいます。
なるべくエラーを防ぐようにした方が良いでしょう。

活用例1. ディレクトリを作成する + 条件分岐でエラー回避!

意外と知られていませんが(?)
ディレクトリを作成するには、dir.create() 関数を使います。 (fsパッケージならdir_create()

dir.create("new-dir")

ただし、 new-dirというディレクトリがすでにあるときは、エラーが出てしまいます。

 警告メッセージ: 
 dir.create("new-dir") で:   'new-dir' はすでに存在します 

エラーを防ぐには、あらかじめ同名のディレクトリがないことを確認するとよいですね。

条件分岐を使って以下のように書きます。

if (!dir.exists("new-dir")){
dir.create("new-dir")
}


fs::dir_create() の場合は、同名のディレクトリを作ろうとしてもエラーが出ません。

> fs::dir_create("test")
> fs::dir_create("test")
>  

活用例2. 保存するディレクトリ&ファイル名を指定する

例えば new-dir フォルダの中に Beautiful_plot.pdf を作成したいとき、
保存する相対パスは new-dir/Beautiful_plot.pdf になります。

このように、ディレクトリ とファイル名をくっつけるときに使える関数が

  • file.path()
  • fsパッケージの path()

です。

## 引数のディレクトリ+ファイル名が繋がる
> file.path(output_dir, "Beautiful_plot.pdf")
[1] "new-dir/Beautiful_plot.pdf"
> fs::path(output_dir, "Beautiful_plot.pdf")
new-dir/Beautiful_plot.pdf

## 複数ディレクトリも繋げられる
> file.path(".","new-dir", "Beautiful_plot.pdf")
[1] "./new-dir/Beautiful_plot.pdf"
> fs::path(".","new-dir", "Beautiful_plot.pdf")
./new-dir/Beautiful_plot.pdf

## スラッシュを入れるとこうなる
> file.path("~","Desktop/", "Beautiful_plot.pdf")
[1] "~/Desktop//Beautiful_plot.pdf"
> fs::path("~","Desktop/", "Beautiful_plot.pdf")
~/Desktop/Beautiful_plot.pdf

fs::path() を使うと、引数のディレクトリ文字列の前後にスラッシュを入れたときにもきれいなパスを返してくれるのが file.path との違いのようです。
とはいえ、"~/Desktop//Beautiful_plot.pdf" であっても、取り立てて実害はないように思います。

返り値の型も少し違いますね。

スクリプトの中にいれるとこんな感じです。

output_dir <- "new-dir"

p <- ggplot2::ggplot( #中略 ) 
ggplot2::ggsave(file.path(output_dir, "Beautiful_plot.pdf"), p)

それでは、みなさま良いR生活を🌟


アメリエフでは、バイオデータ解析やそのシステム・インフラ環境の開発に興味のあるエンジニア・リーダー候補を募集しています。

www.wantedly.com