Search code examples
javadataframemoverenjin

Moving data between Java and R using renjin


I'm trying to move data between Java and R and vice-versa (as a dataframe) using Renjin. Searching in Stackoverflow I've find something that at first I've thoutht it would work but It wouldn't because I've got the R data in Java as an externalptr. Here is the code:

package teste;

(imports omitted)

public class TesteRenjin {

public static void main(String[] args) throws ClassNotFoundException {

List<Processos_Julgados> processosJulgados = new
ArrayList<Processos_Julgados>();

    String driver = "com.mysql.jdbc.Driver";
    String pwd = "";
    String user = "root";
    String url = "jdbc:mysql://localhost/cocaj_miner";
    Connection con = null;

    try {

    Class.forName(driver);
    con = DriverManager.getConnection(url, user, pwd);
    System.out.println("Conexão bem sucedida");
    String sql = "select ementa, numProcesso from processos_julgados where
ementa is not Null limit 15";
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);

while (rs.next()) {

Processos_Julgados procJulg = new Processos_Julgados();
procJulg.setNumProcesso(rs.getString("numProcesso"));
procJulg.setEmenta(rs.getString("ementa"));
processosJulgados.add(procJulg);

        }

    } catch (SQLException e) {

        System.out.println(e.getMessage());
        //System.out.println("Conexão não foi possível");
    } finally {

        try {
            con.close();
        } catch (SQLException ex) {
            Logger.getLogger(TesteRenjin.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    StringArrayVector.Builder numProcParaR = new StringArrayVector.Builder();

    for (Processos_Julgados processos : processosJulgados) {

        numProcParaR.add(processos.getNumProcesso());

    }

    ListVector.NamedBuilder dfProcessos = new ListVector.NamedBuilder();

    dfProcessos.setAttribute(Symbols.CLASS, StringVector.valueOf("data.frame"));
    dfProcessos.setAttribute(Symbols.ROW_NAMES, new RowNamesVector(processosJulgados.size()));
    dfProcessos.add("processos", numProcParaR.build());

    RenjinScriptEngineFactory factory = new RenjinScriptEngineFactory();
    ScriptEngine engine = factory.getScriptEngine();

    engine.put("df", dfProcessos);

    try {
        engine.eval("str(df)");
    } catch (ScriptException ex) {
        Logger.getLogger(TesteRenjin.class.getName()).log(Level.SEVERE, null, ex);
    }

}

}

Could you help me please?


Solution

  • You are almost there.

    The java object dfProcessos contains a ListVector.NamedBuilder, not a ListVector. A ListVector implements the SEXP interface, and so will be treated as a normal R object (or "S-Expression"), while all other Java objects, including the Builder object, need to be wrapped in an External Pointer R Object.

    Change the line:

    engine.put("df", dfProcessos);
    

    To:

    engine.put("df", dfProcessos.build());
    

    And it should work.