edit row

Hi,

I need to remove the first character from a particular column.

How can i edit a row? i haven't the method setcell

This is my code:

protected BufferedDataTable[] execute(final BufferedDataTable[] inData,
            final ExecutionContext exec) throws Exception {
            
        DataTableSpec inSpec = inData[0].getDataTableSpec();
        BufferedDataContainer buf = exec.createDataContainer(inSpec);
        int column_index = inSpec.findColumnIndex(m_colSel.getStringValue());
        final int nrRows = inData[0].getRowCount();
        int count=0;
        for (DataRow row : inData[0]) {

            String current_value=row.getCell(column_index).toString();
            //code???//
            buf.addRowToTable(row)
            
            exec.checkCanceled();
            exec.setProgress(count / (double) nrRows, 
                    "Added row " + (++count) + "/" + nrRows + " (\"" 
                    + row.getKey() + "\")");

        }
        
        BufferedDataTable[] out = new BufferedDataTable[1];
        buf.close();
        out[0]=buf.getTable(); 
  
            
        return out;
    }

 

Thanks

You don't edit a cell directly, using the approach you have taken above I think you are just returning the input row directly using the line: buf.addRowToTable(row) 

Instead you need to create a new row with the changed value for the cell you are editing. 

I've made an example gist of how you may do this: https://gist.github.com/webbres/c4ee153c7d58da1c8ec5 

However the reccomendation is probably to use a column rearranger for this activity. This is more confusing for a new KNIME developer I would say though. 

Hi, thanks but the link does not work.

There is an example here:

http://tech.knime.org/execute-0

Following the link of the previous post i can solve my problem with Example 2 and 3.

-Example3-

I need to split the input into M outputs and i think that i need M columnRearranger. The code seem to iterate over the rows for each output port. If the loop for the rows have complexity N, my code at last have complexity M*N, right? It is a problem...

-Example2-

I need to create a cell based on the type of a previous cell. There isn't a constructor with the type in input. Must i do a series of if?

if(prev_type=="string")

datacell d = new stringcell(...);

if(prev_type=="int")

datacell d = new intcell(...);

The ColumnRearranger is "only" useful when the number of input rows equals the number of output rows (e.g. adding/replacing a column). If you want to split one input table into several output tables, then you cannot use the ColumnRearranger. You create M BufferedDataContainers and add a row to the appropriate container. So you have a linear complexity.

For your second question: yes, you have to write a line for each cell type because each cell constructor has (potentially) different argument types so there is no way to do it generic.

i post some pseudocode:

/*i must create arrays of each type to know the type of the column inside the for(rows).

I can't do it in the for why a missing value is a type string and not the real type of the column*/

array index_string 

array_index_int 

array_index_double

array_index_date

for(int i=0;i<rows;i++)

    for(int j=0;j<cols;j++)

    {//make new cell
    String curr_val = row(i).cell(j).toString();
    //missing code (edit curr_val)
    if(index_int.contain(j))
        if(curr_val equals("?"))
           //i can't create an int cell empty...What i can do in this case? i need an empty cell
        else
            curr_cell =parseint(curr_val)
    if(index_double.contain(j))
        .
        .


    }
//add the row
}

Am i totally foolish =)?

I don't get what exactly you are trying to achieve. Maybe you can post an example with concrete values first.

Well, my node permits to choose a column.

This column must be split into N exits depending on the value

Example table:

column "RAPP01" type string values (aa,bb,aa,cc)

column "date" type date values (2014-10-10,2014-10-10,2014-10-10,?) 

the ? is an empty cell

result table 1

    mod_aa/2014-10-10

    mod_aa/2014-10-10

result table 2

    mod_bb/2014-10-10

result table 3

    mod_cc/?

all others are empty tables...

I can do this implementation without to modify the input and all work.

Now i need to edit the column named RAPP and this is the problem because i must replicate the missing values.

Some hints to improve performance of this code is well-accepted =)

 

