Take row content from a row if the column index = iteration number

Dear KNIMErs,

working on some procedural RPG creation (again) using KNIME and can’t wrap my head around a problem.

One of my “dice throwing loops” generates this table (an adventure location for my dire heroes, if you’re interested :wink:

loop_result_table

What I would like my workflow to do is this (in general language):

  • If you’re looping through the table the 1st time (iteration 0) take the content of the 1st column and write it to a new column (final location)
  • If you’re looping through the table the 2nd time (iteration 1) take the content of the 2nd column and write it to the new column (final location)
    etc.

At the end I want to create something that would read

Moaning Dome of the Winged Sisterhood

The basic rule here is

if iteration = column index

It feels like I’m nearly there but missing the last piece.

Thanks a lot in advance for nudging me into the right direction :wink:

Phil

4 Likes

I will throw the Unpivot node into the game :slight_smile:

3 Likes

hmmmm… not sure what I can do in the resulting table to get closer.

I have unpivoted like this:

image

1 Like

What you want is essentially the “trace” of the input table/matrix. I was getting excited that I can show of my Java Snippet skills, but the solution turned out to be a simple

out_output = getCell(ROWINDEX, tString);

followed by a GroupBy node to collapse the column into one sentence.
I also added a bit of code to directly push the result to a Flow Variable.

There’s no checking the input, it starts with the leftmost column and goes diagonally from there. Excess columns are ok, excess rows are not. Could be implemented though. :wink:

image
trace of KNIME table.knwf (16.6 KB)

5 Likes

Thank you @Thyme

This definitely works but I personally have a huge problem: I do not understand one bit of what the Java snippet does hence I would probably stay away from it (I don’t like workflows I do not understand).

Don’t get me wrong, I appreciate your effort and that you took the time to provide a solution, but I really want to understand what I am doing (and I definitely don’t want to learn Java :wink: )

No problem, using WFs (or code) one doesn’t understand is always a bad idea. I was about to edit my post because I also found a solution with a lower challenge rating. And while I was writing this, I Node Golf’ed my new solution. :sweat_smile:

I’ll comment on the lowest branch, because the central idea is the same on both non-scripting solutions: “row number filtering”.

  1. Loop over columns
  2. Row Filter to include only one row, equal to the current iteration (uses Flow Variables to control the value)
  3. fresh RowID so the Loop End (Column Append) yields a single row
  4. Column Aggregator to build the sentence.

All three of the variants behave a bit different in edge cases, so they’re not exactly equal.

Small teaser before you can view the screenshot:
The function getCell() returns the value of any column. Java Snippets process the input row-by-row, so it’s always a single value it returns. The argument can bei either the column name or the column index.
In the end, it writes the first column in the first row, the second column in the second row, and so on.


trace of KNIME table.knwf (83.7 KB)

5 Likes

Hi @kowisoft

Interesting question ! I’m hijacking @Thyme’s first workflow with a pure KNIME alternative using the -Unpivot- node as suggested by @Iris with the following suggestion:

The trick here is to detect when the unpivot row corresponds to a cell in the diagonal of a matrix and this happens when the modulo and the truncation (integer division) of the current cell position are the same:

if( mod( $$ROWINDEX$$, 4) == floor( $$ROWINDEX$$ / 4), 1, 0)

This could be generalized to any shifted diagonal too if needed.

trace of KNIME table with unpivot.knwf (45.9 KB)

Thanks @Thyme & @Iris for your contribution to build up together this solution. :wink:

Hope it helps

Best

Ael

5 Likes

Guys, you are awesome.

In the meantime, I have found some way myself, which - from a mathematical perspective - is possibly the same approach you did.

Noob that I am :wink: I just used a few more nodes but at the end, it’s the same. I “mark” the rows which are in the “diagonal”

And that’s how you create

Demonic Hatcheries of the Elemental Fungus

That’s what was returned, when I re-ran my workflow.

:smiley: :smiley:

Thanks a lot @Thyme , @Iris and @aworker - you really rock! :slight_smile:

8 Likes

@aworker I’m stealing my WF back, your solution is so ingenious I had to have it. Who knows, it might be useful in the future.
btw, I didn’t know we can format node annotations. Since when is that a thing? :sweat_smile:

Anyway, thanks for the challenge! :smiling_face:

2 Likes

Thanks @kowisoft & @Thyme for your kind messages :smiley: !

This challenge & collaborative stealing was really good fun lol :rofl:

Looking forward to next one :smiley: :+1:

Cheers
Ael

3 Likes

Glad you found the solution already, and thank you for such a unique challenge. Here’s my alternative workflow, where the primary nodes are the combination of the Moving Aggregation Node and the Group Loop Node. It works for the dataset you provided. The only caveat for my workflow is you have to alter the Column Filter Node if you’re working on other datasets of similar format/layout containing additional rows.

2 Likes

@kowisoft , next time you have this kind of challenge, you can submit it to the KnimeIt challenge :wink:

Also, to clarify your “rules”:

  • If you’re looping through the table the 1st time (iteration 0) take the content of the 1st column and write it to a new column (final location)
  • If you’re looping through the table the 2nd time (iteration 1) take the content of the 2nd column and write it to the new column (final location)
    etc.

Did you mean 1st row of the 1st column, 2nd row of the 2nd column, etc? Because for me, “the content of the 1st column” means all the rows of the 1st column. It’s only from the highlighted texts and your expected results that I understood what you meant.

3 Likes

@badger101 … that is a very interesting approach. I personally find it super interesting to see the different ways, people approach this problem. Thank you for taking the time to think about this.

@bruno29a Good info, thanks. Wasn’t aware that one can hand in “challenges” - The JustKnimeIT series is the place I send people to, once they were introduced to KNIME. It is really interesting to see the challenges and solutions of all the people.

Regarding your questions: You’re absolutely right, I should have been more precise: What I meant was exactly what you pointed out (1st row of 1st column, 2nd row of 2nd column etc.)

By the way, I have posted the whole workflow including my dice sim to the KNIME Hub so you might roll for some special places as well :wink:

Just for fun, here are some locations I rolled this morning :grinning_face_with_smiling_eyes:

  • Criminal Cliffs of the Slug Minotaur(s)
  • Poisoned Court of the Mental Frog
  • Hidden Prison of the Bone-Executioner
  • Deadly Pits of the Mammoth Scorpion

But the real heroes are you guys, coming up with so many ideas and solutions, I would say, you would overcome the challenges in these locations easily :+1: :heart:

4 Likes

I have looked at the workflow you shared, @kowisoft. Thanks for introducing me to Vernalis Extension. I’m studying it now starting with the random numbers generator.

(P.s. Found a spelling error in the official node description, where it wrote “either Double of Integer format” where it should be “either Double or Integer format.”)

4 Likes

Nice @kowisoft , thanks for sharing.

For submitting ideas for JustKnimeIt, you can take a look at:

2 Likes

Really great solutions here I would never have thought of. Thanks for sharing. Also the amount of solutions is astounding.
I went with a plain good old python logic. I guess I still (maybe to often) consider KNIME as a “low” code not a “no” code ETL Tool.
br

1 Like