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.