Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* *##% Nuiton Java-2-R library
* Copyright (C) 2006 - 2009 CodeLutin
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* . ##%*/
package org.nuiton.j2r.jni;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.j2r.REngine;
import org.nuiton.j2r.REngineAbstract;
import org.nuiton.j2r.RException;
import org.nuiton.j2r.RInstructions;
import org.nuiton.j2r.types.RDataFrame;
import org.nuiton.j2r.types.RList;
import org.rosuda.JRI.REXP;
import org.rosuda.JRI.Rengine;
/**
* RJniEngine.java
*
* Created: 22 aout 2006
*
* @author Arnaud Thimel
*/
public class RJniEngine extends REngineAbstract implements REngine {
private Log log = LogFactory.getLog(RJniEngine.class);
/**
* Rengine is made to be static
*/
private static Rengine engine;
/**
* If true, commit each R instruction on the fly, if false, commit only when
* the commit() method is called.
*/
private Boolean autocommit = true;
/**
* List used to store all the R instructions when not in autocommit mode
* (when autocommit == false).
*/
private List rInstructions = new LinkedList();
/**
* Initialize the R engine.
*
* @return true if initialized, false otherwise.
*
* @see org.nuiton.j2r.REngine#init()
*/
@Override
public boolean init() {
if (engine == null) {
try {
String[] args = {"--no-save"};
//Set the property so that rJava does not make a System.exit(1)
//System.setProperty("jri.ignore.ule", "yes");
//jriLoaded is false is rJava did not find jri library
if (!Rengine.jriLoaded) {
if (log.isErrorEnabled()) {
log.error(
"Cannot find jri library, make sure it is correctly installed");
}
return false;
}
engine = new Rengine(args, false, null);
if (!engine.waitForR()) {
if (log.isErrorEnabled()) {
log.error("Cannot load the R engine");
}
return false;
}
} catch (Exception eee) {
log.error("An error occured during R/JNI initialization.",
eee);
return false;
}
}
return true;
}
/**
* Evaluate a R expression in R and get back the result.
*
* @param expr the R expression to evaluate.
*
* @return the result of the R expression.
*
* @see org.nuiton.j2r.REngine#eval(java.lang.String)
*/
@Override
public Object eval(String expr) throws RException {
REXP result = null;
if (log.isDebugEnabled()) {
log.debug(String.format(RInstructions.RTRY, expr));
}
//encapsulate the R expression in a try method/object to get the R error
//message if thrown
result = engine.eval(String.format(RInstructions.RTRY, expr));
if (result.getAttribute(RInstructions.ATTRIBUTE_CLASS) != null) {
//if the "class" attribute of the R expression is "try-error"
//throw a new exception with the error message from R.
String klass =
result.getAttribute(RInstructions.ATTRIBUTE_CLASS).asString();
if (klass.equals(RInstructions.CLASS_ERROR)) {
throw new RException(result.asString());
}
}
return convertResult(result);
}
/**
* Convert the result from an R expression to a java object.
*
* @param rexp the R expression to convert.
*
* @return the java object corresponding to the R expression.
*/
private Object convertResult(REXP rexp) {
if (rexp == null) {
log.debug("Null returned");
return null;
}
if (log.isDebugEnabled()) {
log.debug("Converting : " + rexp.toString());
}
int type = rexp.getType();
Object result = null;
switch (type) {
case REXP.XT_STR:
//If string return the r expression as string
result = rexp.asString();
break;
case REXP.XT_INT:
//if integer, return the rexp as integer
result = (Integer) rexp.asInt();
break;
case REXP.XT_ARRAY_INT:
int[] array = rexp.asIntArray();
Integer[] bigArray = new Integer[array.length];
for (int i = 0; i < array.length; i++) {
bigArray[i] = (Integer) array[i];
}
result = bigArray;
//Check if only one integer, return an integer.
if (array.length == 1) {
result = (Integer) array[0];
}
break;
case REXP.XT_ARRAY_DOUBLE:
//if double array, return the rexp as double array.
double[] doublearray = rexp.asDoubleArray();
Double[] bigdoublearray = new Double[doublearray.length];
for (int i = 0; i < doublearray.length; i++) {
bigdoublearray[i] = (Double) doublearray[i];
}
result = bigdoublearray;
//Check if only one double, return a double.
if (doublearray.length == 1) {
result = doublearray[0];
}
break;
case REXP.XT_BOOL:
//if boolean, return rexp as boolean
result = rexp.asBool().isTRUE();
break;
case REXP.XT_DOUBLE:
//if double, return rexp as double
//Get a double array
result = rexp.asDoubleArray();
//return only the first element.
result = (Double) ((double[]) result)[0];
break;
case REXP.XT_NULL:
//if null return null
result = null;
break;
case REXP.XT_ARRAY_BOOL_INT:
//if boolean array, get the rexp as integer array (full of 0 and 1)
result = rexp.asIntArray();
int[] integers = ((int[]) result);
Boolean[] booleanArray = new Boolean[integers.length];
//transform the 0 and 1 in true and false in a boolean array
for (int i = 0; i < integers.length; i++) {
if (integers[i] == 1) {
booleanArray[i] = Boolean.TRUE;
} else {
booleanArray[i] = Boolean.FALSE;
}
}
//check if there is only a boolean, return a boolean
if (booleanArray.length == 1) {
result = booleanArray[0];
} else {
result = booleanArray;
}
//return the boolean array
break;
case REXP.XT_ARRAY_STR:
//if is a string array, return as a string array.
result = rexp.asStringArray();
break;
case REXP.XT_VECTOR:
//dataframes, lists and vectors are recognized as vectors.
//get the class of the vector (to successfully detect data.frames)
String klass = "";
REXP klassAttribute = rexp.getAttribute(
RInstructions.ATTRIBUTE_CLASS);
if (klassAttribute != null) {
klass = klassAttribute.asString();
}
//get REXP asList to successfully detect lists.
org.rosuda.JRI.RList list = rexp.asList();
if (klass.equals(RInstructions.CLASS_DATAFRAME)) {
//if rexp is a data.frame
RDataFrame temp = new RDataFrame((REngine) this);
//create the data list.
List> data =
new ArrayList>();
//get rexp as a list (data.frame is a list of vectors)
org.rosuda.JRI.RList dataList = rexp.asList();
for (int i = 0; i < dataList.keys().length; i++) {
//for each vector, create a list and fill it with the
//content of the vector.
List