- Clearing variables on each loop iteration serves no purpose.
- Using numel rather than length is a good habit to learn.
- It is easy and advisable to check if fopen succeeded.
- textscan returns a cell array of the columns, so why not just use cell2table to get a table?
- Why not just use readtable to import the file directly into a table?
- Dynamically accessing variable names, as you are requesting is not recommended- It is much simpler and more efficient to use a cell array and indexing. Read this to know more:
Table name from input to loop
6 views (last 30 days)
Show older comments
Jesper Kamp Jensen
on 29 Jun 2018
Commented: Jesper Kamp Jensen
on 29 Jun 2018
Hi,
I'm loading data from different files in a loop. I want to create a table for each individual data file.
datafiles=recursivedir('PATH','*.txt');
for o = 1:length(datafiles)
%extract date and time from filename
[versn, name, ext] = fileparts(datafiles{o});
filename=datafiles{o};
fileID = fopen(filename,'r');
dataArray = textscan(fileID, formatSpec, 'Delimiter', delimiter, 'MultipleDelimsAsOne', true, 'TextType', 'string', 'ReturnOnError', false);
fclose(fileID);
T_'name' = table(dataArray{1:end-1}, 'VariableNames', {'Output','Date','Time'});
% I want to create a new table for each loop with the name set from the fileparts.
% Clear temporary variables
clearvars filename delimiter formatSpec fileID dataArray ans;
end
I want to create a table for each loop that has the name like T_test1 and from the fileparts name(1) = 'test1' How do I do this, so I get a table for each loop?
Best regards, Jesper
6 Comments
Stephen23
on 29 Jun 2018
Edited: Stephen23
on 29 Jun 2018
"but hoped there was a way to incorporate the filenames more easily."
Arrays are the easy way! What you are trying do to is the opposite of easy.
By far the easiest way is to put the filenames into an array, which is what my answer does. Note that meta-data (e.g. filenames) is also data, and so it should definitely not be stored in variable names, because putting (meta-)data into variable names makes it harder to access, and makes your code slow, complex, and more liable to bugs. Read this to know more:
In my answer the filenames are stored in the struct array S, whose contents correspond exactly with the imported data in cell array T, i.e.
S(1).name <-> T{1}
S(2).name <-> T{2}
S(3).name <-> T{3}
... etc
Accessing either/both of these is clearly trivial and simple using indexing. So all of the filenames are there for you, waiting for you to extract whatever information you want from them. You can even use some handy syntaxes for dealing with that non-scalar structure, e.g. to put them all into one cell array:
{S.name}
which you could then use with strcmp, regexp, etc., e.g. to identify filenames starting with 'BMW':
idx = strncmp({S.name},'BMW',3)
Note how simply I can access and process all of the names at once!
If you want all of the data to be collected into one variable then you could even put the tables into the structure:
for k = ...
...
S(k).table = cell2table(...)
end
and then all of the filenames and imported data are in the same structure, and are trivial to access.
Accepted Answer
Stephen23
on 29 Jun 2018
Edited: Stephen23
on 29 Jun 2018
Rather than magically defning variable names it is much simpler to use basic MATLAB indexing and a cell array T:
D = 'Path';
S = dir(fullfile(D,'*.txt'));
T = cell(1,numel(S));
for k = 1:numel(S)
[fid,msg] = fopen(fullfile(D,S(k).name));
assert(fid>=3,msg)
C = textscan(fid,...);
fclose(fid);
T{k} = cell2table(C,...);
end
0 Comments
More Answers (0)
See Also
Categories
Find more on Numeric Types 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!