Matlab save table with different file names in different files - matlab

I'm trying to read different files (txt) using a datastore and readtable in order to parse them and write them into a .mat file.
I'm using ds = datastore('*.txt').Files to get all the file names in a directory, then with a for loop I iterate through all the different files and I save them with different names.
However when I import the file in matlab they have all the same table name (dat).
Here's the code:
ds = datastore('*.txt');
fnames = ds.Files;
l = length(fnames);
for i = 1:l
dat = readtable(fnames{i}, 'Delimiter', '\t');
dat.Properties.VariableNames(1:2) = {'rpm', 'p_coll'};
dat = removevars(dat{i},20:width(dat));
save([fnames{i} '.mat'],'dat');
end
I tried using an array of dat but it didn't work. Any ideas?

As Sardar said there is no point in storing your data in L different variables. If you have to do so, there probably is a bigger problem in your program design. You'd better describe why you need that.
As an alternative, you can load those files in a single cell array:
L = 10;
for ii =1:L
dat = 2*ii;
fn = sprintf('dat%d.mat', ii);
save(fn, 'dat');
end
dats = cell(L, 1);
for ii=1:L
fn = sprintf('dat%d.mat', ii);
load(fn);
dats{ii} = dat;
end
Another option is to lad them in a struct:
dats = struct();
for ii=1:L
fn = sprintf('dat%d.mat', ii);
load(fn);
dats.(sprintf('dat%d', ii)) = dat;
end
I do not see any advantage in this method compared to cell array, but it's kind of funny.
Finally, if you really have a reason to store data in multiple variables, you can use eval:
for ii =1:L
dat = ii^2;
eval(sprintf('dat%d=dat;', ii));
fn = sprintf('dat%d.mat', ii);
save(fn, sprintf('dat%d', ii));
end
for ii=1:L
fn = sprintf('dat%d.mat', ii);
load(fn);
end

Related

Matlab: function on multiple files

