Menu

Рабочий каталог в R: setwd(), getwd() и очистка рабочего пространства

Где R ищет файлы и как этим управлять: getwd(), setwd(), list.files(), очистка окружения через rm(list = ls()) и почему автосохранение .RData — ловушка.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

Что такое рабочий каталог

Каждая сессия R выполняется «внутри» ровно одной папки — рабочего каталога. Всякий раз, когда вы используете относительный путь (путь, не начинающийся от корня файловой системы), R разрешает его относительно этой папки. read.csv("data.csv") означает не «найди data.csv где-нибудь на моём компьютере»; это означает «открой файл с именем data.csv в рабочем каталоге».

Один этот факт объясняет самую частую ошибку новичков в 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 всё в порядке; расходятся рабочий каталог сессии и расположение файла. Две функции ниже превращают эту загадку в десятисекундную диагностику.

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

Две технические заметки. На Windows пишите пути через / (или удвоенный \\) — одиночный \ внутри строк R является экранирующим символом, поэтому "C:\Users" это синтаксическая ошибка. И setwd() немедленно даёт ошибку, если папки не существует, — это самый дружелюбный отказ за весь день: он не может молча оставить вас смотрящим не туда.

Поэтому порядок отладки для любой ошибки «cannot open file» такой: getwd(), чтобы увидеть, куда смотрит R, а затем сравнить это с тем, где на самом деле лежит файл.

list.files(): посмотреть, что видит R

Третий инструмент набора перечисляет содержимое рабочего каталога — буквально множество имён, до которых может дотянуться относительный путь:

Если файл, который вы пытаетесь прочитать, есть в этом выводе, read.csv("thatfile.csv") его найдёт. Если нет, никакое переписывание строки read.csv не поможет — чинить нужно рабочий каталог. list.files("data") заглядывает в подпапку, а list.files(pattern = "\\.csv$") фильтрует только CSV. Когда имя файла выглядит правильным, но не находится, list.files() также вскрывает классических виновников: невидимое расширение .txt, дописанное текстовым редактором, или Data.csv вместо data.csv в системе, чувствительной к регистру.

Почему жёстко прописанный setwd() ломается

Теперь принципиальная часть. Вам встретятся скрипты, которые открываются строкой:

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

Эта строка работает ровно на одной машине — авторской. На вашем ноутбуке, на Mac коллеги, на сервере отдела или на вашем же компьютере после реорганизации она падает на первой строке. Жёстко прописанный абсолютный путь впекает раскладку папок одного человека в код, который должен её пережить.

Решение — перевернуть ответственность: не заставляйте скрипт искать папку — запускайте R в правильной папке и используйте относительные пути внутри скрипта. Конкретно:

  • Используйте проекты RStudio. Открытие файла .Rproj автоматически задаёт рабочий каталог папкой проекта на любой машине. Внутри скрипта read.csv("data/sales.csv") тогда работает у всех, у кого есть проект.
  • Запуск из терминала делает то же самое: Rscript analysis.R использует папку, из которой вы его запустили, в качестве рабочего каталога (см. запуск скриптов R).
  • Пакет here идёт ещё дальше для тех, кому это нужно: here::here("data", "sales.csv") строит пути от корня проекта независимо от того, куда забрёл рабочий каталог, — но проекты плюс относительные пути закрывают большинство потребностей и без него.

Сам по себе setwd() не зло — он вполне уместен в интерактивной работе, при разведке. Дурно пахнет именно абсолютный, привязанный к машине setwd(), закоммиченный в начало общего скрипта.

Рабочее пространство: ls() и rm()

Рядом с вопросом «в какой я папке» стоит вторая часть состояния сессии — рабочее пространство (глобальное окружение), то есть все объекты, созданные вами в этой сессии. ls() их перечисляет, rm() удаляет:

Последний ls() печатает character(0) — пустое рабочее пространство. Заклинание rm(list = ls()) выглядит странно, пока его не разберёшь: ls() возвращает символьный вектор всех имён объектов, а rm(list = ...) удаляет каждое имя из этого вектора. Это кодовый эквивалент иконки метлы на панели Environment в RStudio.

Знайте, чего оно не делает: пакеты, загруженные через 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) удаляет один; rm(list = ls()) очищает все — пакеты и опции остаются.
  • Ctrl+L (или cat("\014")) очищает только текст консоли.
  • Не сохраняйте и не восстанавливайте .RData автоматически: стартуйте чисто и перезапускайте скрипт — именно это делает вашу работу воспроизводимой.

Дальше: чтение настоящих данных — read.csv() и родственные функции, теперь, когда R смотрит в нужную папку.

Часто задаваемые вопросы

Как задать рабочий каталог в R?

Вызовите setwd("path/to/folder"), чтобы сменить его, и getwd(), чтобы увидеть текущий. В RStudio можно также воспользоваться меню: Session → Set Working Directory. Но для всего, что вы будете перезапускать или передавать другим, предпочитайте проект RStudio (он задаёт рабочий каталог автоматически) вместо жёстко прописанной строки setwd() — абсолютные пути ломаются на любой другой машине.

Как очистить окружение в R?

rm(list = ls()) удаляет каждый объект из глобального окружения: ls() перечисляет все имена объектов, а rm() их удаляет. Чтобы убрать один объект, используйте rm(x). Учтите, что это очищает только объекты — загруженные пакеты остаются загруженными, а текст консоли не трогается (за это отвечает Ctrl+L в RStudio).

Почему read.csv говорит «cannot open file», хотя файл существует?

Потому что R разрешает относительные пути относительно своего рабочего каталога, а ваш указывает не на ту папку, где лежит файл. Выполните getwd(), чтобы увидеть, куда смотрит R, и list.files(), чтобы увидеть, что он там видит. Исправьте это, открыв проект в правильной папке (или через setwd()), а не вставляя абсолютный путь в скрипт.

Coddy programming languages illustration

Учитесь программировать с Coddy

НАЧАТЬ