protected BufferedDataTable[] execute(final BufferedDataTable[] inData,
            final ExecutionContext exec) throws Exception {

        NodeLogger n = NodeLogger.getLogger(SplitterDQNodeModel.class);

        DataTableSpec inSpec = inData[0].getDataTableSpec();
        ArrayList<BufferedDataContainer> buf = new ArrayList<BufferedDataContainer>();
        for(int i=0;i<EXIT;i++)
            buf.add(exec.createDataContainer(inSpec));
        
        int column_index = inSpec.findColumnIndex(m_colSel.getStringValue());
        
        String[] column = inSpec.getColumnNames();
        ArrayList<Integer> index_column_rapp= new ArrayList<Integer>();
        for(int i=0;i<column.length;i++)
        {
            if(column[i].toUpperCase().indexOf("RAPP")!=-1)
                    index_column_rapp.add(i);
            
            if(inSpec.getColumnSpec(i).getType().toString().equals("IntCell"))
                index_column_int.add(i);
            if(inSpec.getColumnSpec(i).getType().toString().equals("DoubleCell"))
                index_column_double.add(i);
            if(inSpec.getColumnSpec(i).getType().toString().equals("DateAndTimeCell"))
                index_column_data.add(i);
        }

        int count = 0;

        final int nrRows = inData[0].getRowCount();

        ArrayList<String> list_value=new ArrayList<String>();

        for (DataRow row : inData[0]) {
            
            int nrColumns = row.getNumCells();
            DataCell[] cells = new DataCell[nrColumns];
            
            for (int i = 0; i < nrColumns; i++) {

                String current_value = row.getCell(i).toString();
                
                
                if(index_column_rapp.contains(i))
                    current_value = U_rappID(current_value);

                
                cells[i] = new StringCell(current_value);
                
                if(index_column_int.contains(i))
                    {if(!current_value.equals("?"))
                        cells[i] = new IntCell(Integer.parseInt(current_value));    
                    else
                        cells[i] = new IntCell(0);    
                    }
                else
                if(index_column_double.contains(i))
                    {if(!current_value.equals("?"))
                        cells[i] = new DoubleCell(Double.parseDouble(current_value));
                    else
                        cells[i] = new DoubleCell(0.0d);
                    }
                else
                    if(index_column_data.contains(i))
                        {if(!current_value.equals("?"))
                        {    
                            int year=Integer.parseInt(current_value.substring(0,4));
                            int month=Integer.parseInt(current_value.substring(5,7));
                            int day=Integer.parseInt(current_value.substring(8,10));
                            cells[i] = new DateAndTimeCell(year,month-1,day);
                        }
                        else
                            cells[i] = new DateAndTimeCell(1000, 0, 1);
                        }
                
            }
            DataRow new_row = new DefaultRow(row.getKey(), cells);

            
            
            String current_value=row.getCell(column_index).toString();
            int index = list_value.indexOf(current_value);
            if(index==-1)
            {    
                if(list_value.size()<EXIT)
                    {buf.get(list_value.size()).addRowToTable(new_row);
                    list_value.add(current_value);
                    }
                else
                {
                    buf.get(EXIT-1).addRowToTable(new_row);
                }
            }
            else
                buf.get(index).addRowToTable(new_row);


            exec.checkCanceled();
            exec.setProgress(count / (double) nrRows, 
                    "Added row " + (++count) + "/" + nrRows + " (\"" 
                    + row.getKey() + "\")");
        }
        
        BufferedDataTable[] out = new BufferedDataTable[EXIT];
        
        for(int i=0;i<EXIT;i++)   {        
            buf.get(i).close();
            out[i]=buf.get(i).getTable(); 
        }               

            
        return out;

    }

Well, my node permits to choose a column.

This column must be split into N exits depending on the value

Example table:

column "RAPP01" type string values (aa,bb,aa,cc)

column "date" type date values (2014-10-10,2014-10-10,2014-10-10,?) 

the ? is an empty cell

result table 1

    mod_aa/2014-10-10

    mod_aa/2014-10-10

result table 2

    mod_bb/2014-10-10

result table 3

    mod_cc/?

all others are empty tables...

I can do this implementation without to modify the input and all work.

Now i need to edit the column named RAPP and this is the problem because i must replicate the missing values.

Some hints to improve performance of this code is well-accepted =)

