cell array of strings to matlab structure - arrays

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.

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.

Matlab arrayfun with array of elements that are [1x4 struct]

I have a array, 'MY_STRUCTURES_Array', with single row and N columns. Each element is a [1x4 struct]. I want to extract a numeric valued 'thisField' from each structure of each [1x4 struct] element.
The result I am looking for is a 4xN array of the values for each 'thisField' value, where each row in this result corresponds to a colum in the [1x4 struct].
The code I am using is this:
arrayfun(#(x) (x.thisField), MY_STRUCTURES_Array);
Matlab returns the error
Attempt to reference field of non-structure array.
If I put the following in the command line,
MY_STRUCTURES_Array{1}
I get a list of all of the fields of the [1x4 struct].
If I put this in the command line,
MY_STRUCTURES_Array{1}.thisField
I get four answers, like this:
ans =
1
ans =
1
ans =
1
ans =
0
If I look at the size
size(MY_STRUCTURES_Array{1}.thisField)
Matlab says "Error using size", so I see this is not an array. But I'm not sure what it is.
I am not sure how to proceed to get the 4xN array I am looking for.
UPDATE
Output from command MY_STRUCTURES_Array returns a row array of [1x4 struct].
Output from whos MY_STRUCTURES_Array{1} returns nothing
Output from whos MY_STRUCTURES_Array returns:
Name Size Bytes Class Attributes
MY_STRUCTURES_Array 1x103 1371136 cell
Output from whos MY_STRUCTURES_Array{1}.thisField returns nothing
Output from MY_STRUCTURES_Array{1}.thisField was shown in the original post.
The fact that you're accessing MY_STRUCTURES_Array as MY_STRUCTURES_Array{1} indicates that it's a cell array, so I'll answer based on that.
Say we have MY_STRUCTURES_Array as a cell array of struct arrays:
MY_STRUCTURES_Array = {[1x4 struct], [1x4 struct], [1x4 struct]}
It contains N elements (here N = 3). Each element is a struct array with 4 elements and various fields. We want to extract the value of field foo, which contains a single number.
out = zeros(4, N);
for it = 1 : N
out(:, it) = [MY_STRUCTURES_Array{it}.foo];
end
out(i, j) now contains the value of MY_STRUCTURES_Array{j}(i).foo
EDIT:
Using arrayfun():
out = arrayfun(#(x) x.foo, cell2mat(MY_STRUCTURES_Array')')
This converts the cell array of struct arrays into a 2d struct array, then extracts field foo from each element.

Matlab - Filter Struct array using multiple strings

I have a large struct array
Month =
1x10131 struct array with fields:
name
date
bytes
isdir
datenum
From which I need to filter a number of rows using an array (in the name field).
I was previously using
result = Month([string here])
But I just noticed that is not doing what I wanted at all, it seems to be filtering in someway, but not in anyway I desired.
I have the above struct array, and 4 strings (name) in a char array. I need an output of the four matched names with the associated date, bytes, isdir and datenum from the original array..
Here's a little code snippet that will put in SelectedMonth the structs that have the name field matching one of the entries in cell array SelectedName:
SelectedName = {'n1', 'n2', 'n3', 'n4'}; % change to your values
SelectedIndex = cellfun(#(x) any(strcmp(x, SelectedName)), {Month.name});
SelectedMonth = Month(SelectedIndex);
From here on you may extract wjhatever information you want from the struct array SelectedMonth. Please note that the string comparison is case sensitive, so be careful about the case of the names.

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 can I display and access structure array contents in MATLAB?

Firstly, I have the user input their own text files consisting of states, capitals, and populations and I put all of these values into a structure array using the following code:
clear
clc
%Part A
textfile=input('What is the name of your text file?\n','s');
fid=fopen(textfile);
file=textscan(fid,'%s %s %f','delimiter',',');
State=file{1}
Capital=file{2}
Population=file{3}
regions=struct('State',State,...
'Capital',Capital,...
'Population',Population)
fclose(fid);
My first question: is it possible to display all of the values in the structure? Displaying the structure array just gives me this:
50x1 struct array with fields:
State
Capital
Population
And my second question: is it possible for me to access information in this structure by trying to find, for example, 'California' only?
As you've already discovered, the default display of structure arrays in MATLAB doesn't tell you much, just the array dimensions and field names. If you want to see the contents, you'll have to create formatted output yourself. One way you can do this is to use STRUCT2CELL to collect the structure contents in a cell array, then use FPRINTF to display the cell contents in a particular format. Here's an example:
>> regions = struct('State',{'New York'; 'Ohio'; 'North Carolina'},...
'Capital',{'Albany'; 'Columbus'; 'Raleigh'},...
'Population',{97856; 787033; 403892}); %# Sample structure
>> cellData = struct2cell(regions); %# A 3-by-3 cell array
>> fprintf('%15s (%s): %d\n',cellData{:}); %# Print the data
New York (Albany): 97856
Ohio (Columbus): 787033
North Carolina (Raleigh): 403892
With regard to your second question, you can collect the entries from the 'State' fields in a cell array, compare them to a given name with STRCMP to get a logical index, then get the corresponding structure array element:
>> stateNames = {regions.State}; %# A 1-by-3 cell array of names
>> stateIndex = strcmp(stateNames,'Ohio'); %# Find the index for `Ohio`
>> stateData = regions(stateIndex) %# Get the array element for `Ohio`
stateData =
State: 'Ohio'
Capital: 'Columbus'
Population: 787033
NOTE:
As you mention in a comment, each 'Population' entry in your structure array ends up containing the entire 50-by-1 vector of population data. This is likely due to the fact that file{3} in your sample code contains a vector, while file{1} and file{2} contain cell arrays. In order to properly distribute the contents of the vector in file{3} across the elements of the structure array, you need to break the vector up and place each value in a separate cell of a cell array using NUM2CELL before passing it to STRUCT. Defining Population like this should solve the problem:
Population = num2cell(file{3});

Resources