
prerna.reactor.frame.r.util.RJavaJriTranslator Maven / Gradle / Ivy
The newest version!
package prerna.reactor.frame.r.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.rosuda.JRI.REXP;
import org.rosuda.JRI.RFactor;
import org.rosuda.JRI.RVector;
import org.rosuda.JRI.Rengine;
import org.rosuda.REngine.Rserve.RConnection;
import prerna.sablecc2.om.PixelDataType;
import prerna.sablecc2.om.nounmeta.NounMetadata;
import prerna.util.Constants;
public class RJavaJriTranslator extends AbstractRJavaTranslator {
private static ConcurrentMap genEngineLock = new ConcurrentHashMap();
private static final Logger classLogger = LogManager.getLogger(RJavaJriTranslator.class);
Rengine engine;
/**
* Constructor only accessible through the package
* Please use the insight object or the RJavaTranslatorFactory
* to get the correct instance
*/
public RJavaJriTranslator() {
}
/**
* Create a new engine if it doesn't exist
* @return
*/
private static synchronized Rengine generateEngine() {
Rengine retEngine = Rengine.getMainEngine();
if(retEngine != null) {
return retEngine;
}
String OS = java.lang.System.getProperty("os.name").toLowerCase();
if(!OS.contains("win")) {
// not windows - pass in vanilla
return new Rengine(new String[]{"--vanilla"}, true, null);
} else {
// windows only works if you pass in null... word...
return new Rengine(null, true, null);
}
}
private static synchronized ReentrantLock getEngineLock(String id) {
genEngineLock.putIfAbsent(id, new ReentrantLock());
return genEngineLock.get(id);
}
/**
* This will start R, only if it has not already been started
* In this case we are starting an engine for JRI
*/
@Override
public void startR() {
Rengine retEngine = Rengine.getMainEngine();
if(retEngine == null && this.insight != null) {
if(this.insight.getVarStore().containsKey(R_ENGINE)) {
retEngine = (Rengine) this.insight.getVarStore().get(R_ENGINE).getValue();
}
}
if(retEngine == null) {
logger.info("R Connection has not been defined yet...");
} else {
logger.info("Retrieving existing R Connection...");
}
if(retEngine == null) {
try {
ReentrantLock lock = getEngineLock("genId");
try {
lock.lock();
// start the R Engine
logger.info("Starting R Connection... ");
retEngine = generateEngine();
logger.info("Successfully created R Connection... ");
// load all the libraries
Object ret = retEngine.eval("library(splitstackshape);");
if(ret == null) {
throw new ClassNotFoundException("Package splitstackshape could not be found!");
} else {
logger.info("Successfully loaded packages splitstackshape");
}
// data table
ret = retEngine.eval("library(data.table);");
if(ret == null) {
throw new ClassNotFoundException("Package data.table could not be found!");
} else {
logger.info("Successfully loaded packages data.table");
}
// reshape2
ret = retEngine.eval("library(reshape2);");
if(ret == null) {
throw new ClassNotFoundException("Package reshape2 could not be found!");
} else {
logger.info("Successfully loaded packages reshape2");
}
// stringr
ret = retEngine.eval("library(stringr);");
if(ret == null) {
throw new ClassNotFoundException("Package stringr could not be found!");
} else {
logger.info("Successfully loaded packages stringr");
}
// lubridate
ret = retEngine.eval("library(lubridate);");
if(ret == null) {
throw new ClassNotFoundException("Package lubridate could not be found!");
} else {
logger.info("Successfully loaded packages lubridate");
}
// dplyr
ret = retEngine.eval("library(dplyr);");
if(ret == null) {
throw new ClassNotFoundException("Package dplyr could not be found!");
} else {
logger.info("Successfully loaded packages dplyr");
}
} finally {
lock.unlock();
}
// set the rengine
if(this.insight != null) {
this.insight.getVarStore().put(IRJavaTranslator.R_ENGINE, new NounMetadata(retEngine, PixelDataType.R_ENGINE));
}
// initialize the r environment
this.engine = retEngine;
setMemoryLimit();
} catch(NullPointerException e) {
classLogger.error(Constants.STACKTRACE, e);
System.out.println("Could not connect to R JRI. Please make sure paths are accurate");
throw new IllegalArgumentException("Could not connect to R JRI. Please make sure paths are accurate");
} catch(ClassNotFoundException e) {
System.out.println("ERROR ::: " + e.getMessage() + "\nMake sure you have all the following libraries installed:\n"
+ "1)splitstackshape\n"
+ "2)data.table\n"
+ "3)reshape2\n"
+ "4)stringr\n"
+ "5)lubridate\n"
+ "6)dplyr\n");
classLogger.error(Constants.STACKTRACE, e);
throw new IllegalArgumentException("ERROR ::: " + e.getMessage() + "\nMake sure you have all the following libraries installed:\n"
+ "1)splitstackshape\n"
+ "2)data.table\n"
+ "3)reshape2\n"
+ "4)stringr\n"
+ "5)lubridate\n"
+ "6)dplyr\n");
} catch(Exception e) {
classLogger.error(Constants.STACKTRACE, e);
}
}
this.engine = retEngine;
initREnv();
}
@Override
public Object executeR(String rScript) {
try {
//rScript = rScript.replaceAll("\"", "\\\"");
//rScript = rScript.replaceAll("'", "\\'");
rScript = encapsulateForEnv(rScript);
logger.debug("Running rscript > " + rScript);
REXP rexp = engine.eval(rScript);
if(rexp == null) {
logger.info("Hmmm... REXP returned null for script = " + rScript);
}
return rexp;
} catch (Exception e) {
classLogger.error(Constants.STACKTRACE, e);
}
return null;
}
@Override
public void executeEmptyR(String rScript) {
//rScript = rScript.replaceAll("\"", "\\\"");
//rScript = rScript.replaceAll("'", "\\'");
rScript = encapsulateForEnv(rScript);
logger.debug("Running rscript > " + rScript);
engine.eval(rScript, false);
}
@Override
public Object executeRDirect(String rScript) {
try {
logger.debug("Running rscript > " + rScript);
REXP rexp = engine.eval(rScript);
if(rexp == null) {
logger.info("Hmmm... REXP returned null for script = " + rScript);
}
return rexp;
} catch (Exception e) {
classLogger.error(Constants.STACKTRACE, e);
}
return null;
}
@Override
public void executeEmptyRDirect(String rScript) {
logger.debug("Running rscript > " + rScript);
engine.eval(rScript, false);
}
@Override
public boolean cancelExecution() {
// TODO >>>timb: R - need to complete cancel exec (later)
return false;
}
@Override
public String getString(String script) {
script = encapsulateForEnv(script);
REXP val = engine.eval(script);
if(val != null) {
return val.asString();
}
return null;
}
@Override
public String[] getStringArray(String script) {
script = encapsulateForEnv(script);
REXP val = engine.eval(script);
if(val != null) {
return val.asStringArray();
}
return null;
}
/**
* This method is used to get the column types of a frame
* Need to account for R where factors come in as ordered factors...
* Have portions in other places to pick up "ordered" and "factor" as both factor
* @param frameName
*/
@Override
public String[] getColumnTypes(String frameName) {
String script = "sapply(" + frameName + ", class);";
script = encapsulateForEnv(script);
REXP val = engine.eval(script);
if(val != null) {
int typeInt = val.getType();
if(typeInt == REXP.XT_ARRAY_STR || typeInt == REXP.XT_STR) {
return val.asStringArray();
} else if(typeInt == REXP.XT_VECTOR) {
RVector vector = val.asVector();
int vSize = vector.size();
String[] arr = new String[vSize];
for(int i = 0; i < vSize; i++) {
Object v = vector.get(i);
if(v instanceof REXP) {
REXP vRexp = (REXP) v;
int vType = vRexp.getType();
if(vType == REXP.XT_STR) {
arr[i] = vRexp.asString();
} else if(vType == REXP.XT_ARRAY_STR) {
arr[i] = vRexp.asStringArray()[0];
}
} else {
arr[i] = v.toString();
}
}
return arr;
}
}
return null;
}
@Override
public int getInt(String script) {
script = encapsulateForEnv(script);
REXP val = engine.eval(script);
if(val != null) {
return val.asInt();
}
return 0;
}
@Override
public int[] getIntArray(String script) {
script = encapsulateForEnv(script);
REXP val = engine.eval(script);
if(val != null) {
return val.asIntArray();
}
return null;
}
@Override
public double getDouble(String script) {
script = encapsulateForEnv(script);
REXP val = engine.eval(script);
if(val != null) {
return val.asDouble();
}
return 0;
}
@Override
public double[] getDoubleArray(String script) {
script = encapsulateForEnv(script);
REXP val = engine.eval(script);
if(val != null) {
return val.asDoubleArray();
}
return null;
}
@Override
public double[][] getDoubleMatrix(String script) {
script = encapsulateForEnv(script);
REXP val = engine.eval(script);
if(val != null) {
return val.asDoubleMatrix();
}
return null;
}
@Override
public boolean getBoolean(String script) {
script = encapsulateForEnv(script);
REXP val = engine.eval(script);
if(val != null) {
return val.asBool().isTRUE();
}
return false;
}
@Override
public Object getFactor(String script) {
script = encapsulateForEnv(script);
REXP val = engine.eval(script);
if(val != null) {
return val.asFactor();
}
return null;
}
@Override
public Map getHistogramBreaksAndCounts(String script) {
script = encapsulateForEnv(script);
REXP histR = engine.eval(script);
if(histR != null) {
RVector vectorR = histR.asVector();
double[] breaks = vectorR.at("breaks").asDoubleArray();
int[] counts = vectorR.at("counts").asIntArray();
Map retMap = new HashMap();
retMap.put("breaks", breaks);
retMap.put("counts", counts);
return retMap;
}
return null;
}
@Override
public Map flushFrameAsTable(String framename, String[] colNames) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy