Menu

R の作業ディレクトリ: setwd()、getwd()、ワークスペースの消去

R がファイルを探す場所とその制御方法: getwd()、setwd()、list.files()、rm(list = ls()) による環境の消去、そして .RData の自動保存が罠である理由。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

作業ディレクトリとは何か

すべての R セッションはちょうど 1 つのフォルダ「の中で」動きます。それが 作業ディレクトリ です。相対パス — ファイルシステムのルートから始まらないパス — を使うたびに、R はそのフォルダを基準に解決します。read.csv("data.csv") は「このコンピュータのどこかから data.csv を探して」という意味ではありません。「作業ディレクトリの中の data.csv というファイルを開いて」という意味です。

この 1 つの事実が、R で最もよくある初心者のエラーを説明します。

read.csv("data.csv")
# Error in file(file, "rt") : cannot open the connection
# In addition: Warning message: cannot open file 'data.csv': No such file or directory

ファイルは存在します — ただ、R が今見ているフォルダにないだけです。あなたの read.csv の呼び出し に問題はありません。セッションの作業ディレクトリとファイルの場所が食い違っているのです。以下の 2 つの関数は、この謎を 10 秒の診断に変えます。

getwd() と setwd()

getwd()(get working directory)は、R が今どこを見ているかを教えてくれます。

これを実行すると絶対パスが表示されます — このセッションが根を張っているフォルダです。setwd()(set working directory)はそれを変更します。

setwd("C:/Users/rosa/projects/sales-analysis")   # Windows: use / not \
setwd("/Users/rosa/projects/sales-analysis")     # macOS / Linux
getwd()                                          # confirm it took

機械的な注意が 2 点あります。Windows ではパスを /(または \\ の二重)で書きましょう — 単独の \ は R の文字列内でエスケープ文字なので、"C:\Users" は構文エラーになります。また setwd() はフォルダが存在しない場合すぐエラーになりますが、これはその日いちばん親切な失敗です。間違った場所を黙って指したままにさせられることがありません。

したがって、あらゆる「cannot open file」エラーのデバッグ手順はこうです。getwd() で R がどこを見ているかを確認し、ファイルが実際にある場所と比べる。

list.files(): R に見えているものを見る

道具箱の 3 つ目は、作業ディレクトリの中身 — 文字どおり相対パスで到達できる名前の集合 — を列挙します。

読み込もうとしているファイルがその出力に現れるなら、read.csv("thatfile.csv") はそれを見つけます。現れないなら、read.csv の行を何度打ち直しても無駄です — 直すべきは作業ディレクトリです。list.files("data") はサブフォルダを覗き、list.files(pattern = "\\.csv$") は CSV だけに絞り込みます。ファイル名が 正しく見える のに見つからないとき、list.files() は典型的な犯人も暴きます。テキストエディタが付け足した見えない .txt 拡張子や、大文字小文字を区別するシステムでの Data.csvdata.csv の違いです。

決め打ちの setwd() が壊れる理由

ここからは主張のある部分です。次のような行で始まるスクリプトを目にすることがあるでしょう。

setwd("C:/Users/me/Desktop/stuff/project3/final_FINAL")

この行が動くのはちょうど 1 台のマシン、つまり著者のマシンだけです。あなたのノート PC、同僚の Mac、部門のサーバー、あるいは整理し直した後の自分のコンピュータでは、1 行目でエラーになります。絶対パスの決め打ちは、それより長生きするはずのコードに、ある 1 人のフォルダ構成を焼き付けてしまいます。

対処は責任を反転させることです。スクリプトにフォルダを探させるのではなく、正しいフォルダで R を起動し、スクリプトの中では相対パスを使いましょう。 具体的には次のとおりです。

  • RStudio プロジェクトを使う。 .Rproj ファイルを開くと、どのマシンでも作業ディレクトリが自動的にプロジェクトフォルダに設定されます。スクリプトの中の read.csv("data/sales.csv") は、そのプロジェクトを持つ全員で動きます。
  • ターミナルから実行する ことも同じ役割を果たします。Rscript analysis.R は起動したフォルダを作業ディレクトリとして使います(R スクリプトの実行 を参照)。
  • here パッケージは望む人向けにもう一歩進みます — here::here("data", "sales.csv") は作業ディレクトリがどこへ迷い込んでいてもプロジェクトのルートからパスを組み立てます — が、プロジェクト+相対パスでたいていの需要はそれなしで満たせます。

setwd() 自体が悪なのではありません。探索中の対話的な使い方なら問題ありません。臭うのは、共有されるスクリプトの先頭にコミットされた、マシン固有の絶対パスによる setwd() です。

ワークスペース: ls() と rm()

