Доступ к объектам R из подпроцесса в родительский процесс

89
10

В контексте обучения 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, но концепция opencpu локального сервера, а затем использовать R, чтобы поговорить с этим сервером и получить представления, кажется слишком сложным.

Спасибо!

спросил(а) 2021-01-25T16:16:43+03:00 5 месяцев назад
1
Решение
63

Другим возможным подходом является пакет 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

ответил(а) 2021-01-25T16:16:43+03:00 5 месяцев назад
63

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


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

ответил(а) 2021-01-25T16:16:43+03:00 5 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема