How to use a filename character array as a name of a variable?

26 views (last 30 days)
I'm running a code in which I'm quantifying certain parameters in a file.
  • I have a character variable which is called filename, and contais the name of the file as described below.
  • I also have the results of the quantification in a matrix variable called Results
filename='3229_011_2.mat'
Results=[1;21;2441;141;1114;114;2241;44521;14241]
I saved Results variable with the filename as name of the file, so right now I have a file called 3229_011_2.mat that contains the variable Results.
I made the same quantification in around 100 images, so now I have 100 files with different filenames but the same variable Results in it.
My intention is to concatenate ALL the Results variables in one single matrix, to work in all of them at the same time.
However, I tried to open all the files in Matlab, but since they all have the same variable name, I can't open them all at the same time to concatenate the matrices. For this reason, I thought that it would be useful to change the name of the variable Results to the name of the filename for each file at the moment that I'm doing the quantification and saving the file. In this way, I could open all the files and concatenate them.
This would be my goal:
filename='whatever_1221.mat'
whatever_1221=[1;21;2441;141;1114;114;2241;44521;14241]
Any ideas about how to solve this, or alternative approaches that I can use?
Thanks.
  1 Comment
Stephen23
Stephen23 on 11 Feb 2022
Edited: Stephen23 on 11 Feb 2022
"However, I tried to open all the files in Matlab, but since they all have the same variable name, I can't open them all at the same time to concatenate the matrices."
Of course you can. Because you correctly designed your data and used exactly the same name in each .mat file you made this task very easy, you can just store the imported data in one container array, just like the MATLAB documentation shows:
You can simply and efficiently access all of the imported data using indexing.
"For this reason, I thought that it would be useful to change the name of the variable Results to the name of the filename for each file at the moment that I'm doing the quantification and saving the file."
No, naming variables dynamically should be avoided. Once you start dynamically naming variables like that you paint yourself into a corner and force yourself into writing slow, complex, inefficient code which is buggy and difficult to debug:
Dynamically naming variables like that is https://en.wikipedia.org/wiki/Anti-pattern

Sign in to comment.

Accepted Answer

David Hill
David Hill on 10 Feb 2022
Just use a loop.
newResults=[];
for k=1:100
r=load(strcat('whatever_',num2str(k)));
newResults=[newResults;r.Results];
end

More Answers (2)

AndresVar
AndresVar on 10 Feb 2022
Edited: AndresVar on 11 Feb 2022
You can use EVAL (see Stephen's comment to why this can cause error)
[~,varname]= fileparts(filename)
data = [....]; % your data
eval(sprintf('%s = data',varname);
OR an alternative to renaming the variables is that you can just load it under different names
data1 = load("file1.mat",'Results')
data2 = load("file2.mat",'Results') % then you have data2.Results and data1.Results
%% OR you can put it into a structure array.. you can make a loop
data(1) = load("file1.mat",'Results')
data(2) = load("file2.mat",'Results')
data(3) = load("file3.mat",'Results')
%% OR you if they are the same length you can just append it into a matrix
data = load("file1.mat",'Results')
for ...
data = [data load(iifile,'Results')]
end
  2 Comments
Stephen23
Stephen23 on 11 Feb 2022
Edited: Stephen23 on 11 Feb 2022
"You can use EVAL"
No, that code won't work.
Once again, using EVAL for such trivial code is a bad idea. Lets try it and see what happens:
% Create fake data:
Results = rand(2,3);
save('3229_011_2.mat','Results')
clearvars
% Import data:
S = load('3229_011_2.mat')
S = struct with fields:
Results: [2×3 double]
[~,varname]= fileparts('3229_011_2.mat') % can anyone see the problem yet?
varname = '3229_011_2'
data = S.Results;
eval(sprintf('%s = data',varname) % Oh no! Fragile, buggy, anti-pattern code!
Invalid expression. When calling a function or indexing a variable, use parentheses. Otherwise, check for mismatched delimiters.

Error in connector.internal.fevalMatlab

Error in connector.internal.fevalJSON
Question: are all valid filenames also valid MATLAB variable names? (hint: no)
Question: is code that magically names variables using filenames robust? (hint: no, it is fragile and buggy)
AndresVar
AndresVar on 11 Feb 2022
Yes I agree eval is bad, I just added that to answer the question.

Sign in to comment.


Stephen23
Stephen23 on 11 Feb 2022
Edited: Stephen23 on 11 Feb 2022
A very neat and simple approach is to import the data into the same structure that DIR returns:
P = 'absolute or relative path to where the files are saved';
S = dir(fullfile(P,'*.mat'));
for k = 1:numel(S)
F = fullfile(P,S(k.name));
D = load(F);
S(k).data = D.Results; % your well-designed .mat files make this easy!
end
All of the imported file data is in the structure S, for example the second file:
S(2).name % filename
S(2).data % the Results data
You can easily use a comma-separated list to concatenate all of the Results data into one matric, if so desired, depending on the orientation of the data in Results, something like one of these:
M = horzcat(S.data)
M = vertcat(S.data)

Community Treasure Hunt

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

Start Hunting!