Exporting a cell structure from Matlab to Excel - arrays

I have a cell structure which has <1*40 struct> inside it. Every structure has the same field names (each having 12 field names and respective values). I want to Export this cell Array into an Excel file such that all the field names become the heading (12 consecutive columns), and below each field Name Comes its respective field values.
I have tried xlswrite by using cell2struct but it does not help.
If anyone could help me with this ?

If your input data looks something like this:
data = {struct('a', 1, 'b', 2), struct('a', 3, 'b', 4)};
You can process it using a combination of struct2cell and simple concatenation.
First convert from a cell array to an array of structs:
data = cat(2, data{:});
Then you can get the values using struct2cell
values = struct2cell(data(:));
Then the column names should simply be the fieldnames of your struct
headers = fieldnames(data);
Then you can concatenate the headers with the data to yield the input to xlswrite
xlsdata = cat(2, headers, values)'
xlswrite('filename.xlsx', xlsdata);
xlsdata =
'a' 'b'
[1] [2]
[3] [4]
We can condense this a little bit:
xlsdata = cat(2, fieldnames(data{1}), struct2cell(cat(2, data{:})))';
xlswrite('filename.xlsx', xlsdata);

Related

MATLAB: How to tabulate structs with same fields

I have use a 428×1 cell array called data
data = {[1×1 struct]
[1×1 struct]
....
[1x1 struct]}
These struct all have the same structure
data {2,1}
>>struct with fields
additional_model_information: 'H Series,S3150-S0-AW-04-02-C-F421,'
ceiling_fan_size_diameters_in_inches: '60'
airflow_efficiency_cfm_watt_low: '727'
airflow_efficiency_cfm_watt_high: '392'
The structure fields are the same for all 428 cells, and the fields values change in each struct.
How could i create a table that puts all of the structs together so that it shows all of the field values for each field? Pehaps using a nested for loop?
I eventually want to export this data to excel.
Let's say you've got your nx1 cell array of structs, data. This method doesn't assume you have 4 fields in your data or any knowledge of what they are called. You could even use it with structs with different fieldnames if you included some try/catch logic.
You can get the field names of a representative struct using fieldnames
fnames = fieldnames(data{1});
Then set up some output cell array out of the correct size
out = cell(numel(fnames), numel(data));
Then use nested loops to 1. loop through items in data and 2. loop through field names.
for n = 1:numel(data)
for field = 1:numel(fnames)
temp = data{n};
out{field, n} = temp.(fnames{field});
end
end
Finally, append the field names as the first column
out = [fnames, out];
And write the cell array to your Excel file
% File location, cell array, sheet, cell
xlswrite('C:\...\test.xlsx', out, 1, 'A1');
How about
T = cell(length(data) , 4);
for k = 1 : length(data)
T(k , :) = {data{k}.additional_model_information , ...
data{k}.ceiling_fan_size_diameters_in_inches, ...
data{k}.airflow_efficiency_cfm_watt_low, ...
data{k}.airflow_efficiency_cfm_watt_high};
end
Then you can use xlswrite to export to excel.

selecting specific cells in a structure array based on the values of the field

