Clear Filters
Clear Filters

Reference .mat variable name after loading

3 views (last 30 days)
I am trying to perform operations on a number of .mat files in a loop. The problem is that some of the loaded files do not come in with the variable name "maxtees". For example, some will be named "maxtees2000". Thus, I can not perform function that references "maxtees" (e.g., rows(maxtees)) when this isn't the appropriate variable name. Is there a way I can pull or reference these variables without having to re-save them all or set up different loops for different naming conventions? Thanks.
files = dir(['max*' '*.mat'])
maxT = [];
for i = 1:length(files)
load(files(i,1).name)
maxtees = maxtees(find(all(maxtees,2)),:);
maxtees = [gridNos maxtees(:,4) maxtees(:,5) maxtees(:,6) maxtees(:,9) maxtees(:,10)];
maxT = [maxT;maxtees];
end

Accepted Answer

Stephen23
Stephen23 on 24 Feb 2017
Edited: Stephen23 on 24 Feb 2017
Never load into the workspace directly, always load into a structure. Then your task is also much simpler, because it is easy to test for the existence of fields in that structure.
Here is a simple example, with variables named A and A100 in several mat files:
>> A = 0:3;
>> save('temp1.mat','A');
>> A = 4:6;
>> save('temp2.mat','A');
>> A100 = 7:9;
>> save('temp3.mat','A100');
Now clear the data and read those mat files back into MATLAB:
>> clear
>> D = dir('*.mat');
>> for k = 1:numel(D)
S = load(D(k).name);
F = fieldnames(S);
idx = strncmpi(F,'A',1); % you need to choose the best way to identify the variables.
vec = S.(F{idx}) % here is the data!
end
vec =
0 1 2 3
vec =
4 5 6
vec =
7 8 9
The best solution is to use exactly the same name in all of the mat files, because different variable names implies that you are storing meta-data in the variable name, which is not a good practice. Meta-data should be stored just like any other data, and not put into variable names. Read this for a more detailed explanation:
Also avoid "solutions" that use eval: using eval is a bad practice that removes all code helper tools and the JIT engine speed improvements (i.e. is not how you should be practicing writing code):
  4 Comments
Steven Ramsey
Steven Ramsey on 25 Feb 2017
Is it necessary there to use the idx component? Say if for some reason you had included
B = 10:12;
save('temp4.mat','B');
then idx = 0 and you hit an error, right? It seems the rest of what you provided is exactly what I needed: a method to use a file regardless of the name (fieldname? I'm still pretty ignorant on the terminology). And I agree on using the same variable name, I've since corrected that (another result of my current state of ignorance).
Thanks for your help!
Stephen23
Stephen23 on 26 Feb 2017
Edited: Stephen23 on 26 Feb 2017
@Steven Ramsey: personally I would define the idx explicitly, because:
  • it is a specific operation ("identify field names") that deserves its own line/s, which can then be clearly commented and explained, e.g.: "identify the required structure field"
  • this line generates its own variable whose value can be observed in the debugger, thus helping us to answer "did the code really do what we expected"?
  • you can comment it out and try alternative lines.
  • idx is its own variable which can be used elsewhere too, e.g. you could easily check the number of matches:
assert(nnz(idx)==1,'Too many or no matching variables found in %s',S(k).name)
If all of your files are guaranteed to have exactly the same fieldnames in that that structure (i.e. have the same variables saved in the mat file), then you could skip the step with matching fieldnames:
for k = 1:numel(D)
S = load(D(k).name);
vec = S.fieldname % here is the data!
end
It might look similar, but this is still preferable to load-ing straight into the workspace.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!