how to get max, min and avg of a field of a structure in a cell matrix

26 views (last 30 days)
Hi
I have a cell matrix consisting of 3 columns and 400 rows. Every entry in this matrix is a structure. Lets say three columns are A, B and C. Column A contains same structure StructureA, Column B contains same structure StructureB, Column C contains same structure StructureC in all rows. Let say StructureC contains 4 fields field1, field2, field3 and field4.
  1. I want to find max and min value of field3 across all rows in column C.
  2. Then I want to find out which row of ColumnC contains max value and which row contains min value of field3.
  3. Then I want to find out the average of field3 across all rows in ColumnC.
  4. Finally I want to get all the rows where field3 equals to some value, such as get all the rows where field3 = 'abc' in ColumnC.
I have already tried below code to calculate the max value but it did not work
maxField3 = max(Column3{:,3}.field3)
I don't want to use loop for calculating these things. Please help.
Thanks in advance.

Accepted Answer

Stephen23
Stephen23 on 5 Feb 2016
Edited: Stephen23 on 5 Feb 2016
I would suggest that you convert your data in a non-scalar structure, then your task become trivial using basic indexing and commands. The best solution would be to get rid of the cell array entirely, and have just one non-scalar structure. If the three columns require different fields, then three non-scalar structures will be required.
Hers is an example of a non-scalar structure, and how easy it is access its data:
>> S = struct('f1',{1,2,3,4},'f2',{10,20,30,0});
>> size(S)
ans = 1 4
>> S(3).f1
ans = 3
>> [S.f1]
ans = 1 2 3 4
>> [val,idx] = max([S.f2])
val = 30
idx = 3
You can also use indexing, arrayfun, and many other operations.
You will find your code a lot simpler to write if you use non-scalar structure instead of putting lots of separate structures into a cell array. Here is how to concatenate a cell array of structures into one non-scalar structure:
>> X = {struct('f1',1,'f2',10);struct('f1',2,'f2',20);struct('f1',3,'f2',30)};
>> S = vertcat(X{:});
  4 Comments
Stephen23
Stephen23 on 6 Feb 2016
"but this is not going to solve my problem."
Yes it does.
Oh, and it is also exactly the same concept that you used in your answer, so therefore it must actually solve your problem.
Matt J
Matt J on 6 Feb 2016
So I though the best way to keep the data in a proper way is to use cell matrix of structure. And while using this matrix I want to find out the Max, Min and average of the fields in a column.
You said in your original post that you didn't want to use a loop, which sounds like you are trying to optimize the speed of your code. Otherwise why would you care about avoiding loops?
Both cell arrays and structure arrays are bad for speed optimization. They scatter the data around RAM in inefficiently accessible ways. It is better to read your Excel data directly into a matrix, rather than split it across all kinds of cells and structs. There's no clear reason why you couldn't do that.

Sign in to comment.

More Answers (1)

Anil Verma
Anil Verma on 6 Feb 2016
I got the solution.
For calculating max of a field of a structure in Column3 of cell matrix StructreCellMatrix
Find all the desired structure
desiredStructure = [StructreCellMatrix{:,3}];
find max of a field of a structure
maxField3 = max[desiredStructure.field3];
Similar procedure can be done for calculating min and average
  2 Comments
Stephen23
Stephen23 on 6 Feb 2016
Edited: Stephen23 on 7 Feb 2016
That is exactly the concept that I showed you in my answer. Here it is again, just in case you missed it. First convert to a non-scalar structure (just like you do):
S = vertcat(X{:}); % or with indexing
then get the values into an array and perform your calculation (just like you do):
[val,idx] = max([S.f2])
Amazing. You see, not only did I already give you this answer one day ago, I also told you why storing your data in a non-scalar structure would be much much easier for you. Do you realize that my (and your identical) solution first converts your complicated cell array of structures into one non-scalar structure? Your variable desiredStructure is a non-scalar structure. And you could make all of your code much simpler if you used just this instead of wasting your time with individual structures in cell arrays. Don't worry, most beginners ignore good advice, although Matt J and I showed you two ways of making your code simpler and faster.
Matt J
Matt J on 6 Feb 2016
Edited: Matt J on 7 Feb 2016
maxField3 = max[desiredStructure.field3];
This is better than what you were doing before, but it is still unclear why you wouldn't read all of the field3 values from Excel directly into its own matrix. If you expect to be processing data as a group, as when doing max, min, averages, etc..., a matrix is much more appropriate and efficient than structs or cells.
And that's exactly what you ended up doing anyway, but a lot more slowly and indirectly. The statement [desiredStructure.field3] just unsplits your field3 data from structure fields and consolidates them in a matrix of its own.

Sign in to comment.

Categories

Find more on Structures in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!