Data looks more like this:
DATA = struct('Direction',{[1,1,1,1],[1,1,2,1],[2,2,2,2,2],[2,2,2,2,1,2],[2,2,2,2]},'Tr‌ial'{'correct','incorrect','incorrect','correct','correct'});
this is just an example and i have other fields as well
So for example, I just want to work with the cells in my struct which have the Trial as correct, so I want to select those cells and I would like to store those cells in a separate struct. I am not sure if I'm clear or not I apologize for that.
Same for if I want to select only those cells which the direction field that is a vector as what I have here with different sizes but I want to select only those vectors that all their elements are "2" only.
Thank you
You can filter only the elements with Trial = 'Correct' like this:
DATA = DATA(arrayfun(#(x) strcmp(x.Trial, 'correct'), DATA))
If you also want to filter only the elements where Direction = 2 (all values), then also do this:
DATA = DATA(arrayfun(#(x) all(x.Direction == 2), DATA))
Or you can do all above in just one line like this:
DATA = DATA(arrayfun(#(x) strcmp(x.Trial, 'correct') & all(x.Direction == 2), DATA))

Struct array initialization without values

I have a structure
AStructX : 7x1 struct array with fields:
field1
field2
field3
field4
field5
Now I want to generate an empty 1x7 that looks like the previous struct, but with empty values.
I tried
AStructY = repmat(AStructX(1),1,7); but the values of AStructX is copied.
I tried
AStructY = repmat(AStructX(1),1,0); when I add values to it, it pass with MATLAB, but Coder generation fails with the following error message
??? Subscripting into an empty matrix is not supported.
Use cell2struct:
len = 7;
fn = fieldnames(AStructX)
AStructY = cell2struct(repmat({[]},numel(fn),len),fn)
That gives a 7x1 struct array with the same fields, empty contents. If you want a 1x7, simply transpose the array (i.e. AStructY = cell2struct(...).').
I'll make the following assumptions:
1. AStructX is 2-D.
2. You want the new structure to have the size size(AStructX').
3. The field names are not fixed.
To do this, you first need the fieldnames, then create a new struct with empty cells as values:
names = fieldnames(AStructX)'; %'// row vector
len = length(names); %// number of fields
for i=1:len
names{2,i} = cell(size(AStructX')); %'// the contents are empty
end
AStructY = struct( names{:} ); %// will take the names matrix columnwise
This will result in completely empty entries ([]), if you want to initialize the values to 0 instead, the line inside the loop becomes
names{2,i} = num2cell(zeros(size(AStructX'))); %'// initialize values to 0

How to save a structure array to a text file

In MATLAB how do I save a structure array to a text file so that it displays everything the structure array shows in the command window?
I know this thread is old but I hope it's still going to help someone:
I think this is an shorter solution (with the constraint that each struct field can contain scalar,arrays or strings):
%assume that your struct array is named data
temp_table = struct2table(data);
writetable(temp_table,'data.csv')
Now your struct array is stored in the data.csv file. The column names are the field names of a struct and the rows are the different single-structs of your struct-array
You have to define a format for your file first.
Saving to a MATLAB workspace file (.MAT)
If you don't care about the format, and simply want to be able to load the data at a later time, use save, for example:
save 'myfile.mat' structarr
That stores struct array structarr in a binary MAT file named "file.mat". To read it back into your workspace you can use load:
load 'myfile.mat'
Saving as comma-separated values (.CSV)
If you want to save your struct array in a text file as comma-separated value pairs, where each pair contains the field name and its value, you can something along these lines:
%// Extract field data
fields = repmat(fieldnames(structarr), numel(structarr), 1);
values = struct2cell(structarr);
%// Convert all numerical values to strings
idx = cellfun(#isnumeric, values);
values(idx) = cellfun(#num2str, values(idx), 'UniformOutput', 0);
%// Combine field names and values in the same array
C = {fields{:}; values{:}};
%// Write fields to CSV file
fid = fopen('myfile.csv', 'wt');
fmt_str = repmat('%s,', 1, size(C, 2));
fprintf(fid, [fmt_str(1:end - 1), '\n'], C{:});
fclose(fid);
This solution assumes that each field contains a scalar value or a string, but you can extend it as you see fit, of course.
To convert any data type to a character vector as displayed in the MATLAB command window, use the function
str = matlab.unittest.diagnostics.ConstraintDiagnostic.getDisplayableString(yourArray);
You can then write the contents to a file
fid = fopen('myFile.txt', 'w');
fwrite(fid, str, '*char');
fclose(fid);

cell array of strings to matlab structure

I need to create a matlab structure as such ds=struct('name',{{'my_name_is'},{'matlab_thining_hair'}}) which stores as a 1x2 struct array with fields: name. A call to ds.name generates the output:
ds.name
ans =
'my_name_is'
ans =
'matlab_thining_hair'
Please note the single quotes in the output. They are important. That said, I need to create the above mentioned structure using the following variable:
X = [1x46 char] [1x47 char] i.e., 1x2 cell, which I believe is actually a cell array of strings. Among other things, I've tried the following:
Y = cell2struct(X, 'name', 1)'
which results in a 1x2 structure array with fields name, however a call to Y generates the output:
Y.name
ans = my_name_is
ans = matlab_thining_hair
Note that the single quotes in the output are missing, and albeit both Y and ds are 1x2 struct arrays with fields name, the field values are not formatted the same and the structures also vary in their bytes size. How to format the field values as character arrays?
In your first case you have created a struct with two fields whose values are cell arrays. The cell arrays are displayed with quotes.
In your second case your struct fields have char arrays which is what you want. Char arrays display without quotes.
You can verify this by typing in your command prompt {'abc'} and then 'abc'.
In your first case you can create non-cell array field values by passing the strings outside cell parenthesis.
ds=struct('name',{'my_name_is','matlab_thining_hair'})
Stick your char strings in another layer of cells before calling cell2struct. Instead of:
X = { 'foo', 'bar' }
Try:
X = { {'foo'}, {'bar'} }
That is, a 1-by-2 cell whose cell contents are themselves cells, not chars. Then cell2struct(X, 'name', 1) should give you a struct array with fields of cell arrays.
If your existing X is a cellstr, I think you can just call num2cell on it to push each cell down into another layer of cell indirection.

Resources