Write multiple .csv files - matlab

I have a cell array in Matlab (1x149): each cell containing data from a separate .txt file. I used the following code to load the .txt files
d = dir('*.txt');
nfiles = length(d);
data = cell(1, nfiles);
for k = 1:nfiles
data{k} = importdata(d(k).name);
end
Columns 1 through 5
[39676x182 double] [39676x182 double] [39676x182 double] [39676x182 double] [39676x182 double]
I want to write individual .csv files for each cell.
I tried using csvwrite, but it gives a large file which I can't really work with. I am trying to write a for loop to write each cell to a separate CSV file

I have just tried this and generated some random numbers which fit your problem.
test = mat2cell(randi(50,39676*5,182),[39676,39676,39676,39676,39676],182);
test = test';
Gives me:
test =
[39676x182 double] [39676x182 double] [39676x182 double] [39676x182 double] [39676x182 double]
Looping through this with:
for i = 1:5
csvwrite(strcat('file',num2str(i),'.csv'),test{1,i})
end
Results in five *.csv Files (file1.csv, file2.csv, ...). Using strcat to get file name could be solved better, but i dont know how.

Related

Cell of matrices to csv matlab

I have a problem converting my results to a csv file.
My cell is like this:
[1403x36 double] [1290x36 double] [1813x36 double] [1363x36 double] [1286x36 double]
[1355x36 double] [1194x36 double] [1130x36 double] [1277x36 double] [1494x36 double]
[1447x36 double] [1455x36 double] [1817x36 double] [1434x36 double] [1536x36 double]
I want my CSV file to have (rows x 36).
I tried already cell2csv and i did a loop of fprint also, but neither of them worked.
Thank you in advance.
As with the other users who have commented, it's not clear to me what the desired structure or ordering of the contents of your CSV should be, but here is an example workflow that assumes you would be comfortable first reshaping your cell array into an Q x 1 size (in column-major order), and then concatenating the contents in each cell into an Mx36 matrix.
myCell = {rand(10,36),rand(5,36); rand(4,36),rand(7,36)};
myCell = myCell(:);
myMatrix = cell2mat(myCell);
csvwrite('filename.csv',myMatrix);

MATLAB: Access Data in Nested Structure using For loop

