Доступ к объектам R из подпроцесса в родительский процесс
В контексте обучения R-программированию я пытаюсь запускать R-сценарии совершенно независимо, чтобы я мог сравнить сгенерированные ими объекты.
В настоящее время я делаю это с R средами:
student_env <- new.env()
solution_env <- new.env()
eval(parse(text = "x <- 4"), env = student_env)
eval(parse(text = "x <- 5"), env = solution_env)
student_env$x == student_env$y
Хотя это обеспечивает некоторую инкапсуляцию, на данный момент оно завершено. Например, если я выполню library()
Вызовите в среде студента, он присоединен к пути поиска глобальной сессии R, что делает пакет доступным для кода, выполняемого в среде решения.
Чтобы обеспечить полное разделение, я мог запустить подпроцессы, используя subprocess
пакет:
library(subprocess)
rbin <- file.path(R.home("bin"), "R")
student_handle <- spawn_process(rbin, c('--no-save'))
solution_handle <- spawn_process(rbin, c('--no-save'))
process_write(student_handle, "x <- 4\n")
process_write(solution_handle, "x <- 5\n")
Однако я не уверен, как выполнить выборку объектов R, чтобы я мог их сравнить.
Мои вопросы:
- Является
subprocess
хороший подход? - Если да, как я могу (эффективно!) Получить R представлений объектов из подпроцесса, чтобы я мог сравнить объекты в родительском процессе? Python делает это с помощью травления / укропа.
- Я мог бы общаться через файлы.rds, но это ненужное создание / чтение файлов.
- В R я наткнулся
RProtoBuf
, но я не уверен, что это решит мою проблему.
- Если нет, есть ли другие подходы, которые я должен рассмотреть? Я смотрел в
opencpu
, но концепция запуска локального сервера и последующего использования R для связи с этим сервером и получения представлений кажется слишком сложным подходом.
Спасибо!
2 ответа
Другим возможным подходом является callr
пакет, который популярен и разработан заслуживающим доверия источником: https://github.com/r-lib/callr.
Пример оттуда:
r(function() var(iris[, 1:4]))
#> Sepal.Length Sepal.Width Petal.Length Petal.Width
#> Sepal.Length 0.6856935 -0.0424340 1.2743154 0.5162707
#> Sepal.Width -0.0424340 0.1899794 -0.3296564 -0.1216394
#> Petal.Length 1.2743154 -0.3296564 3.1162779 1.2956094
#> Petal.Width 0.5162707 -0.1216394 1.2956094 0.5810063
Я бы использовал RServe
так как он позволяет вам запускать несколько сеансов R и управлять ими всеми из основного сеанса R. Вы можете запускать команды в этих сеансах в любом заданном (переплетенном) порядке и получать доступ к объектам, хранящимся там в собственном формате.
subprocess
был создан для запуска и управления любой произвольной программой через интерфейс командной строки, поэтому я никогда не собирался добавлять механизм передачи объектов. Хотя, если бы я получил доступ к объектам из дочерних процессов, я бы сделал это через saveRDS
а также readRDS
,