Convert matrix to vector of structs

10 views (last 30 days)
I wish to convert a matrix to a vector of structs, such that each column of the matrix is represented by a struct.
The problem with the code
M = struct('a',[1 2 8],'b',[2 1 3])
is that I cannot index into M directly by entering
M(1)
or
M(2)
etc... After forming the vector of structs, I need to be able to delete the i-th row (or the i-th field of every struct in the vector.
For example, suppose I have a vector of structs representing people. The vector is named "people", and it has two structs, "name" and "age". I need to be able to refer to all people over the age of 40 using the following code:
people(people.age>40)
or retrieve the names of all people between the age of 20 and 30 using the following code:
people(people.age>=20 & people.age<=30).name
I would greatly appreciate any help.

Accepted Answer

Daniel Underwood
Daniel Underwood on 5 Apr 2011
Here's the solution I ultimately used and prefer, where "M" is a real matrix:
data = struct( 'id', M(:,11), ...
'PSAtests', M(:,1), ...
'PSAestimate', M(:,3), ...
'PSA', M(:,10), ...
'isActual', 1-M(:,4), ...
'age', M(:,5), ...
'cancer', M(:,6), ...
'cancerAge', M(:,7), ...
'biopsy', M(:,8), ...
'biopsyAge', M(:,9) );
Then, if I wish to modify "data", I use the function "subsetstruct" which is part of Matlog, provided at the following URL:
To use "subsetstruct", I simply create a logical index array and can create a new struct which is a subset of my "data" struct, for example:
olderpatients = subsetstruct(data,data.age>80);
I'm very happy with this solution. And thanks for everyone's help.

More Answers (4)

Matt Fig
Matt Fig on 2 Apr 2011
I am a little confused by your terminology. It seems that you are mixing the use of the terms 'stuctures' and 'fieldnames' of structures. So perhaps this won't help, but let me know if I am on the right track.
people(1).name = 'Angel';
people(2).name = 'Steve';
people(3).name = 'Jeff';
people(4).name = 'Bill';
people(5).name = 'Jim';
people(6).name = 'Matt';
people(1).age = 20;
people(2).age = 28;
people(3).age = 45;
people(4).age = 19;
people(5).age = 30;
people(6).age = 26;
idx = [people(:).age]>20 & [people(:).age]<30; % Those in age range.
people(idx).name % And their names.
EDIT
.
.
I recommend you read the help on CELL2MAT and CELL2STRUCT. They should get you where you need to go.

the cyclist
the cyclist on 2 Apr 2011
You can create the sort of indexing you want if you enclose the condition in square brackets:
[people.age]>=20
will give the logical vector you want.

David Young
David Young on 2 Apr 2011
My answer to your subsequent question, 4581, may be relevant to this also.

Julian Hapke
Julian Hapke on 20 Oct 2016
simpler without any external functions
olderpatients = structfun(@(X) X(data.age>80),data,'Uni',false);

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!