Assigning a multidimensional array from Java to R through Rserve

I am using Java / R / Rserve for a project. I ran into the problem of moving a multidimensional array from Java to the R workspace for computation. Until now, the assign method of an RConnection object RConnection only allowed the following: byte[], double[], int[], REXP, String,and String[] .

I got around this by creating a loop in Java and passing the variables individually. Although this works, it looks ugly and inefficient.

 RConnection c = new RConnection(); c.eval("x <- matrix(0,nrow=dimX[1],ncol=dimX[2])"); for (int i = 0; i < dimX[0]; i++){ c.assign("i",Integer.toString(i+1)); c.eval("i <- as.numeric(i)"); for (int j = 0; j < dimX[1]; j++){ c.assign("j",Integer.toString(j+1)); c.eval("j <- as.numeric(j)"); c.assign("tmp", Double.toString(XOBS[i][j])); c.eval("x[i,j] <- as.numeric(tmp)"); } } 

The document for Rserve at http://www.rforge.net/Rserve/dist/JRclient/JavaDoc/org/rosuda/JRclient/REXP.html seems outdated, and the examples for Rserve are pretty limited. Can someone give me a suggestion on how to improve this code?

thanks

+4
source share
4 answers

I found one solution and just made it a little more friendly, a link to the source is also attached.

Comments: This is a ready-to-use utility method. It is based on the JRI, which is now part of rJava.

A source:
http://www.lbgi.fr/wikili/index.php/JRI

  /** * Creates and assigns a matrix object in R from 2D table of double * * @param rEngine the R instance used * @param sourceArray the 2D table of double * the matrix must have always the same column number on every row * @param nameToAssignOn the R object name * @return R matrix instance or null if R return an error */ public static REXP assignAsRMatrix(Rengine rEngine, double[][] sourceArray, String nameToAssignOn) { if (sourceArray.length == 0) { return null; } rEngine.assign(nameToAssignOn, sourceArray[0]); REXP resultMatrix = rEngine.eval(nameToAssignOn + " <- matrix( " + nameToAssignOn + " ,nr=1)"); for (int i = 1; i < sourceArray.length; i++) { rEngine.assign("temp", sourceArray[i]); resultMatrix = rEngine.eval(nameToAssignOn + " <- rbind(" + nameToAssignOn + ",matrix(temp,nr=1))"); } return resultMatrix; } 
+2
source

For reference (the method may not be available even when the question is asked):

 REXP REXP.createDoubleMatrix(double[][] arg); 
+2
source

what if you do something like this (changing line and line numbers for your needs)?

 RConnection c = new RConnection(); double[][] test = { { 1.0D, 2.0D }, { 3.0D, 4.0D } }; c.assign("res", test[0]); for (int i = 1; i < 2; i++) { c.assign("tmp", test[i]); c.eval("res<-rbind(res,tmp)"); } REXP x = c.eval("sum(res)"); System.out.println(x.asString()); 

this returns 10, as expected, but however, it

 String s = c.eval("rowSums(res)").asString(); System.out.println(s); 

does not print what he suggested, it just returns 3 , maybe my installed Ubuntu RServe is broken and cannot print everything after a space in the result line 3 7 :

 > rowSums(d) c1 c2 3 7 

and I can also find good examples :(

+1
source

You can:

  • smooth the array into a whole row vector so that

    a11 a12

    a21 a22

=>

 flat_array = new int[] {a11, a12, a21, a22} 
  • Assign a local variable for example:

    rEngine.assign (". values", flat_array);

  • Call the function R, which makes the matrix (or frame) global, for example:

In R:

  make.matrix <- function(nrows, ncols, values) { value_mat <- matrix(values, nrow=nrows, ncol=ncols, byrow=TRUE) temp.res <<- res res } 

In Java:

 rEngine.eval("make.matrix(2,2,.values)"); 
  • You now have a matrix in temp.res
0
source

Source: https://habr.com/ru/post/1442336/


All Articles