cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Did you know you can set a signature that will be added to all your posts? Set it here! X

Extracting rows from a Matrix of results

Perez
12-Amethyst

Extracting rows from a Matrix of results

Hello everyone,

 

I'm encountering a problem with the attached Mathcad Prime 8 where the custom function MaxRecords(M) isn't yielding the expected results when reading imported data from the attached RAW DATA.xlsx.

 

The input matrix "MaxT3" passed to the MaxRecords(M) function, comprises five sets of results for each ID where there is a total of 289 IDs. I need to extract only the records with the maximum resultant force FR (column 10). The result from MaxRecords should have only 289 records, but it's currently delivering 1445 records (289x5). Could you please review and let me know where the issue lies?. 

 

Also, the resultant matrix of maximum records should keep the same order as the matrix MainRunT3:

 

EP_10515634_0-1688172205131.png

I tested the MaxRecords function with a smaller data set and is working fine (see snapshots below of the smaller set raw data and the corresponding MathCAD results):

EP_10515634_1-1688173710514.png

EP_10515634_2-1688173773151.png

 

Finally, please let me know an easy method to disconnect a large matrix from its formula.

 

The attached prime is version 8. Please keep in mind that currently I don't have access to p9.

1 ACCEPTED SOLUTION

Accepted Solutions

OK, I fixed the first part of your own MaxRecords() function (creation of vector R). The second part should work OK

Werner_E_2-1688252107525.png

 

But I preferred to streamline the second half a bit using the match() function.
Here is the function which, as I hope, does what you expect:

Werner_E_1-1688252064313.png

You will notice that MaxRecords2() does not return the very same result as the fixed  MaxRecords(). Reason is that my MaxRecords2() choses the FIRST row if there is more than one row per ID with the same maximum force (occurs usually when the force is zero), while your approach choses the LAST one.

I had already asked in the past what the function should do in that case, but again you ignored that question.

So here is a slight modification which returns the same result as your function:

Werner_E_3-1688252365178.png

 

Werner_E_4-1688252598183.png

 

BUT ... the order of the rows in the result matrix are now NOT THE SAME as their order in the original input matrix.
But it looks to me now that this is what you expect (hopefully!).

