Проблема с вызовом ggplot с использованием R_tryEval

Я пытаюсь построить систему, позволяющую выполнять произвольный код R из приложения C ++.
Для достижения этого ядро ​​метода следует тому, что описано здесь: http://www.hep.by/gnu/r-patched/r-exts/R-exts_121.html

Это работало хорошо для любого кода R до сих пор. Тем не менее, я столкнулся с проблемой при использовании ggplot. Я пытаюсь отправить полученный график ggplot в png файл. Он работает нормально, если выполняется непосредственно в консоли R, но когда я использую свой интерфейс C ++, полученный файл будет пустым.

Точнее, код R организован следующим образом:

  • Загрузить библиотеку ggplot2
  • Определите некоторые фиктивные данные для построения графика.
  • Вызовите png для создания графического устройства.
  • Позвоните в ggplot.
  • Вызовите dev.off (), чтобы закрыть графическое устройство.

Когда сводится к минимальному случаю, вот мой код:

#include <QDebug>

#include <Rembedded.h>
#include <Rinternals.h>
#include <R_ext/Parse.h>

int main(int argc, char *argv[])
{
const char *argvrf[] = {"RConsole"};
int argcrf = sizeof(argvrf) / sizeof(argvrf[0]);

Rf_initEmbeddedR(argcrf, (char**)argvrf);

// Create some dummy data for a ggplot.
// For the purpose of this minimal example, R code is just directly defined as a QString here.

QString RScript = "library(\"ggplot2\") \n" ;
RScript += "id<-c(1,2,3,4,5) \n" ;
RScript += "names<-c(\"A\",\"B\",\"C\",\"D\",\"E\") \n" ;
RScript += "notes<-c(12,20,13,15,10) \n" ;
RScript += "df1<-data.frame(id,names,notes) \n" ;

// Define a file as graphicsDevice (adapt adress to your own filesystem)
RScript += "png(\"C:/Users/Evain/Desktop/tests/testggplot.png\", width=480, height=480, res=72) \n" ;
// Drawing the ggplot.
RScript += "ggplot(data=df1,aes(x=id,y=notes))+geom_line() \n" ;
// Closing the graphic device.
RScript += "dev.off() \n" ;ParseStatus status;
SEXP cmdSexp, cmdexpr = R_NilValue;
int i, errorOccurred, retVal=0;

// Convert the command line to SEXP
PROTECT(cmdSexp = Rf_allocVector(STRSXP, 1));
SET_STRING_ELT(cmdSexp, 0, Rf_mkChar(RScript.toLocal8Bit().data()));
cmdexpr = PROTECT(R_ParseVector(cmdSexp, -1, &status, R_NilValue));

switch (status){
case PARSE_OK: {
// Loop is needed here as EXPSEXP might be of length > 1
for(i = 0; ((i < Rf_length(cmdexpr)) && (retVal==0)); i++){
R_tryEval(VECTOR_ELT(cmdexpr, i), R_GlobalEnv, &errorOccurred);
if (errorOccurred) {
// Interrupt process.
qDebug() << "Error occured" ;
retVal = -1;
}
}
break ;
}
default: {
qDebug() << "Incorrect R command" ;
break;
}
}
return 0;
}

Связь с R работает нормально, если это не ggplot. Например, если я заменю

RScript += "ggplot(data=df1,aes(x=id,y=notes))+geom_line() \n" ;

С:

RScript += "plot(3) \n";

Тогда все работает нормально, создается png файл с нужным сюжетом.
С ggplot этот код выполняется без видимых проблем. Сообщения qDebug () не запускаются. Файл png даже создан (это означает, что вызов png () выполнен правильно). Но файл пуст.

Это не просто проблема с комбинацией png () и ggplot () или с моими фиктивными данными, поскольку, если я просто запускаю следующий R-скрипт в консоли R, я получаю ожидаемый результат (файл создан и содержит сюжет):

library("ggplot2")
id<-c(1,2,3,4,5)
names<-c("A","B","C","D","E")
notes<-c(12,20,13,15,10)
df1<-data.frame(id,names,notes)

png("C:/Users/Evain/Desktop/tests/testggplot.png", width=480, height=480, res=72)
ggplot(data=df1,aes(x=id,y=notes))+geom_line()
dev.off()

Примечание: я нахожусь на Windows 10, используя R3.4.3.
Стоит отметить, что метод png () ведет себя немного по-другому в Linux. Для окон файл создается при вызове png (), даже если он должен оставаться пустым. Для Linux файл не будет создан, если в нем ничего не написано.

Если файл png уже существует, он также заменяется пустым. Это то, что мы должны ожидать при вызове png () в одиночку. Просто ggplot не добавляется к нему.

Такое чувство, что объединение R_tryEval () с png () работает нормально. Комбинирование png () с ggplot работает нормально, но комбинирование R_tryEval () с png () и ggplot () — нет. Любая идея ?

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]