Interfacing R and Java ( Installation and Sample Programs)

958 views
Skip to first unread message

Shekhar

unread,
Apr 25, 2011, 7:39:13 AM4/25/11
to Bangalore R Users - BRU
Hi,
In the earlier posts we have seen how to interface R with the one of
the compiled languages like C++. In this post we will see how to
interface java with R. The sample programs described in this post are
only one sided as of now. That means we will be calling Java functions
from the R environment only not the other way round.

1. Software details:

--------------------------------------------------------------
Software | Version
-------------------------------------------------------------
OS | CentOS5.5
-------------------------------------------------------------
Java JDK | 1.6.0_22
------------------------------------------------------------
R | 2.12.0
------------------------------------------------------------
rJava package | 0.9-0
-------------------------------------------------------------

2. Installation:

(A). Downloaded the “rJava” package from http://www.rforge.net/rJava/files/rJava_0.9-0.ar.gz
(B) Untar the package by running the command
tar –xvf rJava_0.9-0.tar.gz.
It will create the directory “rJava”
(C) Run the command
R CMD INSTALL rJava.
This will install the rJava package.
(D) Checking whether the package has been installed. Open the R
console and type the function installed.packages().
It should show rJava package in the list

---------------------------------------------------------------------------
SAMPLE PROGRAMS
-----------------------------------------------------------------------
The java class files you can provide in the CLASSPATH environment
variable.

The basic steps for calling the java functions from R is :
------Load the rjava library (library(rJava)
------Initialize the JVM (.jinit())
------Create the class object using .jnew function.
------Call the desired java function using .jcall function.
-------------------------------------------------------
P1. Hello world program
-----------------------------------------------------
1. I have created a simple helloworld. java file as follows:

public class helloworld {
public void SayHello(String str)
{
System.out.println("Hello how are you dear");
System.out.println(str);
}
}

2. Compiled this java file: javac helloworld.java. It will create the
class file with the name helloworld.class

3. I have provided the path in the CLASSPATH variable. ( i.e.
in .bashrc file)

Follow the following steps for calling the java function from the R:
1. Open the R console and load the “rJava” library using the function
library(rJava)
2. Initialize the JVM by using the function .jinit()
3. Create the object of the class “helloworld” by using the function
s<-.jnew(“helloworld”)
If the class file is found then it will create the object of that
class and you can type “s” on the R console.Output will be something
like this:

> obj<-.jnew("helloworld")
> obj
[1] "Java-Object{helloworld@3cb89838}"

4. Now call the function “ SayHello” function defined inside the class
helloworld as follows:

> obj$SayHello("Som")
Hello how are you dear
Som
>

Although it is recommended that this is not the efficient method of
calling the function. It is very slow. So you can use .jcall function
provided by the rJava package.
For example: You can call the “SayHello” function using .jcall as
follows:

>result<-.jcall(obj,"V","SayHello","Som")
Hello how are you dear/n
Som


The description of parameter passed to the .jcall function is as
follows:

(i)First parameter--->Object of the class which you have created
using .jnew function
(ii)Second Parameter--->The return type of the function. V for void, I
for integer, D for double, [I for array of integer, [D for array of
doubles, [[D for two dimensional arrays(matrix)
(iii)Third parameter--->The method name which you wish to call
(iv)Fourth parameter--->Arguments that is required by the java
function you are calling

-----------------------------------------------------------------------
P2: Passing Array from R to java ( We will be passing array from the R
to java and we will be printing them
----------------------------------------------------------------------

(A) Java Side code:

Filename: passingArrays.java

public class passingArrays
{
public void ArrayFromR2Java(int len, int a[])
{
for(int i=0;i<len;i++)
{
System.out.println(a[i]);
}
}
}

Compile the file: javac passingArrays.java

(B) R side code

library(rJava)
.jinit()
obj<-.jnew("passingArrays") # give the fully qualified path to the
class file
vec<-c(1,2,3)# defining vector
res<-.jcall(obj,"V","ArrayFromR2Java",length(vec),as.integer(vec))

the output will be
1
2
3

----------------------------------------------------------------------------
P3: Passing array from Java to R
------------------------------------------------------------------------------
(A) Java side code:

Here we will be sending the number of elements from R. Java function
will take the length and will create and populate the array and send
it back to R.

public class passingArrays
{
public int[] ArrayFromJava2R(int length)
{
int a[] = new int[length];
for(int i=0;i<length;i++)
a[i] = i;
return a;
}
}
(B) R side code:

library(rJava)
.jinit()
obj<-.jnew("passingArrays") # give the fully qualified path to the
class file
res<-.jcall(obj,"[I","ArrayFromJava2R",as.integer(5))

The ouput will be:
> res
[1] 0 1 2 3 4

----------------------------------------------------------------------
P4. Squaring the elements of array
---------------------------------------------------------------------
(A) Java side code:
//Array and its length will be sent from the R, and after squaring
each elements in the R, the array will be sent back to the R
public class passingArrays
{
public int[] DoSquare(int len, int a[])
{
for(int i=0;i<len;i++)
{
a[i] = a[i] * a[i];
}
return a;
}
}
(B) R side code:

library(rJava)
.jinit()
obj<-.jnew("passingArrays") # give the fully qualified path to the
class file
vec<-c(1,2,3)
res<-res<-.jcall(obj,"[I","DoSquare",length(vec),as.integer(vec))

The output will be:
> res
[1] 1 4 9

-----------------------------------------------------------------
P5: Concatenating two arrays
----------------------------------------------------------------
(A) Java side code:

//Send two arrays and their lengths from R,after concatenating the
arrays,it will be sent back to R

public class passingArrays
{
public int[] ConcatArrays(int len1, int arr1[], int len2, int
arr2[])
{
int result[] = new int[len1 + len2];
for(int i=0;i<(len1+len2);i++)
{
if(i <len1)
result[i] = arr1[i];
else
result[i] = arr2[i-len1];
}
return result;
}
}
(B) R side code:

library(rJava)
.jinit()
obj<-.jnew("passingArrays") # give the fully qualified path to the
class file
vec1<-c(1,2,3)
vec2<-c(4,5,6,7,8)
res<-.jcall(obj,"[I","ConcatArrays",length(vec1),as.integer(vec1),length(vec2),as.integer(vec2))

The output will be:
> res
[1] 1 2 3 4 5 6 7 8

--------------------------------------------------------------------------------------
P6: Passing Matrix from Java to R
---------------------------------------------------------------------------------
(A) Java side code:
public class passingArrays
{
public double[][] PassMatrixFromJava2R()
{
double[][]retArr=new double[3][4];
for(int i=0;i<3;i++)
for(int j=0;j<4;j++)
retArr[i][j]=(i*1000)+j;
return(retArr);
}
}

(B) R side code:

library(rJava)
.jinit()
obj<-.jnew("passingArrays") # give the fully qualified path to the
class file
res<-.jcall(obj,"[[D","PassMatrixFromJava2R")
mat=sapply(res,.jevalArray)

The output will be :
> mat
[,1] [,2] [,3]
[1,] 0 1000 2000
[2,] 1 1001 2001
[3,] 2 1002 2002
[4,] 3 1003 2003

In the next post we can see some more problems like matrix
multiplication, Gibbs phenomena etc.

Regards,
Som Shekhar
Reply all
Reply to author
Forward
0 new messages