Accessing field data in nonscalar structure array

4 Ansichten (letzte 30 Tage)
KAE
KAE am 18 Nov. 2019
Kommentiert: KAE am 19 Nov. 2019
Let's say I have a nested non-scalar structure array,
Patient(1).Vitals.weight = 185;
Patient(1).Vitals.temperature = [98 96 100 101];
Patient(1).Vitals.mood = {'Good'};
Patient(1).Location.state = 'VA';
Patient(2).Vitals.weight = 203;
Patient(2).Vitals.temperature = [97 97 98 99];
Patient(2).Vitals.mood = {'Fair'};
Patient(2).Location.state = 'NC';
Patient(3).Vitals.weight = 190;
Patient(3).Vitals.temperature = [98 99 99 100];
Patient(3).Vitals.mood = {'Bad'};
Patient(3).Location.state = 'CT';
I would like to acess the data, for example creating (a) a vector containing the weights [185 203 190], (b) a cell array containing the states {'VA', 'NC', 'CT'}, and (c) a matrix containing the temperature values [98 96 100 100; 97 97 98 99; 98 99 99 100]. I want to avoid looping through Patient(1), Patient(2), etc. since my real structure array is large. How do I extract the data? Some failed attempts are listed below.
Patient.Vitals.weight
% Expected one output from a curly brace or dot indexing expression, but there were 2 results.
[Patient.Vitals.weight]
% Expected one output from a curly brace or dot indexing expression, but there were 2 results.
Patient(:).Vitals.weight
% Expected one output from a curly brace or dot indexing expression, but there were 2 results.
Any suggestions? Or is there some other data storage form better suited to data extraction? [I am using multilevel nesting because my real structure is an output of xml2struct, and perhaps I could flatten the results, but then I will lose some data organization.]

Akzeptierte Antwort

Daniel M
Daniel M am 18 Nov. 2019
Bearbeitet: Daniel M am 18 Nov. 2019
Here is a solution. You'll have to write the functions differently for gathering cells and arrays.
fun = @(s,field) {s.(field)}; % use {} for string/char
output = fun([Patient.Location],'state');
% ans = 1×3 cell array
% {'VA'} {'NC'} {'CT'}
fun2 = @(s,field) [s.(field)]; % use [] for numbers
output = fun2([Patient.Vitals],'weight');
% ans = 185 203 190
And this even works in R2019b:
f1 = @(s,field) [s.(field)];
f2 = @(s,field,subfield) [f1(s,field).(subfield)];
output = f2(Patient,'Vitals','weight');
% ans = 185 203 190
But this essentially does the same thing as creating a temporary struct, [Patient.Vitals], and then indexing into that. It can just be neatly arranged into an anonymous function.
There is probably also a way to do this with subsref, but it would probably get complex.
  5 Kommentare
Guillaume
Guillaume am 19 Nov. 2019
If your xml schema chan be flattened into one or more table, I would consider using that. But indeed, matlab hasn't got an efficient way of storing xml (or json) data. You could use containers.Map but its implementation in matlab leaves a lot to be desired.
KAE
KAE am 19 Nov. 2019
Thanks. Perhaps there is a solution outside Matlab that I can call from within Matlab to access XML data. I will look around.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Guillaume
Guillaume am 18 Nov. 2019
This is one of the reason I dislike multilevel structures (the other being they're very inefficient memory-wise), there's no easy way to extract all the data from the leaves at once.
The best you can do is probably:
tempvitals = vertcat(Patient.Vitals); %concatenate all the Vitals fields. Note that they must all have the same fields themselves
Weight = vertcat(tempvitals.weight);

Kategorien

Mehr zu Structures finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by