Пакет reticulate позволяет легко использовать лучшее из обоих - вместе!

R и Python имеют много общего и имеют много различий. Большинство базовых концепций структур данных в этих двух языках очень схожи, и сейчас существует множество пакетов для анализа данных на обоих языках. Но R настроен таким образом, что я бы назвал его «сначала данные, затем приложение», тогда как Python с самого начала считает, что разработка приложений больше ведется. Программисты Javascript, например, вставляли бы в Python немного быстрее, чем они вставляли бы в R, чисто с точки зрения синтаксиса и управления средой.

Я все больше и больше работал с R и Python и сталкивался с ситуациями, когда мне хотелось бы использовать оба вместе. Это может происходить по многим причинам, но наиболее распространенная из них - вы создаете что-то на R и вам нужны функции, которые вы или кто-то другой ранее написал на Python. Конечно, вы могли бы переписать его на R, но это не очень СУХОЙ, не так ли?

Пакет reticulate в R позволяет выполнять код Python внутри сеанса R. На самом деле он существует уже несколько лет и улучшается все больше и больше, поэтому я хотел напечатать краткое руководство о том, как это работает. Если вы являетесь родным языком R, чтобы reticulate начать работу, вам нужно немного понять, как работает Python - и как он обычно управляет средой - и поэтому это руководство может помочь вам настроить его намного быстрее, чем если бы вы пытались работать. это сами.

Среды в R и Python

Любой программный проект работает в среде, в которой он хранит и получает доступ ко всему, что необходимо или создается во время его выполнения. В R для всех проектов доступна общая глобальная среда, в которой должен быть доступ к базовому языку R и всем установленным пакетам. В этом смысле все проекты в R обычно выполняются в одной и той же общей базовой среде. Один из способов подумать об этом - представить, что все в вашем доме используют один и тот же зарядный концентратор для своих iPhone. Они должны покинуть свою комнату, чтобы зарядить телефон, а если они продадут его, покупателю придется самостоятельно решить вопрос о зарядке.

В Python, однако, каждый проект обычно настраивается как полностью автономный - со своей собственной средой, собственной копией базы Python и независимыми копиями всех модулей, которые ему необходимы для выполнения. Вы можете думать об этом так, как будто у каждого есть собственное зарядное устройство для iPhone в своей комнате. Им не нужно выходить на улицу и подключать к электросети где-нибудь еще, и если они продали телефон, он идет в комплекте с собственным зарядным устройством.

Модель Python дороже с точки зрения процессов установки и ресурсов диска / памяти, но она позволяет легче переносить проекты между людьми с минимальной конфигурацией, поэтому нетрудно увидеть, как она выросла непосредственно из мышления разработки программного обеспечения, которое вот почему я считаю Python более ориентированным на приложения. Я должен отметить, что то, что я описываю, «типично» для большинства повседневных пользователей этих языков. Он не универсален, и если вы знаете, как это сделать, можно выполнять оба типа рабочих процессов проекта на обоих языках. Мы также видели недавние шаги в языке R, направленные на дальнейшее продвижение к моделям управления средой в стиле Python - например, с пакетом renv.

Вот небольшой рисунок, который я набросал, чтобы простым языком объяснить разницу между тем, как среды обычно работают в R и Python.

Теперь, если вы хотите, чтобы Python разговаривал с R, ему все равно нужно найти свою среду - вы не можете указать ему доступ к глобальной среде R. Это все равно, что сказать англоговорящему, чтобы он проложил маршрут, задавая вопрос китайскому.

Итак, чтобы заставить Python работать внутри вашего R-проекта, вам понадобятся две вещи:

  1. Среда Python, созданная внутри вашего проекта R, чтобы Python мог сориентироваться
  2. Пакет reticulate для перевода кода Python так, чтобы он работал в R

Настройка среды Python

Теперь я буду использовать простой пример. Предположим, у меня есть проект R в RStudio, который должен использовать функцию, написанную мной на Python. Итак, вот простая функция, которую я сохраню в скрипте Python под названием light_years.py в моем каталоге проекта R под названием test_python (да, RStudio позволяет создавать скрипты Python!). Эта функция принимает в качестве входных данных расстояние в километрах или милях и вычисляет, сколько лет потребуется, чтобы пройти это расстояние со скоростью света - другими словами, каково расстояние в световых годах:

from scipy.constants import cdef light_years(dist, unit = "km"):
    
    c_per_year = c * 60 * 60 * 24 * 365.25
    
    if unit == "km":
    
        dist_meters = dist * 1000
        
    elif unit == "mi":
      
        dist_meters = dist * 1.60934 * 1000
    
    else:
      
        sys.exit("Cannot use that unit!")
        
        
    return dist_meters/c_per_year

Я использую здесь очень простой пример функции, чтобы сделать эту статью понятной, поэтому это немного нереально, а также немного глупо, поскольку я импортирую весь пакет scipy только для того, чтобы получить значение константы, но, надеюсь, это поможет вам получить идея.

Теперь, как мы обсуждали выше, нам нужно предоставить этому коду среду. Для этого нужны:

  1. Версия Python для работы
  2. Доступ к пакету scipy, чтобы он мог получить постоянную c = скорость света

