Dynamically calling variables (it's not what this sounds like!)
Show older comments
Hi everyone,
I have five files that have almost the same name except for one term that is added in the end, like "filename_A", "filename_B" etc., and the columns in these files are almost the same up to that last term as well, e.g.
filename_A: column1_A column2_A column3_A ...
filename_B: column1_B column2_B column3_B ...
I would like to loop through the different files and the different columns, but I cannot figure out how to dynamically bring up the names in the loop with sprintf or similar functions. I know people strongly advise against dynamically creating variables. But is that also the case for calling them?
I suppose an alternative would be to have created my files/named the columns in a better way, but I don't know how. Any help is greatly appreciated because I run into this problem all the time with the way my data is structured!
5 Comments
Mathieu NOE
on 9 Nov 2021
hello
you can do a loop - like example below and then store the results as structures - which is better coding practice
here we loop excel filters but of course adapt it to your data file extension
so the first code is a demo about looping in the directory
fileDir = pwd;
fileNames = dir(fullfile(fileDir,'data*.xlsx')); % get list of data files in directory
fileNames_sorted = natsortfiles({fileNames.name}); % sort file names into natural order
%(https://fr.mathworks.com/matlabcentral/fileexchange/47434-natural-order-filename-sort)
M= length (fileNames_sorted);
out_data = [];
for f = 1:M
% option # 1 for numeric data only using importdata
raw = importdata( fullfile(fileDir, fileNames_sorted{f}));
% create structure
S{f}.filename = fileNames_sorted{f};
S{f}.data = raw; % or column1_A / column2_A etc...
end
the second code is a description about different ways of assigning data to variables
combining both codes should give you the answer to your problem
a=readcell('test.txt',"Delimiter",":");
% option 1 : create a structure :
for ci = 1:size(a,1)
Varnames{ci} = matlab.lang.makeValidName(a{ci,1});
myStruct.(Varnames{ci}) = a{ci,2};
end
% option 2 using assignin (in function variableCreator) :
for ci = 1:size(a,1)
% change blanks in variable names to underscore (otherwise
% variableCreator will throw an error mesage
str = strrep(a{ci,1}, ' ', '_');
val = a{ci,2};
if ischar(val)
disp(['error : non numeric data in line : ' int2str(ci)]);
val = NaN;
end
variableCreator ( str, val )
end
clear str val a ci
% option 3 creating a table - one line engine !
T = array2table(a)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function variableCreator ( newVar, variable )
assignin ( 'caller', newVar, variable );
end
@Mathieu NOE: note that NATSORTFILES accepts the DIR structure directly, so you can simplify the code to:
S = dir(fullfile(..));
S = natsortfiles(S); % no need to extract the name field here!
And then within the loop simply use the same structure to save the imported file data, rather than creating a new cell array:
for k = ..
S(k).data = ..
end
Mathieu NOE
on 9 Nov 2021
RP
on 10 Nov 2021
Mathieu NOE
on 10 Nov 2021
yes sure - there are many ways to tackle each specific problem and it's completely normal that you chose the one that matches best your application
... myself I learn a lot from other's answers and that's the positive aspect of this forum. There's always something new to (re) discover and I do also keep interesting answers in my PC for future use
all the best
Accepted Answer
More Answers (0)
Categories
Find more on Workspace Variables and MAT Files 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!