Grouping points in XY data into user-defined bins for retrieving statistics

Hello,

I was wondering if there was an equivalent in Igor for the discretize() function in MATLAB. I've attached a description of this function here. This function returns the indices of the bins that contain the elements of X.

For example, if I had a wave X  [1,3,3,5,7] and edges [2,4,6,8], the function would return [NaN,1,1,2,3]. Having this function would enable me to retrieve a wave of indices that I can use to select points in other waves of the same size as X so I can calculate statistics (e.g., mean, stdev, number of points) etc. 

For the time being, I have been copying and pasting waves from Igor into MATLAB to use this function and then copying them back into Igor, which has been time-consuming. 

Thank you for your time.

Here's an attempt to write discretize as a user function:

function/wave discretize(wave wX, wave edges)
    Make/free/N=(numpnts(wX), numpnts(edges)) M
    M[][1,] = q * ((wX[p] >= edges[q-1]) && (wX[p] < edges[q]))
    MatrixOP/free wOut = sumRows(M)
    wOut = wOut ? wOut : NaN
    return wOut
end

I assume edges to be monotonic.

The way I did it is probably wildly inefficient. Probably someone will be able to improve upon this.

 

Here is an arguably better way to do it with a user function:

function/wave discretize(wave wX, wave edges)
    duplicate /free wX wOut
    wOut = BinIndex(wX, edges)
    return wOut
end

function BinIndex(variable xval, wave edges)   
    int i
    int imax = numpnts(edges)
   
    if ( (xval < edges[0]) || (xval>=edges[imax-1]) )
        return NaN
    endif
   
    for (i=1;i<imax;i++)
        if ( (xval >= edges[i-1]) && (xval < edges[i]) )
            return i
        endif
    endfor
    return NaN
end

 

it's more efficient to use a built-in function:

function/wave discretize(wave wX, wave edges)
    Duplicate /free wX wOut
    wOut = BinIndex(wX, edges)
    return wOut
end

function BinIndex(variable xval, wave edges)
    FindLevel/EDGE=1/P/Q edges, xval
    return v_flag ? NaN : floor(v_levelX) + 1
end

 

Thank you for your work and thoughts Tony! I had not used FindLevel before, this works very well in the user-defined functions you made.