/*********** k-th Smallest Elements of a Matrix ************** Author: Scott Thompson U.S. Dept. of Justice Date: 28 June 2002 Purpose: find k-th smallest element in each matrix column Caveat: this code is supplied gratis but without warrantee. Comments: Assumes numeric data. Sorting all of the data is generally not a very efficient way to go if the matrix has many rows, especially when k is small. Think about how much faster minc is than sortc when rows(x) is large, for example. Instead I eliminate the smallest value from each column k-1 times, then returning the minimum from each column. This has the further advantage of treating missing or complex values in exactly the same way that minc treats them, unlike algorithms based on sortc. I didn't include any error checking, however. The proc could be made faster still by coding a DLL that found the k-1 smallest values in each column in one pass through the data. ************************************************************/ proc minck(x,k); local c, z, i, missing; c = cols(x); missing = {. }; z = minindc(x); do while k>1; for i (1,c,1); x[z[i],i] = missing; endfor; z = minindc(x); k = k-1; endo; for i (1,c,1); z[i] = x[z[i],i]; endfor; retp(z); endp; /* Additional comment: the perhaps more obvious approach based on sorting, as in the following proc, is much slower */ proc mincksort(x,k); for i(1,cols(x),1); x[.,i] = sortc(x[.,i],1); endfor; retp(x[k,.]'); endp ; /* Additional comment: oddly minc() is slower than minindc(), so that the following variant is slightly slower! */ proc minckodd(x,k); local z, missing; missing = {. }; do while k>1; z = minindc(x); for i(1,cols(x),1); x[z[i],i] = missing; endfor; k = k-1; endo; retp(minc(x)); endp;