R — подключение R и java с помощью Rserve

Я создал приложение, соединяющее R и java, используя пакет Rserve. При этом я получаю сообщение об ошибке «оценка прошла успешно, но объект слишком велик для транспортировки». Я также попытался увеличить значение размера буфера отправки в классе Rconnection. но это, кажется, не работает. Размер переносимого объекта составляет 4 МБ.

вот код из файла подключения R

public void setSendBufferSize(long sbs) выдает RserveException {

    if (!connected || rt == null) {
        throw new RserveException(this, "Not connected");
    }
    try {
        RPacket rp = rt.request(RTalk.CMD_setBufferSize, (int) sbs);
        System.out.println("rp is send buffer "+rp);
        if (rp != null && rp.isOk()) {
            System.out.println("in if " + rp);
            return;
        }
    } catch (Exception e) {
        e.printStackTrace();
        LogOut.log.error("Exception caught" + e);
    }

    //throw new RserveException(this,"setSendBufferSize failed",rp);        
}

Полный класс Java доступен здесь:Rconnection.java


person Shivani Jain    schedule 22.07.2015    source источник
comment
Это может помочь другим, если вы добавите код.   -  person hennes    schedule 22.07.2015


Ответы (1)


Вместо RServe можно использовать JRI, который поставляется с пакетом rJava.

На мой взгляд, JRI лучше, чем RServe, потому что вместо создания отдельного процесса он использует собственные вызовы для интеграции Java и R.

С JRI вам не нужно беспокоиться о портах, соединениях, сторожевых таймерах и т. д. Вызовы R выполняются с использованием библиотеки операционной системы (libjri).

Методы очень похожи на RServe, и вы по-прежнему можете использовать объекты REXP.

Вот пример:

public void testMeanFunction() {

    // just making sure we have the right version of everything
    if (!Rengine.versionCheck()) {
        System.err.println("** Version mismatch - Java files don't match library version.");
        fail(String.format("Invalid versions. Rengine must have the same version of native library. Rengine version: %d. RNI library version: %d", Rengine.getVersion(), Rengine.rniGetVersion()));
    }

    // Enables debug traces
    Rengine.DEBUG = 1;

    System.out.println("Creating Rengine (with arguments)");
    // 1) we pass the arguments from the command line
    // 2) we won't use the main loop at first, we'll start it later
    // (that's the "false" as second argument)
    // 3) no callback class will be used
    engine = REngine.engineForClass("org.rosuda.REngine.JRI.JRIEngine", new String[] { "--no-save" }, null, false);
    System.out.println("Rengine created...");

    engine.parseAndEval("rVector=c(1,2,3,4,5)");
    REXP result = engine.parseAndEval("meanVal=mean(rVector)");
    // generic vectors are RVector to accomodate names
    assertThat(result.asDouble()).isEqualTo(3.0);
}

У меня есть демонстрационный проект, который предоставляет REST API и вызывает функции R с помощью этого пакета.

Взгляните на: https://github.com/jfcorugedo/RJavaServer

person jfcorugedo    schedule 08.09.2015
comment
Просто ссылка на вашу собственную библиотеку или учебник не является хорошим ответом. Ссылка на него, объяснение, почему он решает проблему, предоставление кода о том, как это сделать, и отказ от того, что вы его написали, дает лучший ответ. См.: Что означает "Хорошая" самореклама? - person durron597; 08.09.2015
comment
хорошо, ты прав. Я улучшаю свой ответ, добавляя базовый пример, и причина, по которой я думаю, что JRI лучше, чем RServe - person jfcorugedo; 08.09.2015
comment
Если вы предоставите REST API из вызовов JRI R, вы получите однопоточные веб-сервисы. Используйте Rserve для масштабируемых сервисов. - person Tristan; 09.11.2018
comment
Да, ты прав. На самом деле я запрограммировал оба подхода и использовал тот или иной в зависимости от нескольких факторов. Если вам интересно, посмотрите мой репозиторий - person jfcorugedo; 09.11.2018