# Convert matrix to vector of structs

63 views (last 30 days)
Daniel Underwood on 2 Apr 2011
Answered: Julian Hapke on 20 Oct 2016
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.

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.

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.
Daniel Underwood on 2 Apr 2011
Thanks. Ultimately, I did use your method.

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 on 2 Apr 2011
My answer to your subsequent question, 4581, may be relevant to this also.

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