Когда я беру проект R любой сложности, мои сценарии быстро становятся длинными и запутанными.
Какие методы я могу использовать, чтобы с моим кодом всегда было приятно работать? Я думаю о таких вещах, как
- Размещение функций в исходных файлах
- Когда что-то разбить на другой исходный файл
- Что должно быть в мастер-файле
- Использование функций в качестве организационных единиц (стоит ли это, учитывая, что R затрудняет доступ к глобальному состоянию)
- Отступы / практики разрыва строки.
- Лечить (как {?
- Положить такие вещи, как)} на 1 или 2 строки?
Каковы ваши основные правила организации больших R-скриптов?
r
package
conventions
code-organization
project-organization
Дэн Гольдштейн
источник
источник
ProjectTemplate
пакет.Ответы:
Стандартный ответ - использовать пакеты - см. Руководство по Writing R Extensions, а также различные учебные пособия в Интернете.
Это дает вам
R CMD check
Просто запуск
source()
кода работает для действительно коротких фрагментов. Все остальное должно быть в пакете - даже если вы не планируете его публиковать, вы можете написать внутренние пакеты для внутренних репозиториев.Что касается части «как редактировать», то в руководстве R Internals есть отличные стандарты кодирования R в Разделе 6. В противном случае, я склонен использовать значения по умолчанию в режиме ESS Emacs .
Обновление 2008-Август-13: Дэвид Смит просто блог о R Style Guide Google .
источник
Мне нравится помещать различные функции в свои файлы.
Но мне не нравится система пакетов R. Это довольно сложно использовать.
Я предпочитаю легкую альтернативу, чтобы поместить функции файла в среду (которую каждый другой язык называет «пространством имен») и прикрепить ее. Например, я создал группу утилит следующим образом:
Это все в файле util.R . Когда вы получаете его, вы получаете среду «util», чтобы вы могли звонить
util$bgrep()
и тому подобное; но, кроме того,attach()
призыв делает это так справедливоbgrep()
и такая работа напрямую. Если бы вы не поместили все эти функции в их собственное окружение, они бы загрязнили пространство имен верхнего уровня интерпретатора (котороеls()
показывает).Я пытался смоделировать систему Python, где каждый файл является модулем. Это было бы лучше иметь, но это, кажется, хорошо.
источник
sys.source
:MyEnv <- attach(NULL, name=s_env); sys.source(file, MyEnv)
. Я даже объявляю (в своем собственном окружении!) При запуске функцию,sys.source2
которая будет искать, если окружение с таким же именем уже здесь, и передает это вместо создания нового. Это делает добавление личных функций быстрым, простым и организованным :-)Это может показаться немного очевидным, особенно если вы программист, но вот как я думаю о логических и физических единицах кода.
Я не знаю, так ли это, но когда я работаю в R, я редко начинаю с большой сложной программы. Я обычно начинаю с одного скрипта и разделяю код на логически разделимые блоки, часто используя функции. Код манипулирования данными и визуализации размещается в своих собственных функциях и т. Д. И такие функции группируются в одном разделе файла (манипулирование данными в верхней части, затем визуализация и т. Д.). В конечном итоге вы хотите подумать о том, как упростить поддержку сценария и снизить уровень дефектов.
То, насколько хорошо / грубо детально вы выполняете свои функции, будет различаться, и существуют различные практические правила: например, 15 строк кода или «функция должна отвечать за выполнение одной задачи, которая определяется ее именем» и т. Д. Ваш пробег будет варьироваться. , Поскольку R не поддерживает вызов по ссылке, я обычно делаю свои функции слишком мелкозернистыми, когда требуется передача фреймов данных или подобных структур вокруг. Но это может быть чрезмерной компенсацией за некоторые глупые ошибки производительности, когда я впервые начал с R.
Когда извлекать логические единицы в их собственные физические единицы (например, исходные файлы и большие группы, такие как пакеты)? У меня есть два случая. Во-первых, если файл становится слишком большим, и прокрутка между логически не связанными единицами - раздражение. Во-вторых, если у меня есть функции, которые могут быть использованы другими программами. Я обычно начинаю с помещения некоторого сгруппированного блока, скажем, функций манипулирования данными, в отдельный файл. Затем я могу получить этот файл из любого другого сценария.
Если вы собираетесь развернуть свои функции, то вам нужно начать думать о пакетах. Я не использую R-код в производстве или для повторного использования другими по различным причинам (кратко: культура org предпочитает другие языки, проблемы с производительностью, GPL и т. Д.). Кроме того, я склонен постоянно совершенствовать и добавлять свои коллекции исходных файлов, и я бы предпочел не иметь дело с пакетами при внесении изменений. Так что вы должны проверить другие ответы, связанные с пакетом, такие как Дирк, для более подробной информации по этому вопросу.
Наконец, я думаю, что ваш вопрос не обязательно относится к R. Я действительно рекомендовал бы прочитать Code Complete Стивом Макконнеллом, в котором содержится много знаний о таких проблемах и практике кодирования в целом.
источник
Я согласен с советом Дирка! ИМХО, организация ваших программ от простых скриптов до документированных пакетов для программирования на R - это как переключение с Word на TeX / LaTeX для написания. Я рекомендую взглянуть на очень полезное создание пакетов R: Учебное пособие Фридриха Лейша.
источник
Мой краткий ответ:
Я считаю, что R все больше и больше используется в производстве, поэтому потребность в повторно используемом коде больше, чем раньше. Я нахожу переводчика гораздо более надежным, чем раньше. Нет сомнений в том, что R в 100-300 раз медленнее, чем C, но обычно узкое место концентрируется вокруг нескольких строк кода, которые можно делегировать C / C ++. Я думаю, что было бы ошибкой делегировать сильные стороны R в манипулировании данными и статистическом анализе на другой язык. В этих случаях снижение производительности является низким и в любом случае оправдывает затраты на разработку. Если бы речь шла только о времени выполнения, мы бы все писали на ассемблере.
источник
Я хотел выяснить, как писать пакеты, но не потратил время. Для каждого из моих мини-проектов я храню все свои низкоуровневые функции в папке с именем 'functions /' и помещаю их в отдельное пространство имен, которое я явно создаю.
Следующие строки кода создадут среду с именем "myfuncs" в пути поиска, если он еще не существует (с помощью attach), и заполнят его функциями, содержащимися в файлах .r в моем каталоге 'functions /' (используя sys.source). Я обычно помещаю эти строки вверху основного сценария, предназначенного для «пользовательского интерфейса», из которого вызываются функции высокого уровня (вызывая функции низкого уровня).
Когда вы вносите изменения, вы всегда можете повторно использовать его с теми же строками или использовать что-то вроде
оценить дополнения / модификации в среде, которую вы создали.
Это хорошо, я знаю, но избегает необходимости быть слишком формальным по этому поводу (но если у вас есть возможность, я поощряю систему пакетов - надеюсь, я буду мигрировать таким же образом в будущем).
Что касается соглашений о кодировании, то это единственное, что я видел в отношении эстетики (мне они нравятся, и я немного следую им, но я не использую слишком много фигурных скобок в R):
http://www1.maths.lth.se/help/R/RCC/
Существуют и другие «соглашения» относительно использования [, drop = FALSE] и <- как предложил оператор присваивания в различных презентациях (обычно ключевых) на useR! конференции, но я не думаю, что какие-либо из них являются строгими (хотя [, drop = FALSE] полезен для программ, в которых вы не уверены в ожидаемом вводе).
источник
Считай меня другим человеком в пользу посылок. Я признаю, что был довольно слаб в написании man-страниц и виньеток до тех пор, пока / когда мне придется (т.е. быть освобожденным), но это делает реальный удобный способ связать исходную лань. Кроме того, если вы серьезно относитесь к поддержанию своего кода, все пункты, о которых говорит Дирк, вступают в силу.
источник
Я тоже согласен. Используйте функцию package.skeleton () для начала. Даже если вы думаете, что ваш код больше никогда не будет запущен, это может помочь мотивировать вас на создание более общего кода, который впоследствии сэкономит ваше время.
Что касается доступа к глобальной среде, это легко сделать с помощью оператора << -, хотя это не рекомендуется.
источник
Еще не научившись писать пакеты, я всегда организовывал поиск субскриптов. Это похоже на написание уроков, но не так сложно. Это не очень элегантно, но я считаю, что со временем я строю анализы. Когда у меня работает большой раздел, я часто перемещаю его в другой сценарий и просто использую его, так как он будет использовать объекты рабочей области. Возможно, мне нужно импортировать данные из нескольких источников, отсортировать их все и найти пересечения. Я мог бы поместить этот раздел в дополнительный скрипт. Однако, если вы хотите распространять свое «приложение» для других людей или оно использует какой-то интерактивный ввод, пакет, вероятно, является хорошим маршрутом. Как исследователь, мне редко нужно распространять свой код анализа, но мне ЧАСТО нужно увеличивать или настраивать его.
источник
Я также искал святой Грааль правильного рабочего процесса для создания большого проекта R. В прошлом году я нашел этот пакет под названием rsuite , и, конечно, это было то, что я искал. Этот R-пакет был явно разработан для развертывания больших R-проектов, но я обнаружил, что его можно использовать для R-проектов меньшего, среднего и большого размера. Я дам ссылки на примеры из реальной жизни через минуту (ниже), но сначала я хочу объяснить новую парадигму построения R проектов с
rsuite
.Заметка. Я не создатель или разработчик
rsuite
.Мы работали над проектами совсем не так с RStudio; цель должна быть не в создании проекта или пакета, а в более широком масштабе. В rsuite вы создаете супер-проект или мастер-проект, который содержит стандартные проекты R и пакеты R во всех возможных комбинациях.
Имея супер-проект R, вам больше не нужен Unix
make
для управления нижними уровнями R-проектов; Вы используете R скрипты наверху. Позволь мне показать тебе. Когда вы создаете мастер-проект rsuite, вы получаете следующую структуру папок:В
R
эту папку вы помещаете свои сценарии управления проектами, которые будут замененыmake
.Папка
packages
- это папка, в которойrsuite
хранятся все пакеты, составляющие супер-проект. Вы также можете скопировать и вставить пакет, который недоступен из Интернета, и rsuite также создаст его.папка
deployment
, гдеrsuite
будет записывать все двоичные файлы пакетов , которые были указаны в пакетахDESCRIPTION
файлов. Таким образом, это само по себе делает проект полностью воспроизводимым по времени.rsuite
поставляется с клиентом для всех операционных систем. Я проверил их все. Но вы также можете установить его какaddin
для RStudio.rsuite
также позволяет создавать изолированнуюconda
установку в своей собственной папкеconda
. Это не среда, а физическая установка Python, созданная Anaconda на вашем компьютере. Это работает вместе с RSystemRequirements
, из которого вы можете установить все пакеты Python, которые вы хотите, с любого канала conda, который вы хотите.Вы также можете создавать локальные репозитории, чтобы получать пакеты R, когда вы не в сети, или хотите собрать все быстрее.
Если вы хотите, вы также можете собрать проект R в виде zip-файла и поделиться им с коллегами. Он будет работать при условии, что у ваших коллег будет установлена та же версия R.
Другим вариантом является создание контейнера всего проекта в Ubuntu, Debian или CentOS. Таким образом, вместо того, чтобы делиться zip-файлом со сборкой проекта, вы делите весь
Docker
контейнер с вашим проектом, готовым к запуску.Я много экспериментировал с
rsuite
поиском полной воспроизводимости и избегал зависимости от пакетов, которые устанавливаются в глобальной среде. Это неправильно, потому что как только вы устанавливаете обновление пакета, проект, чаще всего, перестает работать, особенно те пакеты с очень конкретными вызовами функции с определенными параметрами.Первое, что я начал экспериментировать, было с
bookdown
электронными книгами. Мне никогда не удавалось получить скидку, чтобы выдержать испытание временем более шести месяцев. Итак, что я сделал, так это конвертировал исходный проект bookdown, чтобы следоватьrsuite
структуре. Теперь мне не нужно беспокоиться об обновлении моей глобальной среды R, потому что у проекта есть собственный набор пакетов вdeployment
папке.Следующее, что я сделал, было создание проектов машинного обучения, но в
rsuite
пути. Главный, оркестрирующий проект наверху, и все подпроекты и пакеты должны находиться под контролем мастера. Это действительно меняет способ кодирования на R, делая вас более продуктивным.После этого я начал работать в новом пакете под названием
rTorch
. Это было возможно, в значительной степени, из-заrsuite
; это позволяет вам думать и развиваться.Один совет, хотя. Обучение
rsuite
нелегко. Поскольку он представляет новый способ создания проектов R, он чувствует себя тяжело. Не смущайтесь с первых попыток, продолжайте подниматься по склону, пока не сделаете это. Это требует глубоких знаний вашей операционной системы и вашей файловой системы.Я ожидаю, что один день
RStudio
позволит нам создать такие проекты, какrsuite
делается из меню. Это было бы замечательно.Ссылки:
RSuite GitHUb репо
r4ds bookdown
керас и блестящий учебник
moderndive книга-rsuite
interpretable_ml-rsuite
IntroMachineLearningWithR-rsuite
кларк-intro_ml-rsuite
Гайндман-bookdown-rsuite
statistical_rethinking-rsuite
Fread-тесты-rsuite
DataViz-rsuite
торгово-сегментация-h2o-учебник
телекоммуникационный-клиент-маслобойка-учебник
sclerotinia_rsuite
источник
R подходит для интерактивного использования и небольших сценариев, но я бы не стал использовать его для большой программы. Я бы использовал основной язык для большей части программирования и поместил бы его в интерфейс R.
источник
Rcpp
пакета, включая код C ++ в программах на R, становится довольно простым. Таким образом, переписывание определенных частей кода R может быть легко интегрировано в R. Кроме того, с появлением RStudio была введена среда IDE для R, хотя, возможно, она еще и не такая мощная, как Visual Studio.