Outputing cell array to CSV file ( MATLAB ) - matlab

I've created a m x n cell array using cell(m,n), and filled each of the cells with arbitrary strings.
How do I output the cell array as a CSV file, where each cell in the array is a cell in the CSV 'spreadsheet'.
I've tried using cell2CSV, but I get errors ...
Error in ==> cell2csv at 71
fprintf(datei, '%s', var);
Caused by:
Error using ==> dlmwrite at 114
The input cell array cannot be converted to a matrix.
Any guidance will be well received :)

Here is a somewhat vectorized solution:
%# lets create a cellarray filled with random strings
C = cell(10,5);
chars = char(97:122);
for i=1:numel(C)
C{i} = chars(ceil(numel(chars).*rand(1,randi(10))));
end
%# build cellarray of lines, values are comma-separated
[m n] = size(C);
CC = cell(m,n+n-1);
CC(:,1:2:end) = C;
CC(:,2:2:end,:) = {','};
CC = arrayfun(#(i) [CC{i,:}], 1:m, 'UniformOutput',false)'; %'
%# write lines to file
fid = fopen('output.csv','wt');
fprintf(fid, '%s\n',CC{:});
fclose(fid);
The strings:
C =
'rdkhshx' 'egxpnpvnfl' 'qnwcxcndo' 'gubkafae' 'yvsejeaisq'
'kmsvpoils' 'zqssj' 't' 'ge' 'lhntto'
'sarlldvig' 'oeoslv' 'xznhcnptc' 'px' 'qdnjcdfr'
'jook' 'jlkutlsy' 'neyplyr' 'fmjngbleay' 'sganh'
'nrys' 'sckplbfv' 'vnorj' 'ztars' 'xkarvzblpr'
'vdbce' 'w' 'pwk' 'ofufjxw' 'qsjpdbzh'
'haoc' 'r' 'lh' 'ipxxp' 'zefiyk'
'qw' 'fodrpb' 'vkkjd' 'wlxa' 'dkj'
'ozonilmbxb' 'd' 'clg' 'seieik' 'lc'
'vkpvx' 'l' 'ldm' 'bohgge' 'aouglob'
The resulting CSV file:
rdkhshx,egxpnpvnfl,qnwcxcndo,gubkafae,yvsejeaisq
kmsvpoils,zqssj,t,ge,lhntto
sarlldvig,oeoslv,xznhcnptc,px,qdnjcdfr
jook,jlkutlsy,neyplyr,fmjngbleay,sganh
nrys,sckplbfv,vnorj,ztars,xkarvzblpr
vdbce,w,pwk,ofufjxw,qsjpdbzh
haoc,r,lh,ipxxp,zefiyk
qw,fodrpb,vkkjd,wlxa,dkj
ozonilmbxb,d,clg,seieik,lc
vkpvx,l,ldm,bohgge,aouglob

Last commment was written in "pure" C. So It doesnt work in Matlab.
Here it is the right solution.
function [ ] = writecellmatrixtocsvfile( filename, matrix )
%WRITECELLMATRIXTOCSVFILE Summary of this function goes here
% Detailed explanation goes here
fid = fopen(filename,'w');
for i = 1:size(matrix,1)
for j = 1:size(matrix,2)
fprintf(fid,'%s',matrix{i,j});
if j~=size(matrix,2)
fprintf(fid,'%s',',');
else
fprintf(fid,'\n');
end
end
end
fclose(fid);
end

easy enough to write your own csv writer.
-- edited to reflect comments --
fid = fopen('myfilename.csv','w');
for i = 1:size(A,1)
for j = 1:size(A,2)
fprintf(fid,'%s',A{i,j});
if(j!=size(A,2)
fprintf(fid,',',A{i,j})
else
fprintf(fid,'\n')
end
end
end
fclose(fid);

Related

Matlab: func2str from a function in a m-file

In a main m-file I have
conformal = maketform('custom', 2, 2, [], #conformalInverse_0001, []);
used in imtransform that refers to the function defined in conformalInverse_0001.m:
function U = conformalInverse_0001(X, ~)
%#codegen
U = [zeros(size(X))];
Z = complex(X(:,1),X(:,2));
W = 1./(4.*Z.^2-1);
U(:,2) = imag(W);
U(:,1) = real(W);
How can I get the string '1./(4.*Z.^2-1)' in the main program?
I found a way to solve it, but it's not so elegant...
Assume conformalInverse_0001.m is a file in your folder.
You can parse the file as a text file, and search for your formula.
Example:
Assume you know the location is 5'th line in file, and start with W =.
You can use something like the following code to read '1./(4.*Z.^2-1)' in the main program:
%Open file for reading.
fid = fopen('conformalInverse_0001.m', 'r');
%Read 5 lines.
s = textscan(fid, '%s', 5, 'delimiter', '\n');
fclose(fid);
%Get the 5'th line.
s = s{1}(5);
%Convert cell array to string.
s = s{1};
%Get characters from the 5'th character to one char before end of string.
s = s(5:end-1)
Result: s = 1./(4.*Z.^2-1)
You can check textscan documentation for finding more elegant solution.
I'm not sure I fully understand the problem here, but what about adding into your conformalInverse_0001 function something like:
str = '1./(4.*Z.^2-1)';
save('temp_str','str') % or whatever data that you want to save from it
and then adding in your main file:
load('str.mat')% or you can use 'impordata'
where you want to extract it.
I have hacked two solutions with textscan: first knowing the line number and second searching the line that starts with substring 'W = '
% read line line_num = 5 and process string
f_id = fopen(conformalInverse_m_path);
conformalInverse_cell = textscan(f_id,'%s','delimiter','\n'); %disp(conformalInverse_cell); % {68×1 cell}
func_string = conformalInverse_cell{1}{line_num}; disp(func_string); % W = 1./(4.*Z.^2-1); OK
func_string_2=func_string(5:end-1); disp(func_string_2); % 1./(4.*Z.^2-1); OK
% read first line that starts with substring 'W = ' and process string
W_string = 'W = ';
for i=1:100
func_string = conformalInverse_cell{1}{i};
Firt4=func_string(1:4); %disp(['i = ', num2str(i), ': First4 = ', Firt4]);
if strcmp(Firt4,W_string) == 1; line_nr = i; break; end;
end
func_string_2 = conformalInverse_cell{1}{line_nr};
func_string_3=func_string_2(5:end-1);

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.

Matlab - string containing a number and equal sign

I have a data file that contains parameter names and values with an equal sign in between them. It's like this:
A = 1234
B = 1353.335
C =
D = 1
There is always one space before and after the equal sign. The problem is some variables don't have values assigned to them like "C" above and I need to weed them out.
I want to read the data file (text) into a cell and just remove the lines with those invalid statements or just create a new data file without them.
Whichever is easier, but I will eventually read the file into a cell with textscan command.
The values (numbers) will be treated as double precision.
Please, help.
Thank you,
Eric
Try this:
fid = fopen('file.txt'); %// open file
x = textscan(fid, '%s', 'delimiter', '\n'); %// or '\r'. Read each line into a cell
fclose(fid); %// close file
x = x{1}; %// each cell of x contains a line of the file
ind = ~cellfun(#isempty, regexp(x, '=\s[\d\.]+$')); %// desired lines: space, numbers, end
x = x(ind); %// keep only those lines
If you just want to get the variables, and reject lines that do not have any character, this might work (the data.txt is just a txt generated by the example of data you have given):
fid = fopen('data.txt');
tline = fgets(fid);
while ischar(tline)
tmp = cell2mat(regexp(tline,'\=(.*)','match'));
b=str2double(tmp(2:end));
if ~isnan(b)
disp(b)
end
tline = fgets(fid);
end
fclose(fid);
I am reading the txt file line by line, and using general expressions to get rid of useless chars, and then converting to double the value read.

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.

How to convert Matlab variables to .dat (text) file with headers

EDITED QUESTION:
I have 2500 rows x 100 columns data in variable named avg_data_models. I also have 2500 rows x 100 columns variable 'X' and similar size matrix variable 'Y', both containing the co-ordinates. I want to save the values of this variable in a text (.dat) file which must have 302 header lines in the following manner:
avg_data_models
300
X_1
X_2
.
.
.
X_100
Y_1
Y_2
.
.
.
Y_100
avg_data_models_1
avg_data_models_2
avg_data_models_3
.
.
.
.
.
avg_data_models_100
In the above header style, the first line is the name of the file, the 2nd line tells the number of columns (each column has 2500 rows), and the rest of the 300 lines represent the model of each variable respectively - Like 100 models of X, 100 models of Y and 100 models of avg_data_models.
Consider this code:
%# here you have your data X/Y/..
%#X = rand(2500,100);
[r c] = size(X);
prefixX = 'X';
prefixY = 'Y';
prefixData = 'avg_data_models';
%# build a cell array that contains all the header lines
num = strtrim( cellstr(num2str((1:c)','_%d')) ); %#' SO fix
headers = [ prefixData ;
num2str(3*c) ;
strcat(prefixX,num) ;
strcat(prefixY,num) ;
strcat(prefixData,num) ];
%# write to file
fid = fopen('outputFile.dat', 'wt');
fprintf(fid, '%s\n',headers{:});
fclose(fid);
EDIT
It seems I misunderstood the question.. Here's the code to write the actual data (not the header titles!):
%# here you have your data X/Y/..
avg_data_models = rand(2500,100);
X = rand(2500,100);
Y = rand(2500,100);
%# create file, and write the title and number of columns
fid = fopen('outputFile.dat', 'wt');
fprintf(fid, '%s\n%d\n', 'avg_data_models', 3*size(X,2));
fclose(fid);
%# append rest of data
dlmwrite('outputFile.dat', [X Y avg_data_models], '-append', 'delimiter',',')
Note: I used a comma , as delimiter, you can change it to be a space or a tab \t if you like..
You can use fprintf to write the header, like so:
%# define the number of data
nModels = 100;
dataName = 'avg_data_models';
%# open the file
fid = fopen('output.dat','w');
%# start writing. First line: title
fprintf(fid,'%s\n',dataName); %# don't forget \n for newline. Use \n\r if yow want to open this in notepad
%# write number of models
fprintf(fid,'%i\n',nModels)
%# loop to write the rest of the header
for iModel = 1:nModels
fprintf(fid,'%s_%i\n',dataName,iModel);
end
%# use your favorite method to write the rest of the data.
%# for example, you could use fprintf again, using /t to add tabs
%# create format-string
%# check the help to fprintf to learn about formatting details
formatString = repmat('%f\t',1,100);
formatString = [formatString(1:end-1),'n']; %# replace last tab with newline
%# transpose the array, because fprintf reshapes the array to a vector and
%# 'fills' the format-strings sequentially until it runs out of data
fprintf(fid,formatString,avg_data'); %'# SO formatting
%# close the file
fclose(fid);