protected BufferedDataTable[] execute(final BufferedDataTable[] inData,
            final ExecutionContext exec) throws Exception {

        NodeLogger n = NodeLogger.getLogger(SplitterDQNodeModel.class);

        DataTableSpec inSpec = inData[0].getDataTableSpec();
        ArrayList<BufferedDataContainer> buf = new ArrayList<BufferedDataContainer>();
        for(int i=0;i<EXIT;i++)
            buf.add(exec.createDataContainer(inSpec));
        
        int column_index = inSpec.findColumnIndex(m_colSel.getStringValue());
        
        String[] column = inSpec.getColumnNames();
        ArrayList<Integer> index_column_rapp= new ArrayList<Integer>();
        for(int i=0;i<column.length;i++)
        {
            if(column[i].toUpperCase().indexOf("RAPP")!=-1)
                    index_column_rapp.add(i);
            
            if(inSpec.getColumnSpec(i).getType().toString().equals("IntCell"))
                index_column_int.add(i);
            if(inSpec.getColumnSpec(i).getType().toString().equals("DoubleCell"))
                index_column_double.add(i);
            if(inSpec.getColumnSpec(i).getType().toString().equals("DateAndTimeCell"))
                index_column_data.add(i);
        }

        int count = 0;

        final int nrRows = inData[0].getRowCount();

        ArrayList<String> list_value=new ArrayList<String>();

        for (DataRow row : inData[0]) {
            
            int nrColumns = row.getNumCells();
            DataCell[] cells = new DataCell[nrColumns];
            
            for (int i = 0; i < nrColumns; i++) {

                String current_value = row.getCell(i).toString();
                
                
                if(index_column_rapp.contains(i))
                    current_value = U_rappID(current_value);

                
                cells[i] = new StringCell(current_value);
                
                if(index_column_int.contains(i))
                    {if(!current_value.equals("?"))
                        cells[i] = new IntCell(Integer.parseInt(current_value));    
                    else
                        cells[i] = new IntCell(0);    
                    }
                else
                if(index_column_double.contains(i))
                    {if(!current_value.equals("?"))
                        cells[i] = new DoubleCell(Double.parseDouble(current_value));
                    else
                        cells[i] = new DoubleCell(0.0d);
                    }
                else
                    if(index_column_data.contains(i))
                        {if(!current_value.equals("?"))
                        {    
                            int year=Integer.parseInt(current_value.substring(0,4));
                            int month=Integer.parseInt(current_value.substring(5,7));
                            int day=Integer.parseInt(current_value.substring(8,10));
                            cells[i] = new DateAndTimeCell(year,month-1,day);
                        }
                        else
                            cells[i] = new DateAndTimeCell(1000, 0, 1);
                        }
                
            }
            DataRow new_row = new DefaultRow(row.getKey(), cells);

            
            
            String current_value=row.getCell(column_index).toString();
            int index = list_value.indexOf(current_value);
            if(index==-1)
            {    
                if(list_value.size()<EXIT)
                    {buf.get(list_value.size()).addRowToTable(new_row);
                    list_value.add(current_value);
                    }
                else
                {
                    buf.get(EXIT-1).addRowToTable(new_row);
                }
            }
            else
                buf.get(index).addRowToTable(new_row);


            exec.checkCanceled();
            exec.setProgress(count / (double) nrRows, 
                    "Added row " + (++count) + "/" + nrRows + " (\"" 
                    + row.getKey() + "\")");
        }
        
        BufferedDataTable[] out = new BufferedDataTable[EXIT];
        
        for(int i=0;i<EXIT;i++)   {        
            buf.get(i).close();
            out[i]=buf.get(i).getTable(); 
        }               

            
        return out;

    }

 

There are several errors in your code: Instead of

inSpec.getColumnSpec(i).getType().toString().equals("IntCell")

you must use

inSpec.getColumnSpec(i).isCompatible(IntValue.class)

The other types are handled accordingly. Never (!!!) check of the type but instead always use the value interfaces and isCompatible.

Then, if you want to check for missing values use "cell.isMissing()" instead of comparing to "?". Third, in order to create a missing value, use "DataType.getMissingCell()".

 

Thanks =)