Extracting rows from a 2D wave

Is there a way to elegantly pull rows out of a 2D matrix and put them together in a 
newly created 2D wave without using for loop (or any other loop)? 

I have a 2D wave with data and a corresponding 1D wave containing sample codes for each row of the 2D wave. Different rows of the 2D wave can have the same sample code in the 1D wave. 

I want to extract rows from the 2D wave that correspond to a specific code 
and put them into a newly created 2D wave. Can this be done without running a for loop? 

The rows are not clustered together in the original 2D wave so I cannot use duplicate/RMD.  

 

On this note, is it possible to sort rows of a 2D wave based on a corresponding 1D wave using Sort (or something else)? I'm currently running for loop to do this..

Kindly advise. 

Thanks! 

You can use the Extract operation on your 1D sample code wave. Use the /INDX flag so that you get an index wave with the row numbers containing the desired code. Then you can make a wave and assign to it in two lines:

Make/N=(numpnts(indexwave), DimSize(matrixwave, 1)) MatrixForCode
MatrixForCode[][] = matrixwave[indexwave[p]][q]

Naturally, for "indexwave" use the wave you set as the destination for Extract; for "matrixwave" use the actual name of the matrix with the rows you want to extract; and for "MatrixForCode" use the actual name that want that matrix to have.

Great, thanks a lot, @johnweeks! Somehow it had completely slipped my mind that indices pulled with extract can be directly used to allocate rows in a 2D wave. Appreciate the help! 

Can "Extract" be used when there are multiple values/strings to check within a numeric/text wave? 

For example: 

I have a main 1D text wave (call main1D) containing strings, lets say a1,a2,a3,a4,a1,a3,a4,a2,a1,a4,a1,a2,a3,a2,a4.. 

and a global string (call code1D) containing selection strings, lets say a1,a3,a4. 

I want all index values from main1D that match up against all entries in SVAR code1D.

I am trying: 

 extract/INDX/O main1D, main1Dindex, (stringmatch(stringfromlist(p,code1D),main1D[p]) == 1 )

but this does not work. main1Dindex returns null.

Kindly advise.. 

 

Your global string is a stringlist. If you want to test whether a string occurs in a list you can use WhichListItem (or FindListItem or ListMatch or GrepList).

so your logical expression for extract is something like

WhichListItem(code1D,  main1D, ",") > -1

 

Hi Tony, 

Thanks for the advice. I did the following, yet the output wave main1Dsub is null for some reason. Could you please suggest what I maybe doing incorrectly? 

SVAR code1D

wave/t main1D

extract/t/o main1D, main1Dsub, (whichlistitem(code1D, main1D, ",") > -1)

It works if I replace code1D with "stringfromlist(0,code1D)" to look for the first string. However, I need to identify all strings in the global string variable, and I am trying to do this without using the for loop.. I think that's where it is not working..

Maybe to debug you can break it down into parts. Using the example in your post:

print code1D
// should be "a1,a3,a4"
print main1D[2]
// should be "a3"
print WhichListItem(code1D, main1D[2], ",")
// should be 1

Or you could enter expressions in the debugger to investigate.

In reply to by Peeyush Khare

Peeyush Khare wrote:

It works if I replace code1D with "stringfromlist(0,code1D)" to look for the first string.

Then maybe your code1D stringlist uses the default separator, not a comma. So don't specify the separator string as ",".