Accessing field data in nonscalar structure array

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.]

 채택된 답변

Daniel M
Daniel M 2019년 11월 18일
편집: Daniel M 2019년 11월 18일
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

KAE
KAE 2019년 11월 18일
편집: KAE 2019년 11월 18일
I have R2019b so can use the 2nd version. I actually have 4 nested levels in my real structure array so will expand these anonymous functions.
Daniel M
Daniel M 2019년 11월 18일
I would just reconsider how you are organizing your data. Good luck!
KAE
KAE 2019년 11월 19일
The problem comes from working with semi-structured XML files which contain data at multiple levels, and if you get rid of that structure you lose information. Plus the size of information in the same field across different records may vary (e.g. if it contains the output of an error message). Not sure Matlab has a intiuitive solution for handling this kind of information: the best I found in xml2struct which results in the nested structures.
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 2019년 11월 19일
Thanks. Perhaps there is a solution outside Matlab that I can call from within Matlab to access XML data. I will look around.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Guillaume
Guillaume 2019년 11월 18일
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);

카테고리

도움말 센터File Exchange에서 Structures에 대해 자세히 알아보기

질문:

KAE
2019년 11월 18일

댓글:

KAE
2019년 11월 19일

Community Treasure Hunt

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

Start Hunting!

Translated by