appending a column in output

Hi I am trying to append a column to the input table and return that table as a result.
I am using the following:

DataColumnSpec[] allColSpecs = new DataColumnSpec[n+2];
for (int i = 0; i < n; i++) {
allColSpecs[i] = new DataColumnSpecCreator(inSpec.getColumnSpec(i))
.createSpec();
}
allColSpecs[n] =
new DataColumnSpecCreator(“ChrStr”, StringCell.TYPE).createSpec();
allColSpecs[n+1] =
new DataColumnSpecCreator(“Abs_position”, IntCell.TYPE).createSpec();
DataTableSpec outputSpec = new DataTableSpec(allColSpecs);
BufferedDataContainer container = exec.createDataContainer(outputSpec);

DataCell[] cells = new DataCell[2];
Integer out = Integer.parseInt(test[test.length-1]);
cells[1] = new IntCell(out);
cells[0]= new StringCell(out2);
AppendedColumnRow newRow = new AppendedColumnRow(row,cells);
container.addRowToTable(newRow);

Then after a while I get the following error:

ERROR KNIME-Worker-0 PositionStr2Position Execute failed: Cell count in row “RowKey0” is not equal to length of column names array: 5 vs. 3

Does anyone have an idea of what I am doing wrong?

Thanks,

Bernd

Hi Bernd, Have you done the DataColumnSpec[] allColSpecs = new DataColumnSpec[n+2]; for (int i = 0; i < n; i++) { allColSpecs[i] = new DataColumnSpecCreator(inSpec.getColumnSpec(i)) .createSpec(); } allColSpecs[n] = new DataColumnSpecCreator(“ChrStr”, StringCell.TYPE).createSpec(); allColSpecs[n+1] = new DataColumnSpecCreator(“Abs_position”, IntCell.TYPE).createSpec(); DataTableSpec outputSpec = new DataTableSpec(allColSpecs); thing in the configure(…) method too? I think that is the problem. (You might also consider using the ExecutionContext#createColumnRearrangeTable(…) method instead of createDataContainer(…))

sorry forgot to meantion:
This is my configure:

@Override
protected DataTableSpec[] configure(final DataTableSpec[] inSpecs)
        throws InvalidSettingsException {

	DataTableSpec inSpec = inSpecs[0];
	int n=inSpec.getNumColumns();
    DataColumnSpec[] allColSpecs = new DataColumnSpec[n+2];
    for (int i = 0; i < n; i++) {
		allColSpecs[i] = new DataColumnSpecCreator(inSpec.getColumnSpec(i))
				.createSpec();
	}
    allColSpecs[n] = 
        new DataColumnSpecCreator("ChrStr", StringCell.TYPE).createSpec();
    allColSpecs[n+1] = 
        new DataColumnSpecCreator("Abs_position", IntCell.TYPE).createSpec();
    DataTableSpec outputSpec = new DataTableSpec(allColSpecs);

    return new DataTableSpec[]{outputSpec};

}

Also, do you have and example for the ExecutionContext#createColumnRearrangeTable(…).
Thx
B

Hi Bernd,

I am sorry I see no problems with your code (although I have not used AppendedColumnRow before, so there might be a bug). Here are some code adding multiple columns. (Sorry about the low quality of the example.)
Bests, gabor

Hi, the configure method looks okay, however, you should double-check the output spec after the node has been successfully configured inside the node’s out-port view tab “DataTableSpec”. Does it contain the right number of columns with the correct types? From the error message of your initial post it looks that the execute method generates a data row containing less columns (3) that expected (5). Best, Thomas

when debugging and examining newRow it consists of m_appendCell with (two entries) and m_baseRow with three entries, as well as m_rowKey.
So I am expecting the addRowToTable function to handle this “AppendColumnRow” class correctly. (Which I assume it doesn’t??)

Hi, the problem might be that the (Buffered)DataContainer has been created with the input data table spec, but has to be created with the output table spec which is same as created in the configure method. I would recommend to put the code from the configure method into a private method which is than accessed by configure and execute. Best, Thomas

The best way to do this is to use a ColumnRearranger for this purpose (there is actually a quite good example in the java doc). It has different advantags over a AppendColumnRow. It is simpler and, most notably, it does not copy the input table!

Yes, I managed to understand the ColumnRearranger and it works now. The only problem I had initially was that the execution or the actual work is not done in the execute method but in columnrearranger. To me this didn’t seem very elegant or clear, but hey it works now…