Author: jcouteau Date: 2009-08-21 10:24:26 +0200 (Fri, 21 Aug 2009) New Revision: 142 Added: trunk/src/main/java/org/nuiton/j2r/RInstructions.java Modified: trunk/src/main/java/org/nuiton/j2r/REngineAbstract.java trunk/src/main/java/org/nuiton/j2r/jni/RJniEngine.java trunk/src/main/java/org/nuiton/j2r/net/RNetEngine.java trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java trunk/src/main/java/org/nuiton/j2r/types/RList.java Log: Centralize R commands. Modified: trunk/src/main/java/org/nuiton/j2r/REngineAbstract.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/REngineAbstract.java 2009-08-20 15:09:52 UTC (rev 141) +++ trunk/src/main/java/org/nuiton/j2r/REngineAbstract.java 2009-08-21 08:24:26 UTC (rev 142) @@ -14,7 +14,6 @@ * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * <http://www.gnu.org/licenses/lgpl-3.0.html>. ##%*/ - package org.nuiton.j2r; import java.io.File; @@ -44,7 +43,7 @@ @Override public void loadRData(File directory) throws RException { setwd(directory); - voidEval("load(\".RData\")"); + voidEval(RInstructions.LOAD_RDATA); } /** @@ -60,7 +59,7 @@ @Override public void loadRData(File directory, String fileName) throws RException { setwd(directory); - voidEval("load(\""+fileName+".RData\")"); + voidEval(String.format(RInstructions.LOAD_RDATA_FILE, fileName)); } /** @@ -74,7 +73,7 @@ @Override public void saveRData(File directory) throws RException { setwd(directory); - voidEval("save.image()"); + voidEval(RInstructions.SAVE_IMAGE); } /** @@ -89,7 +88,7 @@ @Override public void saveRData(File directory, String fileName) throws RException { setwd(directory); - voidEval("save.image(file=\""+fileName+"\")"); + voidEval(String.format(RInstructions.SAVE_IMAGE_FILE,fileName)); } /** @@ -101,8 +100,8 @@ */ @Override public void setwd(File directory) throws RException { - voidEval("setwd(\"" + - directory.getAbsolutePath().replaceAll("\\\\", "/") + "\")"); + voidEval(String.format(RInstructions.SET_WORKING_DIRECTORY, + directory.getAbsolutePath().replaceAll("\\\\", "/"))); } /** @@ -113,7 +112,7 @@ */ @Override public File getwd() throws RException { - String directory = (String) eval("getwd()"); + String directory = (String) eval(RInstructions.GET_WORKING_DIRECTORY); return new File(directory); } @@ -129,8 +128,7 @@ */ @Override public void dput(String rObject, String outputFileName) throws RException { - String rInstruction = "dput(%s,file=\"%s\")"; - voidEval(String.format(rInstruction, rObject, outputFileName)); + voidEval(String.format(RInstructions.DPUT, rObject, outputFileName)); } /** @@ -146,8 +144,7 @@ */ @Override public void dget(String rObject, String inputFileName) throws RException { - String rInstruction = "%s <- dget(\"%s\")"; - voidEval(String.format(rInstruction, rObject, inputFileName)); + voidEval(String.format(RInstructions.DGET, rObject, inputFileName)); } @@ -166,9 +163,8 @@ File workingdir = getwd(); //Set the destination working directory setwd(outputFile.getParentFile()); - String rInstruction = "dput(%s,file=\"%s\")"; //Save the R object. - voidEval(String.format(rInstruction, rObject, outputFile.getName())); + voidEval(String.format(RInstructions.DPUT, rObject, outputFile.getName())); //Go back to previous working directory setwd(workingdir); } @@ -189,9 +185,8 @@ File workingdir = getwd(); //Set the source working directory setwd(inputFile.getParentFile()); - String rInstruction = "%s <- dget(\"%s\")"; //Load the inputFile - voidEval(String.format(rInstruction, rObject, inputFile.getName())); + voidEval(String.format(RInstructions.DGET, rObject, inputFile.getName())); //Go back to the previous working directory setwd(workingdir); } @@ -205,7 +200,7 @@ */ @Override public void remove(String rObject) throws RException { - voidEval("remove(" + rObject + ")"); + voidEval(String.format(RInstructions.REMOVE, rObject)); } /** @@ -255,7 +250,7 @@ */ @Override public String[] ls() throws RException { - String[] rObjects = (String[]) eval("ls()"); + String[] rObjects = (String[]) eval(RInstructions.LS); return rObjects; } @@ -267,7 +262,7 @@ */ @Override public void clearSession() throws RException { - voidEval("rm(list=ls())"); + voidEval(RInstructions.CLEAR_SESSION); } /** Added: trunk/src/main/java/org/nuiton/j2r/RInstructions.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/RInstructions.java (rev 0) +++ trunk/src/main/java/org/nuiton/j2r/RInstructions.java 2009-08-21 08:24:26 UTC (rev 142) @@ -0,0 +1,53 @@ +package org.nuiton.j2r; + +/** + * + * @author couteau + */ +public interface RInstructions { + + /** + * Load the .RData file located in the working directory + */ + public static final String LOAD_RDATA = "load(\".RData\")"; + /** + * Load the file.RData file located in the working directory + */ + public static final String LOAD_RDATA_FILE = "load(\"%s.RData\")"; + public static final String SAVE_IMAGE = "save.image()"; + public static final String SAVE_IMAGE_FILE = "save.image(file=\"%s\")"; + public static final String SET_WORKING_DIRECTORY = "setwd(\"%s\")"; + public static final String GET_WORKING_DIRECTORY = "getwd()"; + public static final String DPUT = "dput(%s,file=\"%s\")"; + public static final String DGET = "%s <- dget(\"%s\")"; + public static final String REMOVE = "remove(%s)"; + public static final String LS = "ls()"; + public static final String CLEAR_SESSION = "rm(list=ls())"; + public static final String RTRY = "try(%s,silent=TRUE)"; + public static final String CLASS_ERROR = "try-error"; + public static final String CLASS_DATAFRAME = "data.frame"; + public static final String ATTRIBUTE_CLASS = "class"; + public static final String ATTRIBUTE_NAMES = "names"; + public static final String ATTRIBUTE_ROWNAMES = "row.names"; + public static final String GET_ROW_NAMES = "row.names(%s)"; + public static final String GET_ROW_NAME = "row.names(%s)[%s]"; + public static final String SET_ROW_NAMES = "row.names(%s)<-c(%s)"; + public static final String SET_ROW_NAME = "row.names(%s)[%s]<-\"%s\""; + public static final String GET_NAMES = "names(%s)"; + public static final String GET_NAME = "names(%s)[%s]"; + public static final String SET_NAMES = "names(%s)<-c(%s)"; + public static final String SET_NAME = "names(%s)[%s]<-\"%s\""; + public static final String SET_ATTRIBUTE = "attr(%s,\"%s\")<-%s"; + public static final String GET_ATTRIBUTE = "attr(%s,\"%s\")"; + public static final String LENGTH = "length(%s)"; + public static final String LENGTH_COLUMN = "length(%s[,%s])"; + public static final String LENGTH_ATTRIBUTES = "length(attributes(%s))"; + public static final String GET_ATTRIBUTE_NAME = "names(attributes(%s))[%s]"; + public static final String GET_LIST_ITEM = "%s[[%s]]"; + public static final String GET_DATAFRAME_ITEM ="%s[%s,%s]"; + public static final String SET_DATAFRAME_ITEM ="%s[%s,%s]<-%s"; + public static final String SET_LIST_ITEM = "%s[[%s]]<-%s"; + public static final String TRUE = "TRUE"; + public static final String FALSE = "FALSE"; + public static final String AS_INTEGER="as.integer(%s)"; +} Modified: trunk/src/main/java/org/nuiton/j2r/jni/RJniEngine.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/jni/RJniEngine.java 2009-08-20 15:09:52 UTC (rev 141) +++ trunk/src/main/java/org/nuiton/j2r/jni/RJniEngine.java 2009-08-21 08:24:26 UTC (rev 142) @@ -26,6 +26,7 @@ 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; @@ -56,8 +57,6 @@ */ private List<String> rInstructions = new LinkedList<String>(); - private String evaluation = "try(%s,silent=TRUE)"; - /** * Initialize the R engine. * @@ -99,16 +98,17 @@ public Object eval(String expr) throws RException { REXP result = null; if (log.isDebugEnabled()) { - log.debug(String.format(evaluation,expr)); + 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(evaluation,expr)); - if (result.getAttribute("class") != null) { + 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 classe = result.getAttribute("class").asString(); - if (classe.equals("try-error")) { + String klass = + result.getAttribute(RInstructions.ATTRIBUTE_CLASS).asString(); + if (klass.equals(RInstructions.CLASS_ERROR)) { throw new RException(result.asString()); } } @@ -210,13 +210,14 @@ //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("class"); + 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("data.frame")) { + if (klass.equals(RInstructions.CLASS_DATAFRAME)) { //if rexp is a data.frame RDataFrame temp = new RDataFrame((REngine) this); @@ -233,7 +234,7 @@ REXP tempREXP = dataList.at(i); Object[] convertedREXP = (Object[]) convertResult( tempREXP); - templist=Arrays.asList(convertedREXP); + templist = Arrays.asList(convertedREXP); //add this list to the data list. data.add(templist); @@ -242,11 +243,11 @@ //gotten from rexp. It has no variable name so throws a //RException. temp = new RDataFrame((REngine) this, rexp.getAttribute( - "names").asStringArray(), - rexp.getAttribute("row.names").asStringArray(), + RInstructions.ATTRIBUTE_NAMES).asStringArray(), + rexp.getAttribute(RInstructions.ATTRIBUTE_ROWNAMES).asStringArray(), data, ""); result = temp; - } else if (list!=null) { + } else if (list != null) { RList temp = new RList((REngine) this); List<Object> data = new ArrayList<Object>(); org.rosuda.JRI.RList dataList = rexp.asList(); @@ -264,7 +265,7 @@ //RException. try { temp = new RList( - rexp.getAttribute("names").asStringArray(), + rexp.getAttribute(RInstructions.ATTRIBUTE_NAMES).asStringArray(), data, (REngine) this, ""); } catch (RException re) { //don't propagate the error as it is normal. Log it for debug. @@ -322,14 +323,14 @@ //encapsulate the R expression in a try method/object to get the R error //message if thrown if (log.isDebugEnabled()) { - log.debug(String.format(evaluation,expr)); + log.debug(String.format(RInstructions.RTRY, expr)); } - REXP r = engine.eval(String.format(evaluation,expr)); - if (r.getAttribute("class") != null) { + REXP r = engine.eval(String.format(RInstructions.RTRY, expr)); + if (r.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 classe = r.getAttribute("class").asString(); - if (classe.equals("try-error")) { + String classe = r.getAttribute(RInstructions.ATTRIBUTE_CLASS).asString(); + if (classe.equals(RInstructions.CLASS_ERROR)) { throw new RException(r.asString()); } } Modified: trunk/src/main/java/org/nuiton/j2r/net/RNetEngine.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/net/RNetEngine.java 2009-08-20 15:09:52 UTC (rev 141) +++ trunk/src/main/java/org/nuiton/j2r/net/RNetEngine.java 2009-08-21 08:24:26 UTC (rev 142) @@ -34,6 +34,7 @@ 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.rosuda.REngine.REXP; import org.rosuda.REngine.REXPMismatchException; @@ -67,8 +68,6 @@ */ private List<String> rInstructions = new LinkedList<String>(); - private String evaluation = "try(%s,silent=TRUE)"; - /** * Initialize the engine. * @@ -150,10 +149,10 @@ //Encapsulate the R expression to get back the R error message //if thrown. if (log.isDebugEnabled()) { - log.debug(String.format(evaluation,expr)); + log.debug(String.format(RInstructions.RTRY, expr)); } - result = conn.eval(String.format(evaluation,expr)); - if (result.inherits("try-error")) { + result = conn.eval(String.format(RInstructions.RTRY, expr)); + if (result.inherits(RInstructions.CLASS_ERROR)) { //If the R expression is an error, throw an expression with the //real R error message throw new RException(result.asString()); @@ -255,7 +254,7 @@ } else if (rexp.isNull()) { //if rexp contains a null R expression return null; - } else if (rexp.inherits("data.frame")) { + } else if (rexp.inherits(RInstructions.CLASS_DATAFRAME)) { //if rexp is a data.frame RDataFrame temp = new RDataFrame((REngine) this); @@ -279,8 +278,8 @@ //gotten from rexp. It has no variable name so throws a //RException. temp = new RDataFrame((REngine) this, rexp.getAttribute( - "names").asStrings(), - rexp.getAttribute("row.names").asStrings(), + RInstructions.ATTRIBUTE_NAMES).asStrings(), + rexp.getAttribute(RInstructions.ATTRIBUTE_ROWNAMES).asStrings(), data, ""); result = temp; } else if (rexp.isList()) { @@ -301,7 +300,8 @@ //gotten from rexp. It has no variable name so throws a //RException. try { - temp = new RList(rexp.getAttribute("names").asStrings(), + temp = new RList(rexp.getAttribute( + RInstructions.ATTRIBUTE_NAMES).asStrings(), data, (REngine) this, ""); } catch (RException re) { //don't propagate the error as it is normal. Log it for debug. @@ -357,12 +357,12 @@ } else { try { if (log.isDebugEnabled()) { - log.debug(String.format(evaluation,expr)); + log.debug(String.format(RInstructions.RTRY, expr)); } //Encapsulate the R expression to get back the R error message //if thrown. - REXP r = conn.eval(String.format(evaluation,expr)); - if (r.inherits("try-error")) { + REXP r = conn.eval(String.format(RInstructions.RTRY, expr)); + if (r.inherits(RInstructions.CLASS_ERROR)) { //If the R expression is an error, throw an expression with the //real R error message throw new RException(r.asString()); Modified: trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java 2009-08-20 15:09:52 UTC (rev 141) +++ trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java 2009-08-21 08:24:26 UTC (rev 142) @@ -32,6 +32,7 @@ import org.apache.commons.logging.LogFactory; import org.nuiton.j2r.REngine; import org.nuiton.j2r.RException; +import org.nuiton.j2r.RInstructions; /** * Java implementation of the R data.frame @@ -47,10 +48,6 @@ private List<String> rowNames; //Vector containing the vectors of the data.frame private List<List<? extends Object>> data; - private String getRowNamesString = "row.names(%s)"; - private String getRowNameString = "row.names(%s)[%s]"; - private String setRowNamesString = "row.names(%s)<-c(%s)"; - private String setRowNameString = "row.names(%s)[%s]<-\"%s\""; /** * Constructor @@ -199,7 +196,7 @@ if (engine.isAutoCommit()) { //Get back the names from R. String[] rowNamesArray = (String[]) engine.eval(String.format( - getRowNamesString, this.variable)); + RInstructions.GET_ROW_NAMES, this.variable)); //Check if size is correct, if yes, modify local data. if (rowNamesArray.length <= this.data.get(0).size()) { @@ -237,7 +234,7 @@ if (engine.isAutoCommit()) { //Get back the names from R. String name = (String) engine.eval(String.format( - getRowNameString, this.variable, y + 1)); + RInstructions.GET_ROW_NAME, this.variable, y + 1)); //Check if the String is returned. if ((name != null) && (!name.equals(""))) { @@ -280,8 +277,8 @@ } rowNamesString += "\"" + rowNames.get(i) + "\""; } - String rexp = String.format(setRowNamesString, this.variable, - rowNamesString); + String rexp = String.format(RInstructions.SET_ROW_NAMES, + this.variable, rowNamesString); //Send the r instruction to the engine. engine.voidEval(rexp); @@ -310,8 +307,8 @@ rowNames.set(x, rowName); //create the r instruction (row.names(var)[x]<-"rowName") - String rexp = String.format(setRowNameString, this.variable, x + 1, - rowName); + String rexp = String.format(RInstructions.SET_ROW_NAME, + this.variable, x + 1, rowName); //Send the R instruction to the engine. engine.voidEval(rexp); @@ -347,16 +344,16 @@ } else if (data.get(i).get(0) instanceof Boolean) { for (int j = 0; j < data.get(i).size(); j++) { if ((Boolean) data.get(i).get(j)) { - returnString += "TRUE,"; + returnString += RInstructions.TRUE + ","; } else { - returnString += "FALSE,"; + returnString += RInstructions.FALSE + ","; } } } else if (data.get(i).get(0) instanceof Integer) { for (int j = 0; j < data.get(i).size(); j++) { - returnString += "as.integer(" + data.get(i).get(j) + - "),"; + returnString += String.format(RInstructions.AS_INTEGER, + data.get(i).get(j)) + ","; } } else { for (int j = 0; j < data.get(i).size(); j++) { @@ -403,34 +400,33 @@ checkVariable(); checkX(x); checkY(y); - String setString = "%s[%s,%s]<-%s"; try { if (this.data.get(x).get(y) instanceof Double) { ((ArrayList<Double>) this.data.get(x)).set(y, (Double) data); - engine.voidEval(String.format(setString, this.variable, y + 1, + engine.voidEval(String.format(RInstructions.SET_DATAFRAME_ITEM, + this.variable, y + 1, x + 1, data)); } else if (this.data.get(x).get(y) instanceof Boolean) { ((ArrayList<Boolean>) this.data.get(x)).set(y, (Boolean) data); if ((Boolean) data) { - engine.voidEval(String.format(setString, this.variable, y + - 1, - x + 1, "TRUE")); + engine.voidEval(String.format( + RInstructions.SET_DATAFRAME_ITEM, this.variable, + y + 1, x + 1, RInstructions.TRUE)); } else { - engine.voidEval(String.format(setString, this.variable, y + - 1, - x + 1, "FALSE")); + engine.voidEval(String.format( + RInstructions.SET_DATAFRAME_ITEM, this.variable, + y + 1, x + 1, RInstructions.FALSE)); } } else if (this.data.get(x).get(y) instanceof String) { ((ArrayList<String>) this.data.get(x)).set(y, (String) data); - engine.voidEval(String.format(setString, this.variable, y + 1, - x + 1, - "\"" + data + "\"")); + engine.voidEval(String.format(RInstructions.SET_DATAFRAME_ITEM, + this.variable, y + 1, x + 1, "\"" + data + "\"")); } else if (this.data.get(x).get(y) instanceof Integer) { ((ArrayList<Integer>) this.data.get(x)).set(y, (Integer) data); - engine.voidEval(String.format(setString, this.variable, y + 1, - x + 1, - "as.integer(" + data + ")")); + engine.voidEval(String.format(RInstructions.SET_DATAFRAME_ITEM, + this.variable, y + 1, x + 1, String.format( + RInstructions.AS_INTEGER, data))); } else { throw new ArrayStoreException( "The data.frame does not accept this type on those coordinates : " + @@ -461,8 +457,9 @@ checkX(x); checkY(y); if (engine.isAutoCommit()) { - Object returnObject = engine.eval(this.variable + "[" + (y + 1) + - "," + (x + 1) + "]"); + Object returnObject = engine.eval(String.format( + RInstructions.GET_DATAFRAME_ITEM, this.variable, y + 1, + x + 1)); if (returnObject instanceof String) { ((ArrayList<String>) this.data.get(x)).set(y, (String) returnObject); @@ -543,44 +540,47 @@ //update row names String[] rowNamesArray = (String[]) engine.eval(String.format( - getRowNamesString, this.variable)); + RInstructions.GET_ROW_NAMES, this.variable)); for (int i = 0; i < rowNamesArray.length; i++) { rowNames.add(rowNamesArray[i]); } //update names String[] namesArray = (String[]) engine.eval(String.format( - getNamesString, this.variable)); + RInstructions.GET_NAMES, this.variable)); for (int i = 0; i < namesArray.length; i++) { names.add(namesArray[i]); } //update data - Integer dataframelength = (Integer) engine.eval("length(" + - this.variable + ")"); + Integer dataframelength = (Integer) engine.eval(String.format( + RInstructions.LENGTH, this.variable)); for (int i = 0; i < dataframelength; i++) { - Integer arrayListLength = (Integer) engine.eval("length(" + - this.variable + "[," + (i + 1) + "])"); + Integer arrayListLength = (Integer) engine.eval(String.format( + RInstructions.LENGTH_COLUMN, this.variable, i + 1)); ArrayList<Serializable> thisColumn = new ArrayList<Serializable>(); for (int j = 0; j < arrayListLength; j++) { - thisColumn.add((Serializable) engine.eval(this.variable + - "[" + (j + 1) + "," + (i + 1) + "]")); + thisColumn.add((Serializable) engine.eval(String.format( + RInstructions.GET_DATAFRAME_ITEM, this.variable, + j + 1, i + 1))); } data.add(thisColumn); + } //update attributes - Integer attributeslength = (Integer) engine.eval( - "length(attributes(" + this.variable + "))"); + Integer attributeslength = (Integer) engine.eval(String.format( + RInstructions.LENGTH_ATTRIBUTES, this.variable)); - for (int i = 0; i < attributeslength; i++) { - String key = (String) engine.eval("names(attributes(" + - this.variable + "))[" + (i + 1) + "]"); + for (int i = 0; + i < attributeslength; i++) { + String key = (String) engine.eval(String.format( + RInstructions.GET_ATTRIBUTE_NAME, this.variable, i + 1)); - String attribute = (String) engine.eval("toString(attributes(" + - this.variable + ")$" + key + ")"); + String attribute = (String) engine.eval("toString(" + String.format( + RInstructions.GET_ATTRIBUTE, this.variable, key) + ")"); attributes.put(key, attribute); } } @@ -803,4 +803,4 @@ throw new RException("Not supported type"); } } -} +} \ No newline at end of file Modified: trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java 2009-08-20 15:09:52 UTC (rev 141) +++ trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java 2009-08-21 08:24:26 UTC (rev 142) @@ -23,6 +23,7 @@ import org.apache.commons.logging.LogFactory; import org.nuiton.j2r.REngine; import org.nuiton.j2r.RException; +import org.nuiton.j2r.RInstructions; /** * Abstract class for REXP interface, in order to avoid duplicate code for attributes related methods. @@ -44,22 +45,10 @@ //Vector containing the names of the data.frame vectors protected List<String> names; - - //R instruction to assign one attribute value. - protected String assignAttribute = "attr(%s,\"%s\")<-%s"; - - //R instruction to get one attribute value. - protected String getAttribute = "attr(%s,\"%s\")"; - protected String getNamesString = "names(%s)"; - protected String getNameString = "names(%s)[%s]"; protected String indexExceptionText = "Cannot perform operation, index is superior to size.\nIndex : %s\nSize : %s"; protected String dataInconsistencyText = "There is an inconsistency between the local and distant data.\nLocal data size : %s\nDistant data size : %s"; - protected String setNamesString = "names(%s)<-c(%s)"; - //R instruction to assign one name - protected String setNameString = "names(%s)[%s]<-\"%s\""; - //R instruction to get the names protected String noVariable = "No variable name given"; /** {@inheritDoc} */ @@ -76,29 +65,35 @@ for (int i = 0; i < keys.length; i++) { //foreach type of attribute, adapt the R instruction. if (this.attributes.get(keys[i]) instanceof String) { - engine.eval(String.format(assignAttribute, this.variable, - keys[i], "\"" + this.attributes.get(keys[i]) + "\"")); + engine.eval(String.format(RInstructions.SET_ATTRIBUTE, + this.variable, keys[i], + "\"" + this.attributes.get(keys[i]) + "\"")); //String, value between quotes } else if (this.attributes.get(keys[i]) instanceof Double) { - engine.eval(String.format(assignAttribute, this.variable, + engine.eval(String.format(RInstructions.SET_ATTRIBUTE, + this.variable, keys[i], this.attributes.get(keys[i]))); } else if (this.attributes.get(keys[i]) instanceof Integer) { - engine.eval(String.format(assignAttribute, this.variable, - keys[i], "as.integer(" + - this.attributes.get(keys[i]) + ")")); + engine.eval(String.format(RInstructions.SET_ATTRIBUTE, + this.variable, + keys[i], String.format(RInstructions.AS_INTEGER, + this.attributes.get(keys[i])))); //Integer, value formated by the R function : as.integer() } else if (this.attributes.get(keys[i]) instanceof Boolean) { if ((Boolean) this.attributes.get(keys[i])) { - engine.eval(String.format(assignAttribute, this.variable, - keys[i], "TRUE")); + engine.eval(String.format(RInstructions.SET_ATTRIBUTE, + this.variable, + keys[i], RInstructions.TRUE)); //Boolean true replaced by TRUE } else { - engine.eval(String.format(assignAttribute, this.variable, - keys[i], "FALSE")); + engine.eval(String.format(RInstructions.SET_ATTRIBUTE, + this.variable, + keys[i], RInstructions.FALSE)); //Boolean false replaced by REPLACE } } else if (this.attributes.get(keys[i]) instanceof REXP) { - engine.eval(String.format(assignAttribute, this.variable, + engine.eval(String.format(RInstructions.SET_ATTRIBUTE, + this.variable, keys[i], ((REXP) this.attributes.get(keys[i])).toRString())); //REXP replaced by the result of their toRString() method. @@ -119,13 +114,13 @@ public Map<String, Object> getAttributes() throws RException { if (engine.isAutoCommit()) { //get the number of attributes - Integer attributeslength = (Integer) engine.eval( - "length(attributes(" + this.variable + "))"); + Integer attributeslength = (Integer) engine.eval(String.format( + RInstructions.LENGTH_ATTRIBUTES, this.variable)); for (int i = 0; i < attributeslength; i++) { //Get the name of the i attribute - String key = (String) engine.eval("names(attributes(" + - this.variable + "))[" + (i + 1) + "]"); + String key = (String) engine.eval(String.format( + RInstructions.GET_ATTRIBUTE_NAME, this.variable, i + 1)); //Get the attribute getAttribute(key); @@ -141,23 +136,22 @@ Object returnedAttribute; //test if the attribute is a data.frame if ((Boolean) engine.eval("is.data.frame(" + String.format( - getAttribute, this.variable, attribute) + ")")) { + RInstructions.GET_ATTRIBUTE, this.variable, attribute) + ")")) { //if attribute is a list, import the data.frame from R returnedAttribute = new RDataFrame(engine); ((RDataFrame) returnedAttribute).getFrom(String.format( - getAttribute, this.variable, attribute)); + RInstructions.GET_ATTRIBUTE, this.variable, attribute)); //test if the attribute is a list } else if ((Boolean) engine.eval("is.list(" + String.format( - getAttribute, this.variable, attribute) + ")")) { - + RInstructions.GET_ATTRIBUTE, this.variable, attribute) + ")")) { //if attribute is a list, import it from R. returnedAttribute = new RList(engine); - ((RList) returnedAttribute).getFrom(String.format(getAttribute, - this.variable, attribute)); + ((RList) returnedAttribute).getFrom(String.format( + RInstructions.GET_ATTRIBUTE, this.variable, attribute)); } else { //else attribute is imported as any other R expression. - returnedAttribute = engine.eval(String.format(getAttribute, - this.variable, attribute)); + returnedAttribute = engine.eval(String.format( + RInstructions.GET_ATTRIBUTE, this.variable, attribute)); } //put the attribute in the attribute list @@ -188,28 +182,29 @@ boolean isOK = false; if (value instanceof String) { isOK = true; - engine.voidEval(String.format(assignAttribute, this.variable, - attribute, "\"" + value + "\"")); + engine.voidEval(String.format(RInstructions.SET_ATTRIBUTE, + this.variable, attribute, "\"" + value + "\"")); //if String, between quotes } else if (value instanceof Double) { isOK = true; - engine.voidEval(String.format(assignAttribute, this.variable, - attribute, value)); + engine.voidEval(String.format(RInstructions.SET_ATTRIBUTE, + this.variable, attribute, value)); } else if (value instanceof Integer) { isOK = true; - engine.voidEval(String.format(assignAttribute, this.variable, - attribute, "as.integer(" + value + ")")); + engine.voidEval(String.format(RInstructions.SET_ATTRIBUTE, + this.variable, attribute, String.format( + RInstructions.AS_INTEGER, value))); //If integer in the R function : as.integer() } else if (value instanceof Boolean) { isOK = true; //R boolean is upper case - engine.voidEval(String.format(assignAttribute, this.variable, - attribute, value.toString().toUpperCase())); + engine.voidEval(String.format(RInstructions.SET_ATTRIBUTE, + this.variable, attribute, value.toString().toUpperCase())); } else if (value instanceof REXP) { isOK = true; - engine.voidEval(String.format(assignAttribute, this.variable, - attribute, ((REXP) value).toRString())); - //if REXP, use its method toRString() + engine.voidEval(String.format(RInstructions.SET_ATTRIBUTE, + this.variable, attribute, ((REXP) value).toRString())); + //if REXP, use its method toRString() } else { log.warn("This attribute is not valid : " + attribute + " ; " + value + ". It will not be processed"); @@ -267,7 +262,7 @@ if (engine.isAutoCommit()) { //Get back the names from R. String[] namesArray = (String[]) engine.eval(String.format( - getNamesString, this.variable)); + RInstructions.GET_NAMES, this.variable)); //Check if size is correct, if yes, modify local data. checkX(namesArray.length); @@ -303,8 +298,8 @@ if (x < names.size()) { if (engine.isAutoCommit()) { //Get back the names from R. - String name = (String) engine.eval(String.format(getNameString, - this.variable, x + 1)); + String name = (String) engine.eval(String.format( + RInstructions.GET_NAME, this.variable, x + 1)); //Check if the String is returned. if ((name != null) && (!name.equals(""))) { @@ -387,7 +382,7 @@ } namesString += "\"" + names.get(i) + "\""; } - String rexp = String.format(setNamesString, this.variable, + String rexp = String.format(RInstructions.SET_NAMES, this.variable, namesString); //Send the r instruction to the engine. @@ -425,7 +420,7 @@ } //create the r instruction (names(var)[x]<-"name") - String rexp = String.format(setNameString, this.variable, x + 1, + String rexp = String.format(RInstructions.SET_NAME, this.variable, x + 1, name); //Send the R instruction to the engine. Modified: trunk/src/main/java/org/nuiton/j2r/types/RList.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/types/RList.java 2009-08-20 15:09:52 UTC (rev 141) +++ trunk/src/main/java/org/nuiton/j2r/types/RList.java 2009-08-21 08:24:26 UTC (rev 142) @@ -24,6 +24,7 @@ import org.apache.commons.logging.LogFactory; import org.nuiton.j2r.REngine; import org.nuiton.j2r.RException; +import org.nuiton.j2r.RInstructions; /** * Java implementation of the R List. @@ -34,11 +35,9 @@ //Content of the list (eg elements of the list in R) private List<Object> data; - private Log log = LogFactory.getLog(RDataFrame.class); //TODO implement the logger use ! - /** * Create a default RList linked to a R engine (the List is not initialized * in R.) @@ -93,7 +92,7 @@ String variable) throws RException { super(); this.names = new ArrayList<String>(); - for (int i=0;i<names.length;i++){ + for (int i = 0; i < names.length; i++) { this.names.add(names[i]); } this.data = (ArrayList<Object>) data; @@ -114,8 +113,6 @@ } } - - /** * Method to export the list in a String for evaluation in R. * @@ -136,12 +133,13 @@ returnString += "\"" + data.get(i) + "\","; } else if ((data.get(i) instanceof Boolean) && ((Boolean) data.get(i))) { - returnString += "TRUE,"; + returnString += RInstructions.TRUE + ","; } else if ((data.get(i) instanceof Boolean) && (!(Boolean) data.get(i))) { - returnString += "FALSE,"; + returnString += RInstructions.FALSE + ","; } else if (data.get(i) instanceof Integer) { - returnString += "as.integer(" + data.get(i) + "),"; + returnString += String.format(RInstructions.AS_INTEGER, + data.get(i)) + ","; } else if (data.get(i) instanceof REXP) { returnString += ((REXP) (data.get(i))).toRString() + ","; } else { @@ -182,23 +180,33 @@ } if (data instanceof Double) { - engine.voidEval(this.variable + "[[" + (x + 1) + "]]<-" + data); + //in R, all data is numeric, no need to transformation, simple + //assignation + engine.voidEval(String.format(RInstructions.SET_LIST_ITEM, + this.variable, x + 1, data)); } else if (data instanceof Integer) { - engine.voidEval(this.variable + "[[" + (x + 1) + "]]<-as.integer(" + - data + ")"); + //transform the data in R integer + String asInteger = String.format(RInstructions.AS_INTEGER, data); + //assign the transformed data + engine.voidEval(String.format(RInstructions.SET_LIST_ITEM, + this.variable, x + 1, asInteger)); } else if (data instanceof Boolean) { if ((Boolean) data) { - engine.voidEval(this.variable + "[[" + (x + 1) + "]]<-TRUE"); + engine.voidEval(String.format(RInstructions.SET_LIST_ITEM, + this.variable, x + 1, RInstructions.TRUE)); } else { - engine.voidEval(this.variable + "[[" + (x + 1) + "]]<-FALSE"); + engine.voidEval(String.format(RInstructions.SET_LIST_ITEM, + this.variable, x + 1, RInstructions.FALSE)); } } else if (data instanceof String) { - engine.voidEval(this.variable + "[[" + (x + 1) + "]]<-\"" + data + - "\""); + engine.voidEval(String.format(RInstructions.SET_LIST_ITEM, + this.variable, x + 1, "\"" + data + "\"")); } else if (data instanceof REXP) { + //Send the REXP to R engine.voidEval(((REXP) data).toRString()); - engine.voidEval(this.variable + "[[" + (x + 1) + "]]<-" + - ((REXP) data).getVariable()); + //Set the REXP as list item + engine.voidEval(String.format(RInstructions.SET_LIST_ITEM, + this.variable, x + 1, ((REXP) data).getVariable())); } } @@ -214,8 +222,8 @@ public Object get(int x) throws RException { checkX(x); if (engine.isAutoCommit()) { - Object returnObject = engine.eval(this.variable + "[[" + (x + 1) + - "]]"); + Object returnObject = engine.eval(String.format( + RInstructions.GET_LIST_ITEM, this.variable, x + 1)); if (returnObject instanceof String) { this.data.set(x, (String) returnObject); } else if (returnObject instanceof Double) { @@ -281,27 +289,29 @@ //update names String[] namesArray = (String[]) engine.eval(String.format( - getNamesString, this.variable)); + RInstructions.GET_NAMES, this.variable)); for (int i = 0; i < namesArray.length; i++) { names.add(namesArray[i]); } //update data - int length = (Integer) engine.eval("length(" + variable + ")"); + int length = (Integer) engine.eval(String.format(RInstructions.LENGTH, + variable)); for (int i = 0; i < length; i++) { - data.add(engine.eval(this.variable + "[[" + (i + 1) + "]]")); + data.add(engine.eval(String.format(RInstructions.GET_LIST_ITEM, + this.variable, i + 1))); } //update attributes - Integer attributeslength = (Integer) engine.eval("length(attributes(" + - this.variable + "))"); + Integer attributeslength = (Integer) engine.eval(String.format( + RInstructions.LENGTH_ATTRIBUTES, this.variable)); for (int i = 0; i < attributeslength; i++) { - String key = (String) engine.eval("names(attributes(" + - this.variable + "))[" + (i + 1) + "]"); + String key = (String) engine.eval(String.format( + RInstructions.GET_ATTRIBUTE_NAME, this.variable, i + 1)); - Object attribute = engine.eval( - "attributes(" + this.variable + ")$" + key); + Object attribute = engine.eval(String.format( + RInstructions.GET_ATTRIBUTE, this.variable, key)); attributes.put(key, attribute); } }