Настроить среду Python для вашего проекта R. несложно. Учитывая, насколько важны проектные среды в Python, существует множество простых в использовании инструментов управления средой.

Мне больше всего нравится Anaconda. Доступны две версии. Полная версия содержит обширную вселенную всего, что может понадобиться среде, включая все наиболее часто используемые модули Python. Еще есть Miniconda, который занимает меньше места на диске и больше подходит для ограниченных пользователей Python. Вы можете получить Miniconda для своей операционной системы здесь. Убедитесь, что вы загружаете Conda для той версии Python, с которой хотите работать.

После установки Conda, если вы работаете в MacOS или Linux, вы обычно настраиваете свои среды с помощью командной строки. Просто перейдите в каталог вашего проекта R (в моем случае test_python) в терминале и используйте эту команду:

conda create --name test_python

Все очень просто: теперь у вас создана среда Python. Я обычно называю свои среды так же, как и папка проекта, чтобы избежать путаницы в будущем.

Теперь вам нужно указать Conda использовать эту среду для этого проекта, поэтому, все еще находясь в каталоге test_python в командной строке, используйте эту команду:

conda activate test_python

И теперь вы связали этот проект со средой Python, и там есть копия базы Python, через которую можно выполнить ваш код.

Наконец, нашей функции нужен пакет scipy, поэтому он должен быть внутри среды. Это так же просто, как ввести это в активированной папке проекта:

conda install scipy

Затем Conda установит scipy и все зависимости, которые, по его мнению, могут потребоваться в вашу активную среду, и вы готовы к работе - так сказать, просто как scipy.

Теперь, позже вам нужно будет указать R, где найти Python в этой среде, поэтому, если вы воспользуетесь этой командой, вы можете получить список всех сред и путь к тому, где были установлены среды. :

conda info --envs

Это говорит мне, например, что моя среда была установлена ​​на /Users/keithmcnulty/opt/miniconda3/envs/test_python. Я всегда могу найти исполняемые файлы Python в подкаталоге bin, поэтому полный путь к исполняемому файлу Python для моего проекта - /Users/keithmcnulty/opt/miniconda3/envs/test_python/bin/python3, поскольку я использую Python 3. Это все, что нам нужно, чтобы сообщить R, где найти среду Python.

Запуск вашей функции Python в R

Теперь, независимо от того, настроили ли вы свои среды Python, как я, используя Conda, или вы использовали virtualenv, вы сделали сложную задачу. Остальное просто, потому что об этом позаботится reticulate.

Во-первых, вам нужно указать R, где найти исполняемый файл Python в нужной среде при загрузке вашего проекта. Для этого запустите пустой текстовый файл и добавьте следующее, заменив мой путь на любой путь, соответствующий вашему исполняемому файлу Python внутри созданной вами среды проекта.

Sys.setenv(RETICULATE_PYTHON = "/Users/keithmcnulty/opt/miniconda3/envs/test_python/bin/python3")

Теперь сохраните этот текстовый файл в каталоге вашего проекта с именем .Renv. Это скрытый файл, который R будет запускать всякий раз, когда вы запускаете свой проект в RStudio. Итак, теперь закройте RStudio и перезапустите его с открытым проектом test_python, и теперь он будет указывать на среду Python.

Теперь, если вы еще не установили пакет reticulate R, сделайте это сейчас. После установки вы можете попробовать несколько тестов в терминале, чтобы убедиться, что все в порядке.

Сначала вы можете проверить, знает ли R, где находится Python. reticulate::py_available() должен вернуть "TRUE". Вы также можете проверить, установлены ли необходимые вам модули Python: reticulate::py_module_available("scipy") должен вернуть "TRUE". Если все это работает, вы готовы перенести свою функцию в R.

Вы можете создать свой скрипт Python с помощью простого:

reticulate::source_python("light_years.py")

Теперь у вас есть функция light_years(), доступная как функция R. Давайте посмотрим, сколько лет потребуется, чтобы преодолеть квадриллион миль со скоростью света:

> light_years(1000000000000000, "mi")
[1] 170.1074

Отлично! Очевидно, это очень простой пример, но он расскажет вам все, что вам нужно, о том, как интегрировать код Python в ваш R-скрипт. Теперь вы можете представить, как можно ввести всевозможные функции или пакеты, которые в настоящее время предназначены только для Python, и заставить их работать в R - очень интересно. Если вы хотите увидеть несколько сложных примеров того, как использовать reticulate для объединения Python и R, ознакомьтесь с моими недавними статьями на тему Пять способов безупречной работы между R и Python в одном проекте, Создание параметризованных документов PowerPoint и Запуск XGBoost в R.

Изначально я был чистым математиком, затем стал психометриком и специалистом по анализу данных. Я с энтузиазмом отношусь к применению всех этих дисциплин к сложным человеческим вопросам. Я также помешан на кодировании и большой поклонник японских ролевых игр. Найдите меня в LinkedIn или Twitter. Также посетите мой блог на drkeithmcnulty.com или мой скоро выйдет учебник по аналитике людей.