Author: jcouteau Date: 2010-04-15 11:21:38 +0200 (Thu, 15 Apr 2010) New Revision: 197 Log: Clean code, improve toRString method for RDataFrames (deal with empty dataframe) Modified: trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java trunk/src/main/java/org/nuiton/j2r/types/REXP.java trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java trunk/src/main/java/org/nuiton/j2r/types/RList.java Modified: trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java 2010-04-15 07:44:34 UTC (rev 196) +++ trunk/src/main/java/org/nuiton/j2r/types/RDataFrame.java 2010-04-15 09:21:38 UTC (rev 197) @@ -60,6 +60,8 @@ //Vector containing the vectors of the data.frame private List<List<?>> data; + //TODO JC 20100415 Create a toString method that displays the DataFrame + /** * Constructor * @@ -336,42 +338,54 @@ @Override public String toRString() throws RException { checkVariable(); + String returnString = this.variable + "<-data.frame("; - if (!(this.data.isEmpty())) { - for (int i = 0; i < data.size(); i++) { + + for (List<?> column:this.data){ + + if (!column.isEmpty()){ + if (!(this.names.isEmpty())) { - returnString += this.names.get(i) + "=c("; + int index = this.data.indexOf(column); + returnString += this.names.get(index) + "=c("; } else { returnString += "c("; } - if (data.get(i).get(0) instanceof String) { - for (int j = 0; j < data.get(i).size(); j++) { - returnString += "\"" + data.get(i).get(j) + "\","; + + Object firstElement = column.get(0); + + + if (firstElement instanceof String) { + for (Object obj:column) { + returnString += "\"" + obj + "\","; } - } 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)) { + } else if (firstElement instanceof Boolean) { + for (Object obj:column) { + if ((Boolean) obj) { returnString += RInstructions.TRUE + ","; } else { returnString += RInstructions.FALSE + ","; } } - } else if (data.get(i).get(0) instanceof Integer) { - for (int j = 0; j < data.get(i).size(); j++) { + } else if (firstElement instanceof Integer) { + for (Object obj:column) { returnString += String.format(RInstructions.AS_INTEGER, - data.get(i).get(j)) + ","; + obj) + ","; } } else { - for (int j = 0; j < data.get(i).size(); j++) { - returnString += data.get(i).get(j) + ","; + for (Object obj:column) { + returnString += obj + ","; } } + returnString = returnString.substring(0, returnString.length() - 1); returnString = returnString + "),"; + + } - } + } if (!(this.rowNames.isEmpty())) { returnString += "row.names=c("; @@ -387,6 +401,9 @@ } else { returnString += "stringsAsFactors=FALSE)"; } + + System.out.println(returnString); + return returnString; } @@ -491,7 +508,7 @@ * @return a ArrayList containing the ArrayLists of the R data.frame */ public List<List<?>> getData() { - //TODO manage the autocommit mode here. + //TODO JC manage the autocommit mode here. return data; } @@ -697,88 +714,125 @@ */ public void importCsv(File inputFile, boolean rowNames, boolean names, List<Object> importTypes) throws IOException { + //temporary String to read lines. String tmp; + Integer dataSize; + //get the first line of the file BufferedReader br = new BufferedReader(new FileReader(inputFile)); tmp = br.readLine(); String[] splitted = tmp.split("\\;"); + //get the data size (number of columns) if (rowNames) { dataSize = splitted.length - 1; } else { dataSize = splitted.length; } + //if data has already been initialized, clear it. if (this.data != null) { this.data.clear(); } - if ((rowNames) && (this.rowNames != null)) { + + //Clear rowNames + if ((this.rowNames != null)) { this.rowNames.clear(); + } + //if names has already been initialized, clear it. + if (this.names != null) { + this.names.clear(); } + if (names) { //if names are present in the file, parse the first line to get //the names. - if (this.names != null) { - //if names has already been initialized, clear it. - this.names.clear(); - } - //get every name from the first line this.names.addAll(Arrays.asList(splitted).subList(1, splitted.length)); } //temporary data list. - List<List<?>> tempData = - new ArrayList<List<?>>(); + List<List<?>> tempData = new ArrayList<List<?>>(); - //Initialize all the data columns + //Initialize all the data columns with empty lists for (int i = 0; i < dataSize; i++) { List<Object> column = new ArrayList<Object>(); tempData.add(column); } while ((tmp = br.readLine()) != null) { + //parse each line splitted = tmp.split("\\;"); + //to determine the data index on the line. int index = 0; + + //if there are row names, extract the first item as the row name if (rowNames) { - //if there are row names, extract the first item as the row name this.rowNames.add(splitted[0]); index = 1; } + for (int i = index; i < splitted.length; i++) { //cast the data imported to the specified type. //test the size of the inputType list. If 1 import all the //columns as the type of the first element. - if (importTypes.size() == 1) { - if (importTypes.get(0) instanceof String) { - ((ArrayList<Object>) tempData.get(i - index)).add( - splitted[i]); - } else if (importTypes.get(0) instanceof Double) { - ((ArrayList<Object>) tempData.get(i - index)).add(Double.valueOf( - splitted[i])); - } else if (importTypes.get(0) instanceof Integer) { - ((ArrayList<Object>) tempData.get(i - index)).add(Integer.valueOf( - splitted[i])); - } - } else if (importTypes.get(i - index) instanceof String) { - ((ArrayList<Object>) tempData.get(i - index)).add( - splitted[i]); - } else if (importTypes.get(i - index) instanceof Double) { - ((ArrayList<Object>) tempData.get(i - index)).add(Double.valueOf( - splitted[i])); - } else if (importTypes.get(i - index) instanceof Integer) { - ((ArrayList<Object>) tempData.get(i - index)).add(Integer.valueOf( - splitted[i])); + //Get the column for index + ArrayList<Object> objects = (ArrayList<Object>)tempData.get(i - index); + + //add to the column the converted value. If importTypes contains + //only one element, cast into this type, else cast into the + //column type. + if (((importTypes.size() == 1) && + (importTypes.get(0) instanceof String) ) || + ((importTypes.size() > (i -index )) && + (importTypes.get(i - index) instanceof String)) ) { + + //We import strings so no cast in case of string + objects.add(splitted[i]); + + } else if (((importTypes.size() == 1) && + (importTypes.get(0) instanceof Double) ) || + ((importTypes.size() > (i -index )) && + (importTypes.get(i - index) instanceof Double))) { + + //in case of Double + objects.add(Double.valueOf(splitted[i])); + + } else if (((importTypes.size() == 1) && + (importTypes.get(0) instanceof Integer) ) || + ((importTypes.size() > (i -index )) && + (importTypes.get(i - index) instanceof Integer))) { + + //in case of Integer + objects.add(Integer.valueOf(splitted[i])); + } } } br.close(); this.data = tempData; + + + if (log.isDebugEnabled()){ + + //Display the imported data.frame in debug mode + + log.debug("Imported DataFrame : "); + + for(List<?> column:this.data){ + String debugLine="Column " + this.data.indexOf(column)+ " : "; + for(Object obj:column){ + debugLine += obj + " ,"; + } + log.debug(debugLine); + } + } + } private void checkY(int y) { Modified: trunk/src/main/java/org/nuiton/j2r/types/REXP.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/types/REXP.java 2010-04-15 07:44:34 UTC (rev 196) +++ trunk/src/main/java/org/nuiton/j2r/types/REXP.java 2010-04-15 09:21:38 UTC (rev 197) @@ -51,8 +51,6 @@ * * @param variable * name of the data.frame in R - * @param engine - * a REngine where the R session is located. * @throws RException */ void getFrom(String variable) throws RException; Modified: trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java 2010-04-15 07:44:34 UTC (rev 196) +++ trunk/src/main/java/org/nuiton/j2r/types/REXPAbstract.java 2010-04-15 09:21:38 UTC (rev 197) @@ -68,7 +68,7 @@ @Override public void setAttributes(Map<String, Object> attributes) throws RException { - //TODO should be useful to test the validity of attributes before assigning it. + //TODO JC should be useful to test the validity of attributes before assigning it. this.attributes = attributes; if ((this.attributes != null) && (!this.attributes.isEmpty())) { Modified: trunk/src/main/java/org/nuiton/j2r/types/RList.java =================================================================== --- trunk/src/main/java/org/nuiton/j2r/types/RList.java 2010-04-15 07:44:34 UTC (rev 196) +++ trunk/src/main/java/org/nuiton/j2r/types/RList.java 2010-04-15 09:21:38 UTC (rev 197) @@ -29,6 +29,7 @@ package org.nuiton.j2r.types; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -49,7 +50,7 @@ private List<Object> data; private Log log = LogFactory.getLog(RDataFrame.class); - //TODO implement the logger use ! + //TODO JC implement the logger use ! /** * Create a default RList linked to a R engine (the List is not initialized * in R.) @@ -79,7 +80,7 @@ String variable) throws RException { super(); this.names = names; - this.data = (ArrayList<Object>) data; + this.data = data; this.variable = variable; this.attributes = new HashMap<String, Object>(); this.engine = engine; @@ -102,12 +103,19 @@ */ public RList(String[] names, List<Object> data, REngine engine, String variable) throws RException { + super(); + + String[] tempNames = {}; + + if(names!=null){ + tempNames = names.clone(); + } + + this.names = new ArrayList<String>(); - for (int i = 0; i < names.length; i++) { - this.names.add(names[i]); - } - this.data = (ArrayList<Object>) data; + this.names.addAll(Arrays.asList(tempNames)); + this.data = data; this.variable = variable; this.attributes = new HashMap<String, Object>(); this.engine = engine; @@ -237,13 +245,13 @@ Object returnObject = engine.eval(String.format( RInstructions.GET_LIST_ITEM, this.variable, x + 1)); if (returnObject instanceof String) { - this.data.set(x, (String) returnObject); + this.data.set(x, returnObject); } else if (returnObject instanceof Double) { - this.data.set(x, (Double) returnObject); + this.data.set(x, returnObject); } else if (returnObject instanceof Integer) { - this.data.set(x, (Integer) returnObject); + this.data.set(x, returnObject); } else if (returnObject instanceof Boolean) { - this.data.set(x, (Boolean) returnObject); + this.data.set(x, returnObject); } } return this.data.get(x); @@ -264,7 +272,7 @@ * * @param data * a List of Objects, containing each element of the R list - * @throws RException + * @throws RException if cannot communicate with R */ public void setData(List<Object> data) throws RException { this.data = data; @@ -300,9 +308,7 @@ //update names String[] namesArray = (String[]) engine.eval(String.format( RInstructions.GET_NAMES, this.variable)); - for (int i = 0; i < namesArray.length; i++) { - names.add(namesArray[i]); - } + names.addAll(Arrays.asList(namesArray)); //update data int length = (Integer) engine.eval(String.format(RInstructions.LENGTH,
participants (1)
-
jcouteau@users.nuiton.org