「自分は今どのフォルダにいるか」と並ぶ、セッション状態のもう 1 つの要素が ワークスペース(グローバル環境)です — このセッションで作成したすべてのオブジェクトです。ls() が列挙し、rm() が削除します。

最後の ls()character(0) を表示します — 空のワークスペースです。rm(list = ls()) という呪文は、読み解くまでは奇妙に見えます。ls() はすべてのオブジェクト名からなる文字列ベクトルを返し、rm(list = ...) はそのベクトルのすべての名前を削除します。RStudio の Environment ペインにあるほうきのアイコンのコード版です。

これが しない ことも知っておきましょう。library() で読み込んだパッケージは読み込まれたまま、オプションも設定されたまま、作業ディレクトリもそのままです。消去するのはオブジェクトだけです — したがって、本当に真っさらな状態にしたいときの R の再起動の代わりにはなりません。

コンソールの消去と .RData の罠

コンソール(コマンドと出力のスクロールバック)の消去は見た目だけの話で、ワークスペースの消去とは別物です。RStudio では Ctrl+L、コードでは風変わりな cat("\014") がフォームフィード文字を送り、ほとんどのコンソールがそれを「画面を消去」と解釈します。どちらもオブジェクトには触れません。

最後に罠です。R を終了すると「save workspace image?」と尋ねられます — すべてのオブジェクトを隠しファイル .RData に書き出し、次にそのフォルダで R を起動すると黙って再読み込みされる仕組みです。断り、そして恒久的に無効化しましょう(RStudio: Tools → Global Options → 「Restore .RData」のチェックを外し、「Save workspace」を Never に設定)。ワークスペースが復元されるということは、セッションが何日も前のオブジェクト — その後編集したり削除したりしたかもしれないコードが作ったもの — で汚染された状態で始まることを意味します。スクリプトは動いている ように見えます — ファイル内のどこも作っていない古い model_v2 に寄りかかっているからです — が、クリーンなマシンで走らせた瞬間に崩壊します。

プロの習慣は逆です。クリーンな状態から始め、スクリプトを再実行しましょう。 分析が、新しいセッションで上から下まで走るスクリプトになっているなら、それは構造上再現可能です。ワークスペースは使い捨ての出力であって、大事に守るべき状態ではありません。スクリプトが今も独立して成り立つことを証明するために、R をこまめに再起動しましょう(RStudio: Session → Restart R)。

この記事のまとめ

  • 相対パスは作業ディレクトリを基準に解決されます。getwd() で確認し、setwd() で変更し、list.files() で到達できるものを見ます。
  • 「cannot open file」はほぼ常に、作業ディレクトリとファイルのフォルダの食い違いです — getwd()list.files() で診断しましょう。
  • 共有スクリプトに絶対パスの setwd() をコミットしてはいけません — RStudio プロジェクト(またはそのフォルダからのスクリプト実行)と相対パスを使いましょう。
  • ls() はワークスペースのオブジェクトを列挙し、rm(x) は 1 つを削除し、rm(list = ls()) はすべて消去します — パッケージとオプションはそのままです。
  • Ctrl+L(または cat("\014"))はコンソールの表示だけを消去します。
  • .RData の自動保存・復元は避けましょう。クリーンな状態から始めてスクリプトを再実行する — それが作業を再現可能にします。

次は 実データの読み込み — R が正しいフォルダを見るようになった今、read.csv() とその仲間たちを見ていきます。

よくある質問

R で作業ディレクトリを設定するにはどうすればよいですか?

変更するには setwd("path/to/folder") を、現在の場所を確認するには getwd() を呼びます。RStudio ではメニューからも設定できます: Session → Set Working Directory。ただし再実行したり共有したりするものでは、setwd() を決め打ちするより RStudio プロジェクト(作業ディレクトリを自動で設定します)を使いましょう — 絶対パスは他のマシンでは必ず壊れます。

R で環境を消去するにはどうすればよいですか?

rm(list = ls()) はグローバル環境からすべてのオブジェクトを削除します。ls() がすべてのオブジェクト名を列挙し、rm() がそれらを削除します。1 つだけ削除するには rm(x) を使います。これはオブジェクトだけを消去する点に注意してください — 読み込んだパッケージは読み込まれたままで、コンソールの表示にも触れません(それは RStudio では Ctrl+L です)。

ファイルが存在するのに read.csv が 'cannot open file' と言うのはなぜですか?

R は相対パスを作業ディレクトリを基準に解決しますが、そのディレクトリがファイルのあるフォルダとは別の場所を指しているからです。getwd() で R がどこを見ているかを確認し、list.files() でそこから何が見えるかを確認しましょう。直し方は、スクリプトに絶対パスを貼り付けることではなく、正しいフォルダでプロジェクトを開く(あるいは setwd() する)ことです。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める