Delete rows or columns of a 2D wave (DimLabel aware)

Snippet to delete rows or columns of a 2D wave according to a 0/1 index wave. Inspired by A.G.'s comment here:

https://www.wavemetrics.com/forum/general/removing-row-matrix-contains-specific-value-first-column

although I did not follow his suggestion to transpose the matrix in case rows are supposed to be eliminated. At least in my few tests the speed benefit for deleting columns was eaten up by ^t. 

The snippet is quite useful for filtering large datasets in combination with MatrixOP greater/equal/within.  

 

function DeleteRowsOrCols(wave w2d, wave idx [, int dl, int o])
    // w2d is a n x m matrix; w2d MUST NOT contain NaN's
    // idx is either 1D with numPnts(idx) = n or 2D with 1 x m columns
    // idx has values of either 1 or 0; if 0 at p or q, rows or cols of w2d will be eliminated
    // if dl is specified as non-zero integer DimLabels are preserved
    // if o is specified as non-zero integer w2D is overwritten, otherwise output is named NameOfWave(w2d)_mod
   
    variable i, dim = DimSize(idx,1) != 0 ? 1 : 0
    variable nIdxPnts = DimSize(idx,dim)
    variable nRows = DimSize(w2D,0)
    variable nCols = DimSize(w2D,1)
    MatrixOP/FREE nKeeps = sum(idx)
   
    // change idx from 0/1 to NaN/1; make sure idx is at least SP, required after e.g. MatrixOP greater/within/equal
    MatrixOP/FREE tmp = replace(fp32(idx), 0, NaN)
   
    if (dim == 0)
        // eliminate rows
        if(nRows != nIdxPnts)
            print "Incompatible dimensions!"
            return 0
        endif
        MatrixOP/FREE out = redimension(zapNaNs(scaleRows(w2d,tmp)), nKeeps, nCols)
    else
        // eliminate cols
        if(nCols != nIdxPnts)
            print "Incompatible dimensions!"
            return 0
        endif
        MatrixOP/FREE out = redimension(zapNaNs(scaleCols(w2d,tmp)), nRows, nKeeps)
    endif
   
    // preserve Dimlabels?
    if(!paramIsDefault(dl) && dl != 0)
        if (dim == 0)
            MatrixOP/FREE DLidx = zapNaNs(scaleRows(tmp,indexRows(idx)))
            CopyDimlabels/Cols=1 w2d, out
        else
            MatrixOP/FREE DLidx = zapNaNs(scaleCols(tmp,indexCols(idx)))
            CopyDimlabels/Rows=0 w2d, out
        endif
        for(i=0; i<nKeeps[0]; i++)
            SetDimlabel dim, i, $GetDimLabel(w2d, dim, DLidx[i]), out
        endfor
    endif
   
    // overwrite or rename output
    if(!paramIsDefault(o) && o != 0)
        Duplicate/O out, w2d
    else
        Duplicate/O out, $NameOfWave(w2d)+"_mod"
    endif

    return 1
end

 

Forum

Support

Gallery

Igor Pro 9

Learn More

Igor XOP Toolkit

Learn More

Igor NIDAQ Tools MX

Learn More