Java snippet and variable column names

Hi everyone,

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?

Thanks,

Natasja

1 Like

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.

1 Like

Hi Gabriel,

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:)).

Cheers,

Natasja

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.

Hope this helps
-Don

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.
 

Hi Ellert,

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.

Best regards
Don

Yes, KNIME is listening.

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 ;-))

2 Likes

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.

-Don

Wow Bernd that is fantastic news! A big thanks to this mysterious sponsor too.
Can't wait for the 2.6 release :-)

In Knime 2.6 the trick as described by dnaki does no longer work in either the simple or the full java node.

But you can now do it with the standard javanode  with code like:

icc = getColumnCount();
for(i=0; i<icc; i++){
    cn = getColumnName(i);
    r = getCell(cn, tDouble);

... etc

 

(note, no type checking etc. in this sample)

 

1 Like

That 's right, but you still can use the Java Snippet (simple) node.

1 Like

Hello KNIME community,

 

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().

 

Cheers,

Fred

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.

 

1 Like

Hi,

Could someone please explain in more detail how Ellert's code works in practice? I mean this snippet:

icc = getColumnCount();
for(i=0; i<icc; i++){
    cn = getColumnName(i);
    r = getCell(cn, tDouble);

I can't figure out how to enter this into KNIME.

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.

This topic was automatically closed after 2 days. New replies are no longer allowed.