Good day,
I have a nested structure in this format.
Data: [1x1 struct]
a: [1x1 struct]
a1: [10x1 double]
a2: [10x1 double]
a3: [10x1 double]
b: [1x1 struct]
b1: [10x1 double]
b2: [10x1 double]
c: [1x1 struct]
c1: [10x1 double]
c2: [10x1 double]
c3: [10x1 double]
c4: [10x1 double]
Each of sub-fields of a, b & c are duration percentage of an event in buckets. The number of elements in each bucket are number of data-sets. I'd like sum the bucket values of each data set and discard the entire data-set if they don't add up to 100%. How may I access each element of the buckets for a, b & c fields of Data using for loop in a simply format.
EDIT: I figured out how to call the sub-fields & it's elements, sum the percentages & now, if the data-sets not adding up to 100 need to fully removed from each sub-field.
field = fieldnames(Data);
for group = 1:length(field)
for subfield = fieldnames(Data.(field{group}))
fieldSize = structfun(#(field) length(field),Data.(field{group}));
nb_datasets = fieldSize(1,1);
for jj = 1:nb_datasets
for ii = 1:length(subfield)
a_dataset_pcts(jj,ii) = Data.(field{group}).(subfield{ii})(jj,1);
end
a_pct_total(jj,:) = sum(a_dataset_pcts(jj,:));
end
end
end
Matlab like matrices Bensa.... You should drop your approach now.
Fixed size datasets
If all a, b, c arrays are 10x1 sized, you should switch immediately to a cell of arrays, being the index the durations, and the arrays columns the datasets for each duration:
a: [1x1 cell]
a{1}: [10xna double]
a{2}: [10xnb double]
a{3}: [10xnc double]
All statistics go easy. You have two for loops, one for the durations, other for the dataset. Matlab vectorizes the functions inside each dataset (most of the time). In here, i am assuming max(.) is your aggregation array function for obtaining statistics:
n=length(a);
for i=1:n
ni=size(a{i},2);
for j=1:ni
max(a{i})
mean(a{i}')'
if j==j0 && i==i0
a{i}(:,j)=[]; % Cleanup j0th event in i0th dataset
end
end
end
Do you need to compare a.a1 & b.b1 & c.c1? If that is true, then you forcedly should create the auxiliar array x, and then get your stats:
for i=1:n
x(:,i)=a{i};
end
max(x')'
Variable size datasets
If the a, b, c arrays are different each time, then you upgrade the last data and switch to a cell of cells:
a{1}: [1xna cell]
a{1,1}: [la(1)x1 double]
...
a{1,na}: [la(na)x1 double]
a{2}: [1xnb cell]
...
a{3}: [1xnc cell]
...
In here the max(.')' approach is useless, because every dataset could be of different length. If that is the case, you still can reference the data as usually through columns:
n=length(a);
for i=1:n
ni(i)=size(a{i},2);
for j=1:ni(i)
li=length(a{i,j}) % Length of each dataset
max(a{i,j})
% mean(a{i}')' % This do not work anymore
if j==j0 && i==i0
a{i,j}=[]; % Cleanup j0th event in i0th dataset
end
end
end
Do this make sense?. Feel free to comment below...

quickly create a cell array with two elements in matlab?

Given two matrices of distinct sizes, say matrices A and B, how to quickly create a cell array to store them? I know how to do this using the standard way as the following.
c = cell(1,2);
c{1}=A,
c{2}=B;
Is there a better way? Basically, what I am asking is to initialize a given cell array quickly in matlab. Many thanks for your time and attention.
You can easily write the statement in one line with C = {A,B}. This creates a cell-array with two columns and one row.
Let's test it with random data:
A = rand(2,2);
B = rand(3,3);
C = {A,B}
This is the result:
C =
[2x2 double] [3x3 double]
In case you need two rows instead of two columns, just change the , to ; like you would do to create a 'normal' matrix.
A = rand(2,2);
B = rand(3,3);
C = {A;B}
This is the result:
C =
[2x2 double]
[3x3 double]
Otherwise you can directly do
C = {A,B};

Copy cell content from a column to another column in matlab

How should I copy all my cell content in a column to another column in the same cell. e.g.
a{1,1}=[1 2];
a{2,1}=[3 4 5];
a =
[1x2 double] []
[1x3 double] []
then,I'd like to copy all cell contents of this column to another column say column 2 without copying all rows separately using for. I used
a{:,3}= a{:,2}
The right hand side of this assignment has too few values to satisfy the left hand side.
it seems that a{:,2} is not working as it returns different values in different run. So here : doesn't work?
As an output I'd like to have the same elements as copying cells to my new cell homes. i.e.
a{1,2}=[1 2];
a{2,2}=[3 4 5];
So, a will be
a =
[1x2 double] [1x2 double]
[1x3 double] [1x3 double]
You need to use brackets instead if braces in this case.
Try it like this:
a = {[0 1];[2 3];[4 5];};
a(:,2) = a(:,1);

Converting Matlab .mat to csv and keeping variable names

I'm trying to convert a .mat file into csv, preserving the vector/variable names.
This is one example of what I'm dealing with:
mymat =
model_id: [2217x1 double]
own_dummies: [2217x26 double]
id: [2217x1 double]
product: [2217x1 double]
const: [2217x1 double]
mpd: [2217x1 double]
air: [2217x1 double]
mpg: [2217x1 double]
trend: [2217x1 double]
space: [2217x1 double]
hpwt: [2217x1 double]
cdindex: [20x1 double]
cdid: [2217x1 double]
outshr: [2217x1 double]
firmid: [2217x1 double]
share: [2217x1 double]
price: [2217x1 double]
I've tried using csvwrite('test.csv', mymat) but it gives me an error:
??? Undefined function or method 'real' for input arguments of type 'struct'.
Error in ==> dlmwrite at 192
str = sprintf('%.*g%+.*gi',precn,real(m(i,j)),precn,imag(m(i,j)));\
Error in ==> csvwrite at 32
dlmwrite(filename, m, ',', r, c);
I guess the problem is that I'm feeding csvwrite with a struct instead of a matrix.
I can convert the struct variable to variable to a matrix, but then I would loose the variable names.
Surely there is a better way?
how would you actually map the struct to a csv? you cannot do a straight forward map of fieldnames as entries on first line, because the matrices have incompatible dimensions. So this example you'd have to 1. introduce several columns for own_dummies and 2. expand the cdindex.
So you could write a wrapper to make the matrices themselves compatible and to write the columns yourself into the file. something along the (untested,conceptual) lines of
function saveData(filename, data, type)
% at first bring struct data to sensible format
if strcmp(type)='my_mat_type'
data.own_dummies2 = data.own_dummies[2,:]; % split into seperate columns
%...
data.own_dummies26 = data.own_dummies[26,:];
data.own_dummies = data.own_dummies[1,:];
data.cdindex = [data.cdindex -ones(1,2217-length(data.cdindex)]; % pad any missing values as -1
end;
FD = fopen(filename, 'w');
%todo did it open?
fields = fieldnames(data);
nfields = length(fields);
% create column name values
columns = strcat(strcat(fields,',')); % creates string = col1,col2,...coln,
columns = columns(1:length(columns)-1); %remove trailing comma
CRNL = char([10 13]); % or so
% print columns and newline
fprintf(FD,strcat(columns,CRNL));
dataout = cell2mat(struct2cell(data));
% use your method to write the data to the file
fclose(FD);
naturally, you could also just split the individual fields into separate files where the fieldname is contained within the filename, which might be simpler, generally speaking.