In the Java snippet node you can do something like:
if ($ColumnName$ < 10) {
temp = "True";
} else {
temp = "False";
}
return temp;
When you use the Column List Loop Start, I'd then like to be able to replace $ColumnName$ in the above example to the current column header, which is stored in the variable "currentColumnName". Unfortunately the following code:
if ($${ScurrentColumnName}$$ < 10) {
temp = "True";
} else {
temp = "False";
}
return temp;
doesn't work, because the variable only resolves to the column name, not to the associated values in each row for that column. How would one do this?
A related question: it also doesn't seem possible to link the new column to be created to a variable name. Is this possible?
You can use the Column Name (Regex) to unify the column names before you go into the Java Snippet, use the Column Rename to replace the name afterwards and before the Column Append Loop End node. Hope this helps.
Many thanks for the tip, I have things implemented now and it seems to work fine. I don't think I would have come with this as a solution. Not the most straightforward way to build 100's of Bayesian models, but hopefully the planned multi-model node will be ready soon (hint, hint:)).
I sometimes introduce a Java Edit Variable node before the Java Snippet node. The Java Edit Variable node's job is to generate the Java expression string that will be used in the Java Snippet node. (The Java Snippet node can be parameterized with the variable by selecting the variable in the "expression" pull-down in the Flow Variables tab in the configuration dialog). This is one way to dynamically specify the current column name in each iteration of a column name loop. Example Java Edit Variable expression:
StringBuilder sb = new StringBuilder();
String newline = System.getProperty("line.separator");
String currentColName = $${ScurrentColumnName}$$; //we're in a column list loop
//dynamically inserts current col name
sb.append("Double val = $");
sb.append(currentColName);
sb.append("$;");
sb.append(newline);
<<...do something here...>>
return sb.toString();
This works best when the code to generate is short. It's a bit of a pain to write.
Don, your solution works, kinky as it is. But for larger amounts of data it is very slow.
We have 10k rows with 1k columns. It takes near an hour to chew through that.
However, i am pretty sure there should be a true indirect access to variables or columns.I tried java reflection to no avail, even the scriptingEngine but could not get that to work.
My approach is of course a hack. It would be really nice if there were some special syntax or method call one could use in the Java Snippet node that would look up the value for a given column name or index. Something like:
Double val = getDblValueForColIndex(12);
Double val = getDblValueForColName("calculated concentration");
...are you listenening KNIME? ;-)
P.S. This is just a guideline, but in my testing generating a java snippet 1000 times (containing 25 simple StringBuilder append operations) in KNIME takes 4 minutes 40 seconds on my 1-year old dual core dell laptop. This includes the time consumed by the loop start, loop end, and inject variable nodes used to perform this test.
We'll have in new version of the Java Snippet and the Java Edit Variable on the list for KNIME 2.6. It includes dynamic column access (as described by you, Don), syntax highlighting, multiple result values (not by using "return" but by assigning values to defined class fields), definition of variables also in the java snippet node, templates, more types (including date and xml), error highlighting, etc.
Thanks to the anonymous pharma company sponsoring these nodes (they are listening, too ;-))
Wow, that sounds awesome. I've wished for each one of these items at one time or another. KNIME really is listening (and anticipating). Can't wait for the 2.6 release! Thanks again.
I am using a Java Snippet node and perform some iterative calculation based on each row of a column. I would like to update the last row of this column with the result of the calculation.
The issue is that the column name is generated at run time. So, I use the getCell() function fine to retrieve the content of a cell, based on its column index. However, I cannot find an elegant way to set the content of a cell.
Here is the pseudo code for what I'm using (first two lines) and what I would like to use (last line):
value = getCell(v_columnIndex, tDouble);
// Perform calculation
setCell(v_columnIndex) = value;
It is the last function's functionality that I am looking for (setCell() does not exist, AFAIK).
One alternative would be to use Don's suggestion. However, I would like to check with you, user and/or KNIME developers, if it is possible to have the equivalent to setCell().
I was trying to find where the methods of the JSnippet are documented. After searching the JavaDoc API documentation I finally found that you can simply take a look at the node description/help page of the Java Snippet node within KNIME to get a list of all methods. I'm posting here so that other people might also find this.
Unfortunately there do not seem to be any setter-Methods for dynamic columns as requested by Fred in the previous post.
The code that dnaki described is EXACTLY what I am trying to do (use the column name as a variable to enter into a Java snippet), but as I understand, it is no longer usable.