I want to read all wav files containing in a folder, for each file I perform a function.
The result of this function is a number. I want save several results in a file txt.
This is my code:
dirMask = 'folder\*.wav';
wavRoot = fileparts(dirMask);
Files=dir(dirMask);
x = [];
for k=1:length(Files)
FileNames = fullfile(wavRoot, Files(k).name)
nomi=FileNames;
[s,fs] = audioread(FileNames);
a = function(s, fs);
x=a;
end
fid = fopen('file.txt','wt');
fprintf(fid,'%f\n',x);
fclose(fid);
This code doesn't work. How can I do this?
I rearranged things a bit. I wasn't entirely positive of the original intent but I think this is what you were trying to achieve:
dirMask = 'folder\*.wav';
Files = dir(dirMask);
fid = fopen('file.txt','wt');
for k=1:length(Files)
FileName = [ Files(k).folder '\' Files(k).name ]
[s,fs] = audioread(FileName);
% functions named function is a bad idea as it is keyword protected
x = myFunction(s,fs);
fprintf(fid,'%f\n',x);
end
fclose(fid);

Matlab : How to open several .txt files using their names for variable names

I have several .txt files of 2 columns, that I’d like to import and use the second column for subsequent operations. My text files are name as: profileA1.txt, profileA2.txt, etc… and my variables corresponding to the data of the second column are named in the subsequent code are A1, A2, A3, etc…
The code works but currently I have to open manually each .txt file with the Import data wizard, change the name of the second column and click on the import the selection. I tried to write a code (see below) to automatize these steps but it doesn’t work? Anyone has any idea to fix this code?
Thanks
for k = 1:5
myfilename = sprintf('profileA%d.txt', k);
mydata = importdata(myfilename);
Aloop = ['A' num2str(k)];
A{k} = load(myfilename.data(:,2), k);
end
You're example is a little off because you convert myfilename from a character array to a structure magically. I would approach this by reading the entire text file into a cell array of characters then using cellfun and textscan to read in the columns. Like this:
function C = ReadTextFile(infile)
if (exist(infile, 'file') ~= 2)
error('ReadTextFile:INFILE','Unknown file: %s.\n', infile);
end
fid = fopen(infile, 'r');
C = textscan(fid, '%s', 'delimiter','\n');
C = C{1};
fclose(fid);
end
% assign an output file
outFile = 'SomeRandomFile.mat';
for k = 1:5
C = ReadTextFile(sprintf(‘profileA%d.txt’, k));
val = cell2mat(cellfun(#(x) textscan(x, '%*f %f','CollectOutput',1),C));
varName = sprintf('A%d', k);
assignin('base', varName, val);
save(outFile, varName, '-append')
end
You can skip the whole reading as a character array first but I have that function already so I just reused it.

Save a sparse array in csv

I have a huge sparse matrix a and I want to save it in a .csv. I can not call full(a) because I do not have enough ram memory. So, calling dlmwrite with full(a) argument is not possible. We must note that dlmwrite is not working with sparse formatted matrices.
The .csv format is depicted below. Note that the first row and column with the characters should be included in the .csv file. The semicolon in the (0,0) position of the .csv file is necessary too.
;A;B;C;D;E
A;0;1.5;0;1;0
B;2;0;0;0;0
C;0;0;1;0;0
D;0;2.1;0;1;0
E;0;0;0;0;0
Could you please help me to tackle this problem and finally save the sparse matrix in the desired form?
You can use csvwrite function:
csvwrite('matrix.csv',a)
You could do this iteratively, as follows:
A = sprand(20,30000,.1);
delimiter = ';';
filename = 'filecontaininghugematrix.csv';
dims = size(A);
N = max(dims);
% create names first
idx = 1:26;
alphabet = dec2base(9+idx,36);
n = ceil(log(N)/log(26));
q = 26.^(1:n);
names = cell(sum(q),1);
p = 0;
for ii = 1:n
temp = repmat({idx},ii,1);
names(p+(1:q(ii))) = num2cell(alphabet(fliplr(combvec(temp{:})')),2);
p = p + q(ii);
end
names(N+1:end) = [];
% formats for writing
headStr = repmat(['%s' delimiter],1,dims(2));
headStr = [delimiter headStr(1:end-1) '\n'];
lineStr = repmat(['%f' delimiter],1,dims(2));
lineStr = ['%s' delimiter lineStr(1:end-1) '\n'];
fid = fopen(filename,'w');
% write header
header = names(1:dims(2));
fprintf(fid,headStr,header{:});
% write matrix rows
for ii = 1:dims(1)
row = full(A(ii,:));
fprintf(fid, lineStr, names{ii}, row);
end
fclose(fid);
The names cell array is quite memory demanding for this example. I have no time to fix that now, so think about this part yourself if it is really a problem ;) Hint: just write the header element wise, first A;, then B; and so on. For the rows, you can create a function that maps the index ii to the desired character, in which case the complete first part is not necessary.

Matlab Input/output of Several Files

I do matlab operation with two data file whose entries are complex numbers. For example,
fName = '1corr.txt';
f = dlmread('1EA.txt',',');
fid = fopen(fName);
tline = '';
Then I do matrix and other operations between these two files and write my output which I call 'modTrace' as:
modTrace
fileID = fopen('1out.txt','w');
v = [(0:(numel(modTrace)-1)).' real(modTrace(:)) ].';
fprintf(fileID,'%d %e\n',v);
The question is, if I have for example 100 pairs of such data files, like (2corr.txt, 2EA.txt), ....(50corr.txt, 50EA.txt) how can I generalize the input files and how to write all the output files at a time?
First of all, use sprintf to get your variable names depending on the current index.
corrName=sprintf('%dcorr.txt',idx);
EAName=sprintf('%dEA.txt',idx);
outName=sprintf('%dout.txt',idx);
This way, you have one variable (idx) which has to be changed.
Finally put everything into a loop:
n=100
for idx=1:n
corrName=sprintf('%dcorr.txt',idx);
EAName=sprintf('%dEA.txt',idx);
outName=sprintf('%dout.txt',idx);
f = dlmread(EAName,',');
fid = fopen(corrName);
tline = '';
modTrace
fileID = fopen(outName,'w');
v = [(0:(numel(modTrace)-1)).' real(modTrace(:)) ].';
fprintf(fileID,'%d %e\n',v);
end
Instead of hardcoding the number 100, you could also use n=numel(dir('*EA.txt')). It count's the files ending with EA.txt

Loading multiple datasets without overwriting variable

I have a folder containing a number of files, named:
filename_1.mat
filename_2.mat
.
.
.
filename_n.mat
Each file contains a dataset named Var, with identical columns. I want to load all these datasets into the workspace and use vertcat() to vertically concatenate them, but when I load them in a for loop I only get the last dataset since the variable Var is overwritten. These datasets were created in a for loop:
% generate filenames
tss = arrayfun(#(x){sprintf('filename_%d',x)},1:(length(1:3)))';
namerr = cell((length(1:3)),1);
namerr(:,1) = {'E:\FILES\'};
file_names = strcat(namerr,tss,'.mat');
% create datasets and save them to E:\FILES
for ii = 1:3
a = rand(1,5)';
b = rand(1,5)';
Var = dataset({[a,b],'a_name','b_name'});
save(file_names{(ii)},'Var','-v6')
end
% Now read these datasets into workspace and concatenate vertically??
% Is there a way for me to name the datasets `Var_1...Var_n`
% so they are not overwritten?
Sure. You can load the data into a variable, and then access the contents of a file as fields in the variable. Starting with your example, this would look something like this:
loadedData_1 = load(file_names{1})
loadedData_2 = load(file_names{2})
loadedData_3 = load(file_names{3})
mergedData = [...
loadedData_1.Var; ...
loadedData_2.Var; ...
loadedData_3.Var ];
You can clean this up by using a loop:
for ix = 3:-1:1 %Load all data, backwards to force preallocation
loadedData(ix) = load(file_names{ix});
end
mergedData = cat(1,loadedData.Var);
Or if you really want to go over the top I think you can do it in one long line using arrayfun, but that's probably going over the top.
It would be far easier to just do it directly in the loop:
...
Varcat = [];
for ii = 1:3
a = rand(1,5)';
b = rand(1,5)';
Var = dataset({[a,b],'a_name','b_name'});
Varcat = [Varcat; Var];
save(file_names{(ii)},'Var','-v6')
end
Var = Varcat;
In case you actually want to do it much later or in another part of the program, hopefully it's clear how to adapt the same approach for a similar loop with load().