Новогодним подарком в этом году стали для меня новая команда и проект на языке R, о котором в тот момент я знал немного. Поначалу было трудно и не понятно, но время шло, картинка прояснялась. С чем-то удалось разобраться, что-то пришлось принять как есть. И вот, спустя два с половиной месяца работы на R, я решил поделиться опытом и рассказать о своих первых шагах в этом проекте. Я не буду описывать все свои душевные муки и эмоции, которые переполняли меня в процессе освоения этого очень интересного языка, а сосредоточусь на технической стороне вопроса. Цель моей статьи рассказать о том, как отлаживать код в RStudio и создавать новый проект на R.
Первое с чем пришлось мне столкнуться – это отладка приложения. В RStudio есть возможность выделить отдельные участки кода и запустить их. Это очень помогает при работе с R markdown, так как в них, в режиме Debug, нельзя поставить точку останова. А выделить строчки и запустить их можно где угодно.
![запуск строчки кода](https://habrastorage.org/r/w780q1/webt/5-/i8/ev/5-i8evwdifdd3g7npseykp_5fkm.jpeg)
Причем переменные, которые будут вызываться в этих строчках, он берет из глобального окружения. Получается, что для проверки того, как работает та или иная функция достаточно создать глобальные переменные, построчно запускать код из этих функций и смотреть что происходит. Я работаю в RStudio, где на вкладке Global Environment можно увидеть значения этих переменных.
![панель глобального окружения](https://habrastorage.org/r/w780q1/webt/nk/ew/ts/nkewtsehao_zkkjvg61odu6nny8.jpeg)
Создают или меняют значения этих переменных через Console.
![Console](https://habrastorage.org/r/w780q1/webt/h5/ez/ko/h5ezko6hnnra_kykpgmumcr5bqm.jpeg)
Но кроме переменных есть другая проблема. Когда вы выполняете команды построчно, он может не найти код функций, которые вызываются в тех строчках, которые вы выполняете. Для этого их тоже надо загрузить в память. Чтобы это сделать, надо открыть файл с кодом этой функции и нажать на кнопку Source.
![кнопка Source](https://habrastorage.org/r/w780q1/webt/li/fo/bw/lifobw9iddvnl6ku6sjfxzda08k.jpeg)
Есть в RStudio и классический Debug режим. В нем присутствует возможность ставить Break Points, с возможностью запуска в режиме отладки и функция browser(), встретив которую R прерывает выполнение кода, позволяя отладить приложение. Но в нашем проекте это не получило широкого распространения из-за работы с R markdown.
Следующее с чем я столкнулся в R – это два типа проектов: обычный проект (New Project) и проект типа package (R Package). Когда я пришёл в команду, там был некий микс из этих 2-х. Вроде был Package, но он не собирался и запускали его через RScrtipt. Сейчас, благодаря усилиям моих коллег, у нас работающий R Package.
![image](https://habrastorage.org/r/w780q1/webt/xc/re/dc/xcredctesn5zthgv_cvwsik8z5s.jpeg)
Обычный проект (New Project) предлагает написать R-скрипт файлы, где один файл подключается к другому через функцию source(). Таким образом, при запуске скрипта получается как бы “один очень большой файл”, в который включены все файлы проекта. Это не всегда удобно и не очень гибко.
![кнопка Source](https://habrastorage.org/r/w780q1/webt/7b/qf/qh/7bqfqhm6qac0z6o0s2wwipfi_da.jpeg)
В отличие от обычного проекта, проект типа R Package предлагает нам написать библиотеку функций на R, которую потом можно будет установить на любую машину и вызывать эти функции внутри своего R-скрипт файла. Есть правда один нюанс. Функции доступны только из R-скрипта. Поэтому, прежде чем начать с ними работать, нужно будет создать такой скрипт и уже в нем прописать вызовы этих функций. Запускается он в консоли с помощью команды: Rscript. Чтобы это работало нужно в переменных окружения прописать путь к файлу Rscript.exe. На моей машине этот путь выглядит так: C:\Program Files\R\R-4.0.3\bin. При создании своих функций в проекте типа Package, в режиме разработки, следует пользоваться функцией load_all(), которая подтягивает все изменения в память. Если ей не пользоваться, то при всяком изменении кода в проекте, для того чтобы эти изменения вступили в силу, надо запустить процесс инсталляции, что R делает не быстро.
Теперь о проекте R-Package: В отличие от простого проекта, он содержит некую обязательную структуру и специальные файлы. Это:
.Rhistory и .RData присутствуют как в проекте типа Package, так и в обычном проекте. Ещё можно создать папку inst для дополнительных ресурсов и папку test для unit тестов. Более детально с тем, как устроен R package и почему именно так он работает вы можете ознакомиться по ссылке.
При создании проекта типа R Package используют утилиту roxygen2. Она помогает создать документацию для вашего пакета. Идея в том, что вы описываете каждую функцию прямо в коде, а утилита уже сама переносит это описание в папку man, конвертируя в необходимый формат и добавляет информацию о функциях в файл NAMESPACE. Подробнее о roxygen2 тут.
Ещё есть полезные пакеты для настройки проекта, которые используют практически во всех инструкциях по его созданию, как минимум во всех тех, что я нашёл в Интернет:
Все общедоступные пакеты с их описанием и с документацией к языку R хранятся в CRAN — The Comprehensive R Archive Network (https://cran.r-project.org/ )
Для удобства работы, в RStudio уже встроены средства проверки вновь создаваемого проекта (Check Package) и его тестирования (Test Package).
![Build меню](https://habrastorage.org/r/w780q1/webt/pi/b8/jp/pib8jpdkigmbmxpo1lxovrajxfs.jpeg)
Вроде бы всё, что хотел, рассказал, но лучше один раз увидеть, чем сто раз прочитать. Ниже видео о том, как начать работать с R:
По моему опыту, оказавшись на проекте с новым языком программирования, чаще всего, самую большую проблему представляет не сам язык, а инструменты работы с ним, средства конфигурирования и настройки окружения. Надеюсь, что после прочтения этой статьи, многим станет гораздо проще начать работать с R.
Первое с чем пришлось мне столкнуться – это отладка приложения. В RStudio есть возможность выделить отдельные участки кода и запустить их. Это очень помогает при работе с R markdown, так как в них, в режиме Debug, нельзя поставить точку останова. А выделить строчки и запустить их можно где угодно.
![запуск строчки кода](https://habrastorage.org/webt/5-/i8/ev/5-i8evwdifdd3g7npseykp_5fkm.jpeg)
Причем переменные, которые будут вызываться в этих строчках, он берет из глобального окружения. Получается, что для проверки того, как работает та или иная функция достаточно создать глобальные переменные, построчно запускать код из этих функций и смотреть что происходит. Я работаю в RStudio, где на вкладке Global Environment можно увидеть значения этих переменных.
![панель глобального окружения](https://habrastorage.org/webt/nk/ew/ts/nkewtsehao_zkkjvg61odu6nny8.jpeg)
Создают или меняют значения этих переменных через Console.
![Console](https://habrastorage.org/webt/h5/ez/ko/h5ezko6hnnra_kykpgmumcr5bqm.jpeg)
Но кроме переменных есть другая проблема. Когда вы выполняете команды построчно, он может не найти код функций, которые вызываются в тех строчках, которые вы выполняете. Для этого их тоже надо загрузить в память. Чтобы это сделать, надо открыть файл с кодом этой функции и нажать на кнопку Source.
![кнопка Source](https://habrastorage.org/webt/li/fo/bw/lifobw9iddvnl6ku6sjfxzda08k.jpeg)
Есть в RStudio и классический Debug режим. В нем присутствует возможность ставить Break Points, с возможностью запуска в режиме отладки и функция browser(), встретив которую R прерывает выполнение кода, позволяя отладить приложение. Но в нашем проекте это не получило широкого распространения из-за работы с R markdown.
Следующее с чем я столкнулся в R – это два типа проектов: обычный проект (New Project) и проект типа package (R Package). Когда я пришёл в команду, там был некий микс из этих 2-х. Вроде был Package, но он не собирался и запускали его через RScrtipt. Сейчас, благодаря усилиям моих коллег, у нас работающий R Package.
![image](https://habrastorage.org/webt/xc/re/dc/xcredctesn5zthgv_cvwsik8z5s.jpeg)
Обычный проект (New Project) предлагает написать R-скрипт файлы, где один файл подключается к другому через функцию source(). Таким образом, при запуске скрипта получается как бы “один очень большой файл”, в который включены все файлы проекта. Это не всегда удобно и не очень гибко.
![кнопка Source](https://habrastorage.org/webt/7b/qf/qh/7bqfqhm6qac0z6o0s2wwipfi_da.jpeg)
В отличие от обычного проекта, проект типа R Package предлагает нам написать библиотеку функций на R, которую потом можно будет установить на любую машину и вызывать эти функции внутри своего R-скрипт файла. Есть правда один нюанс. Функции доступны только из R-скрипта. Поэтому, прежде чем начать с ними работать, нужно будет создать такой скрипт и уже в нем прописать вызовы этих функций. Запускается он в консоли с помощью команды: Rscript. Чтобы это работало нужно в переменных окружения прописать путь к файлу Rscript.exe. На моей машине этот путь выглядит так: C:\Program Files\R\R-4.0.3\bin. При создании своих функций в проекте типа Package, в режиме разработки, следует пользоваться функцией load_all(), которая подтягивает все изменения в память. Если ей не пользоваться, то при всяком изменении кода в проекте, для того чтобы эти изменения вступили в силу, надо запустить процесс инсталляции, что R делает не быстро.
Теперь о проекте R-Package: В отличие от простого проекта, он содержит некую обязательную структуру и специальные файлы. Это:
- файл DESCRIPTION с описанием пакета,
- папка man для описания функций,
- файл NAMESPACE со списком доступных функций создаваемого пакета,
- папка с названием R, в которой должен лежать ваш код на языке R
- файл .Rbuildignore со списком того, что не входит в пакет при его сборке
- файл .Rhistory, который хранит историю команд в консоли
- .RData хранит содержимое вкладки Environment, точнее данные которые были загружены в память при работе с проектом
.Rhistory и .RData присутствуют как в проекте типа Package, так и в обычном проекте. Ещё можно создать папку inst для дополнительных ресурсов и папку test для unit тестов. Более детально с тем, как устроен R package и почему именно так он работает вы можете ознакомиться по ссылке.
При создании проекта типа R Package используют утилиту roxygen2. Она помогает создать документацию для вашего пакета. Идея в том, что вы описываете каждую функцию прямо в коде, а утилита уже сама переносит это описание в папку man, конвертируя в необходимый формат и добавляет информацию о функциях в файл NAMESPACE. Подробнее о roxygen2 тут.
Ещё есть полезные пакеты для настройки проекта, которые используют практически во всех инструкциях по его созданию, как минимум во всех тех, что я нашёл в Интернет:
- devtools – основной пакет, в котором собранно большинство команд для работы с проектом в их упрощенном виде
- usethis – пакет помощник, упрощающий выполнение многих рутинных операций
- testthat — пакет для написания Unit тестов
- covr — пакет для проверки кода на покрытие unit тестами
Все общедоступные пакеты с их описанием и с документацией к языку R хранятся в CRAN — The Comprehensive R Archive Network (https://cran.r-project.org/ )
Для удобства работы, в RStudio уже встроены средства проверки вновь создаваемого проекта (Check Package) и его тестирования (Test Package).
![Build меню](https://habrastorage.org/webt/pi/b8/jp/pib8jpdkigmbmxpo1lxovrajxfs.jpeg)
Вроде бы всё, что хотел, рассказал, но лучше один раз увидеть, чем сто раз прочитать. Ниже видео о том, как начать работать с R:
- Начало работы с R на RStudio. Проект на языке R или пакет на языке R
- Создание проекта R package вместе с Unit tests и documentation
- Запуск и отладка R кода для проекта R Package
По моему опыту, оказавшись на проекте с новым языком программирования, чаще всего, самую большую проблему представляет не сам язык, а инструменты работы с ним, средства конфигурирования и настройки окружения. Надеюсь, что после прочтения этой статьи, многим станет гораздо проще начать работать с R.