Search code examples
rrjava

Call Java from R


I want to execute Java code from R. I used rJava package and I was able to execute a simple code of Java such as create object or print on screen.

   require("rJava")
    .jinit()
    test<-new (J ("java.lang.String") , "Hello World!")

However what I want to do is to send a dataframe from R or CSV file and execute a code in Java then return the output file to R. At the same time, it is difficult in my case to call the R code from Java, as I want to process the CVS file first in R , then apply the Java code on it and return the result again to R to complete the analysis.


Solution

  • I'd go following way here.

    1. Process CSV file inside R

    2. Save this file somewhere and make sure you know explicit location (e.g. /home/user/some_csv_file.csv)

    3. Create adapter class in Java that will have method String processFile(String file)
    4. Inside method processFile read the file, pass it to your code in Java and do Java based processing
    5. Store output file somewhere and return it's location
    6. Inside R, get the result of processFile method and do further processing in R

    At least, that's what I'd do as a first draft of a solution for your problem.

    Update

    We need Java file

    // sample/Adapter.java
    package sample;
    
    public class Adapter {
      public String processFile(String file) {
        System.out.println("I am processing file: " + file);
        return "new_file_location.csv";
      }
    
      public static void main(String [] arg) {
        Adapter adp = new Adapter();
        System.out.println("Result: " + adp.processFile("initial_file.csv"));
      }
    }
    

    We have to compile it

    > mkdir target
    > javac -d target sample/Adapter.java
    > java -cp target sample.Adapter
    I am processing file: initial_file.csv
    Result: new_file_location.csv
    > export CLASSPATH=`pwd`/target
    > R
    

    We have to call it from R

    > library(rJava)
    > .jinit()
    > obj <- .jnew("sample.Adapter")
    > s <- .jcall(obj, returnSig="Ljava/lang/String;", method="processFile", 'initial_file')
    > s
    I am processing file: initial_file
    > s
    [1] "new_file_location.csv"
    

    And your source directory looks like this

    .
    ├── sample
    │   └──Adapter.java
    └── target
         └── sample
             └── Adapter.class
    

    In processFile you can do whatever you like and call your existing Java code.