Save and load variables of different samples
Show older comments
I do experiments with different samples (let's say 10 different materials). After measuring all samples seperatly, I apply a Matlab Code(the same code for all samples) to the data of each sample. The code does some calculations and in the end I have some variables. These variables I would like to load into another Matlab Code which is suppose to plot some of the variables (e.g. comparison plot for different samples, etc.)
Now the question: How can I save and load the variables in a way to access the variables of different samples (e.g. plot variable 1 of sample 1 with variable 1 of sample 2)?
My idea was to add all the variables to a structure named after the sample and save the structure (e.g water.density, water.color, etc. and then save('filename.mat','-struct','water') ). But the problem is that I am not able to name the structure efficiently (I need to change the code every time). Is there a better approach for this problem?
11 Comments
Stephen23
on 13 Apr 2021
"But the problem is that I am not able to name the structure efficiently (I need to change the code every time). Is there a better approach for this problem?"
Yes: do not force meta-data (e.g. sample numbers, parameter values, etc) into variable names. Meta-data is data, and data should be stored in variables. Once you do that, then you can easily loop over your saved files and process them.
Marcel345614
on 13 Apr 2021
Edited: Marcel345614
on 13 Apr 2021
"This means, I should include the sample name in the first field of the structure (e.g. structure.name, structure.variable1, etc.)? Then I save this structure in the first code."
I don't understand how "first" relates to anything, but yes, in general you should save any meta-data together with all of the other data for that sample/test, e.g.:
P = 'absolute or relative path to where the files are saved';
S.density = 2.3
S.color = [255,192,203];
S.name = 'water';
F = sprintf('myfile_%03d.mat',k);
save(fullfile(P,F),'-struct','S')
"How can I proceed in the second code after I have load all the structures (now all named 'structure')?"
If all of the mat files contain exactly the same variable names (which they should) then this is easy:
For example, something like this:
S = dir(fullfile(P,'*.mat'));
for k = 1:numel(S)
F = fullfile(P,S(k).name);
S(k).data = load(F);
end
A = [S.data]; % 1xN structure of all file data
You can trivially access the content of the structure array A, for example:
A(1).color
A(1).name
A(3).density
Marcel345614
on 13 Apr 2021
Marcel345614
on 13 Apr 2021
"Do I need to "remember" which index number belongs to which sample? Suppose I want to plot density of water and density of milk in one plot, I need to remember that water was index k=3 and milk was k=5? "
It would be more reliable to use the (meta-)data that you have saved in the file. For example:
X = strcmpi('water',{A.name});
A(X).color
A(X).density
and the same for 'milk'.
"I need to call A(1).S.name instead of A(1).name... "
Yes, we need to use the syntax that saves the structure as separate variables. The correct syntax for saving is:
save(fullfile(P,F),'-struct','S')
% ^^^^^^^^^ you need this!
Marcel345614
on 13 Apr 2021
Edited: Marcel345614
on 13 Apr 2021
Stephen23
on 13 Apr 2021
"I would like to access the conductivity of 'milk 0g/l' in a easy way and plot it. This is is easy as long as I have the same samples. But suppose I measure the next week apple juice for different salt concentration."
Sure, just store all meta-data as data in their own right, which will make processing your data much easier.
"Now all the index numbers are shifted and it would be very time consumming to change the code to again simply plot the conductivity of 'milk 0g/l'."
"Very time consuming" is exactly what I am trying to help you to avoid.
Keep your name data and concentration data separate (names should be character/categorical, concentration should be numeric, etc). Then you can perform simple loops, generate permutations, match data in vectors (i.e. get indices), or however you want to pick the samples and groups that you want, e.g.
and if you used a table:
"Is there an easier solution for this?"
Probably you should be using a table, which is specifically designed for working with groups within sets of data:
Marcel345614
on 13 Apr 2021
Edited: Marcel345614
on 13 Apr 2021
Marcel345614
on 14 Apr 2021
Stephen23
on 14 Apr 2021
"Is this the most elegant way"
It looks like a good start to me. The real questions are:
- does it do what you want?
- is it easy for you to understand and maintain?
As mentioned in a previous comment, and for the reasons explained in more detail here
it would be best to not put lots of (particularly numeric) meta-data together into one string. You will regret that later.
"But how can I plot the same thing in the case I do not now which index belongs to the sample 'milk 10g/l' or in the case in which I add samples to the structure A again and again and the indices are thus shiftet each time (and I would need to change the number in the plot command each time)?. How can I easily do this without writing a lot of code(In the real experiment I have a lot of samples and want to plot way more than simply the conductivity for one sample)?"
Take a deep breath. Let the code do these things for you. Do not write lots of code (that is what loops are for).
In essence, everything boils down to indexing.
So you want to plot milk vs coffee: then use strcmp (or whatever) to get the indices of those names. And then loop over all concentrations (stored as numeric, of course) and plot each pair of corresponding data sets. Make sure your code can cope with exceptions (missing pairs, no matches, etc). How you define those combinations and sets of data is up to you: e.g. if you want to do the same for milk vs a whole set of other things (coffee, agave syrup, diesel) then loop over those names. Or perhaps use ndgrid to generate all combinations.
Use indexing to select the relevant data, plot, and save (you will find sprintf and fullfile useful). Done.
Answers (1)
Xingwang Yong
on 13 Apr 2021
You could try cell(). You do not have to save the variable names.
c = cell(1,1); % each col contains variables of a sample, each row is a variable in diffent samples
c{1,1}='water';
c{1,2}='oil';
c{1,3}='salt';
for k = 1:numSamples
c{end+1,k} = var1;
c{end+1,k} = var2;
end
2 Comments
Marcel345614
on 13 Apr 2021
Xingwang Yong
on 13 Apr 2021
You can save the cell array then. The key idea here is that you can use index of cell, i.e. c{1,1}, to get variables instead of structure.filed. So you can get rid of the name of samples.
Categories
Find more on Variables 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!