I attach the full Prime 9 sheet along with a Prime 6 sheet (I don't have P7 and P8 installed) which just includes the function definitions. You should be able to open that sheet and copy the functions (you have to do it one after the other thanks to PTC) in your P8 sheet.

 

 

View solution in original post

15 REPLIES 15
Werner_E
24-Ruby V
(To:Perez)

From looking at your code I don't know what your function "MaxRecords" is supposed to do and what different result you expect.

From the Excel screenshot you provide its also not clear to me why these three lines would be your expected answer.

All I can say is that with the xls file you provide your function "MaxRecords" seems to return the input matrix unchanged - AllT3 is identical to MaxT3!

Perez
12-Amethyst
(To:Werner_E)

Hello @Werner_E , the function MaxRecords should not return AllT3 unchanged. It should select the rows with the maximum resultant force (column 10) within rows of the same ID (column 2).

 

The screen shot is for a smaller data set where the MaxRecords is working as expected. The range A1:L15 is imported to create the matrix RawDataMainRun. This RawDataMainRun is passed to MaxRecords function which produces matrix Ans. Ans only has the rows per unique ID with the maximum value under column 10 (column K of the excel screen shot).

 

I'm not sure why MaxRecords works for the matrix RawDataMainRun from the screen shot example and does not work for the matrix AllT3. 

Werner_E
24-Ruby V
(To:Perez)

> It should select the rows with the maximum resultant force (column 10) within rows of the same ID (column 2).

 

OK, thats something I could work with.

Why not sort the input matrix for column 2 via csort(M,2) and then run through this sorted matrix, selecting the row with the max value of every next five rows (with the same ID)?

 

Or is it OK to use the raw data "RawDataMainRun" (which seems to be already sorted by ID), as Terry did, with its 9 entries per ID instead of the already modified data (AllT3) ?

 

Just noticed that you wrote that the order of occurrence has to be preserved. So sorting for column 2 might not be an option.

Here is an approach which works on AllT3, does not resort and returns the desired lines. It would also work if the number of cases per ID is not exactly 5 for every ID.

 

In case of equal values in column 10, only the first row in M is returned.

In case you want the last row found returned, you will have to reverse the order in the j-loop (let i run from 0 to rows(M)-1.

And if you want to the function to return all lines in that case you have to change the >= to a > (and the order of the j-loop does not matter).  You would get a matrix with 338 rows instead of the 289. So I guess thats not what you expect.

 

The attached file is in format Prime 9. So you will have to retype from the picture (or wait if someone is able and willing to provide a converted file).

Werner_E_0-1688219599315.png

And yes, I know that my function is very inefficient as of the two large nested loops. But at least I could avoid the time consuming submatrix command in the loops or the memory consuming creation of a structure as large as M. But there sure are much more efficient algorithms possible.

 

P.S.: I have not looked in great detail into your MaxRecords() function, but on first glance it looks to me that it would only work if the argument matrix is sorted for column 2, which your matrix AllT3 is NOT!

Werner_E_2-1688221574744.png

Its the first part of your function which should create the nested vector (a 289x1 vector with 5x19 matrices as elements)

This part of your function skips to the next element (i<--i+1) if the ID in the matrix changes without considering that there might be rows with the same ID later.

Furthermore it look like your approach would not preserve the order in which the lines with the max force value occur in the matrix (as I understood thats something you demanded).

Simple example:

Matrix M:

ID force
A 10
B 50
B 20
A

70

my function would return

ID force
B 50
A

70

while yours would return

ID force
A 70
B 50

 

Perez
12-Amethyst
(To:Werner_E)

Hello @Werner_E , your solution is close, just need to preserve the order of the rows as they first appeared:

 

EP_10515634_0-1688226873233.png

 

Werner_E
24-Ruby V
(To:Perez)


@Perez wrote:

Hello @Werner_E , your solution is close, just need to preserve the order of the rows as they first appeared:


Yes, I thought that my function does exactly that!? Doesn't it?
Where is the problem/error?

Perez
12-Amethyst
(To:Werner_E)

Hello @Werner_E , we should be using the matrix AllT3 as is and the function MaxRecords(AllT3) should work fine and report only the 289 unique IDs after selecting the maximums under column 10.

Why it works for this small matrix and not for the AllT3 matrix?

EP_10515634_2-1688226095248.png

EP_10515634_3-1688226153640.png

 

 

Werner_E
24-Ruby V
(To:Perez)


@Perez wrote:

Hello @Werner_E , we should be using the matrix AllT3 as is


Yes, thats what my function does

 


and the function MaxRecords(AllT3) should work fine and report only the 289 unique IDs after selecting the maximums under column 10.

Yes, again. That's what my function is doing. You still don't say what to do if (for the same ID) the maximum value occurs multiple times  in column 10. But you have the choice as already explained to pick the first, last or even all of them - so its up to you.
You still did not comment on my remark concerning the order of the results. As I already wrote would your function (given that you repair the first part of it as explained) would NOT return the lines in the same as as they appear in the input file M but rather use the order in which the first line of an ID show up (no matter if it contains the max force or not). My function preserves the order. The difference was shown in my answer using that simple 4 row matrix

 


Why it works for this small matrix and not for the AllT3 matrix?


You are talking about your function MaxRecords and not mine?

I had already explained that your function assumes the matrix to be sorted for the ID column 2 which your small matrix may be but AllT3 sure is not. Actually your function does not need the matrix to be sorted for the ID column but all rows  for the same ID must be located directly behind each other. This seems to be the case in your "RawDataMainRun" but not in "AllT3".

Perez
12-Amethyst
(To:Werner_E)

Yes, I thought that my function does exactly that!? Doesn't it?
Where is the problem/error?

Your function MaxRec(M) is working and returning only the unique IDs but just need to keep the order as the ID first appeared in the AllT3 matrix:

EP_10515634_0-1688241549156.png

 

Werner_E
24-Ruby V
(To:Perez)

Your result MaxT3b looks different then the one on my side. Did you use a different input file?

Werner_E_0-1688250126004.png

Anyway, I am referring to my picture here. ID "B69  1" is the first entry in my result vector, because the maximum force for ID "B69  1" (1195) occurs in line 17 of AllT3.

The maximum value for ID "B000  1" (its 93) occurs much later in line 867.
So preserving the order means that ID "B69  1" must be in front of ID "B000  1" as otherwise the order of the lines in the result matrix would differ from the order they occur in the input matrix AllT3!

 

That was the reason for my comparison of the two possible behaviors in a prior answer of mine which you still ignore:

Werner_E_0-1688243750966.png

In my opinion the behavior of my function is keeping the order intact as the rows with the maximum force appear in the very same order as they appear in the argument matrix AllT3. BTW similar to the example picture where you highlighted three rows with yellow

The second behavior which your function would show as soon as you fix the first part of your function does NOT always leave the order intact as the example shows.

OK, I fixed the first part of your own MaxRecords() function (creation of vector R). The second part should work OK

Werner_E_2-1688252107525.png

 

But I preferred to streamline the second half a bit using the match() function.
Here is the function which, as I hope, does what you expect:

Werner_E_1-1688252064313.png

You will notice that MaxRecords2() does not return the very same result as the fixed  MaxRecords(). Reason is that my MaxRecords2() choses the FIRST row if there is more than one row per ID with the same maximum force (occurs usually when the force is zero), while your approach choses the LAST one.

I had already asked in the past what the function should do in that case, but again you ignored that question.

So here is a slight modification which returns the same result as your function:

Werner_E_3-1688252365178.png

 

Werner_E_4-1688252598183.png

 

BUT ... the order of the rows in the result matrix are now NOT THE SAME as their order in the original input matrix.
But it looks to me now that this is what you expect (hopefully!).

I attach the full Prime 9 sheet along with a Prime 6 sheet (I don't have P7 and P8 installed) which just includes the function definitions. You should be able to open that sheet and copy the functions (you have to do it one after the other thanks to PTC) in your P8 sheet.

 

 

Perez
12-Amethyst
(To:Werner_E)

Hello @Werner_E , you got it with the function MaxRecords3. It is extracting only the rows per unique IDs with the maximum value under column 10 but keeping the order as each ID first appeared in the AllT3 matrix. 👍

Werner_E
24-Ruby V
(To:Perez)


@Perez wrote:

Hello @Werner_E , you got it with the function MaxRecords3.

Yes, I thought I did so.  It's just a pity that I had to polish my crystal ball to a high gloss and use it intensively and guess the actual specifications 😞

 


It is extracting only the rows per unique IDs with the maximum value under column 10 but keeping the order as each ID first appeared in the AllT3 matrix. 👍

"keeping the order as each ID first appeared" was an info which you missed to explain so far because this means that the actual lines with the max values do not keep their relative order! This was the reason I asked and showed that simple four line example.

 

BTW, MaxRecords2 does the very same! As already explained the difference is the treatment of the elements where the max value shows up more than once. Even after asking, you did not provide any information on how you would like this case to be handled.

 

Glad you finally still got what you were looking for

Hi

I only have Prime 9 so you will have to copy by hand.

A simpler program to extract the maximums exploiting the fact that there are 9 load cases per record

Capture.JPG

 

Results in:

Capture2.JPG

 

Cheers

Terry

Hello @terryhendicott , please adapt your proposed function to be use with the matrix AllT3. Process the matrix AllT3 as is with no preprocessing or sorting of any kind. I tried to adapt it with no success:

EP_10515634_0-1688225041967.png

EP_10515634_1-1688225073490.png

 

 

Top Tags