Доступ к объектам R из подпроцесса в родительский процесс - PullRequest
0 голосов
/ 27 апреля 2018

В контексте обучения 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 ]

0 голосов
/ 29 июля 2018

Я бы использовал RServe, так как он позволяет вам запускать несколько сеансов R и управлять ими всеми из основного сеанса R. Вы можете запускать команды в этих сеансах в любом заданном (переплетенном) порядке и получать доступ к объектам, хранящимся там в собственном формате.

subprocess был создан для запуска и управления любой произвольной программой через интерфейс командной строки, поэтому я никогда не намеревался добавлять механизм передачи объектов. Хотя, если бы я получил доступ к объектам из дочерних процессов, я бы сделал это через saveRDS и readRDS.

0 голосов
/ 27 апреля 2018

Другим возможным подходом является пакет callr, который популярен и разработан заслуживающим доверия источником: https://github.com/r-lib/callr#readme.

Пример оттуда:

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
...