I am attempting to organize a large amount of data into nested structures in MATLAB and I would like for each structure to contain a cell array but I get
A dot name structure assignment is illegal when the structure is empty. Use a subscript on the structure.
Example of code:
Year.Org1 = struct('Set1',{},'Set2',{});
Year.Org2 = struct('Set1',{},'Set2',{});
and then I want Set1/Set2/etc to be cell arrays of n-rows with column 1 str, column 2 str, column 3 value, and so on.
Any advice on initializing this structure and then accessing various parts would be greatly appreciated.
With single curly braces the structure is initialized empty. You can achieve what you want by doubling the curly braces:
Year.Org1 = struct('Set1',{{}},'Set2',{{}});
Best,
Related
I have a couple of line of code which compares some values in two different matrices and even if it is true it doesn't enter the if part.
for i = 1:ux
for j = 1:SIR
if ShelfInfo{SIR, 2} == uniquexy(ux, 1) && uniquexy{ux, 2} == ShelfInfo{SIR, 3}
shelf = ShelfInfo{j,5};
shelves = [shelves; shelf];
1
end
end
end
This code is work but it doesn't enter the if part. I believe it is because of the braces. When I changed everything with curly braces I am receiving this error Brace indexing is not supported for variables of this type. When I am changing this braces with parentheses I am receiving this error Undefined operator '==' for input arguments of type 'table'.
I can't find what to do can you help me with it?
()-indexing subsets an array by elements, and works on any type of array.
{}-indexing subsets a cell array, and extracts the cells' contained values. Basically, it "reaches into" the cells and pulls out their contents. It only works on cell arrays, or objects that have overloaded subsref() to provide this behavior.
I'm guessing you're accidentally applying {}-indexing to your uniquexy in one of your references there, when both of them should be ()-indexing:
... uniquexy(ux, 1) && uniquexy{ux, 2} ...
Besides the indexing problem (which depends on the data type of your matrices and would be handy to give as a part of a minimal working example), in your if-statement you do not loop over your array elements. I assume you would want to use indices i and j, instead of SIR and ux (they indicate a fixed position in your arrays). So why do you need the if-statement inside two for-loops then?
May be check these links on accessing array elements depending on array types:
Basic array indexing
Cell vs. structure arrays
Tables
I have implemented a binary tree in Matlab using 'struct' type elements as nodes. An N-node tree has, say, N such structs.
My problem is that I have M such trees, each having a different number of nodes, N_1, N_2, ..., N_M. How can I hold these trees in a list or array which can be iterated? Several trials like struct of structs did not seem to work.
Edit: I want to do something like the following. myClassTree returns a tree with N_i nodes.
trees = struct;
for i=1:nTrees
tree = myClassTree(train(bags(i,:),:), entropy, depth);
trees(i) = tree;
end
The easiest thing is to create a cell array. Simply replace trees(i) = tree; with trees{i} = tree; (note braces, rather than parenthesis).
Cell arrays are useful whenever you want to store an array of mixed data types. To access elements of a cell array, you can use the braces again. For example, this should work as you expect:
currentTree = trees{someIndex};
The code that you posted creates an array of structs, which only works if the structures have the same fieldnames.
If you wanted (not recommended) you could created a struct of structs, but doing somehting like this trees.(['n' sprintf('%04d',i)]) = tree;. (But please don't.)
The "s{1} annoyance" of the title refers to the first line within the for-block below:
for s = some_cell_array
s = s{1}; % unpeel the enclosing cell
% do stuff with s
end
This s = s{1} business is necessary because the iteration over some_cell_array does not really iterate over the contents of some_cell_array, but rather over 1-element cells, each containing an item from some_cell_array.
Putting aside the question of who could possibly want this behavior as the default, is there any way to iterate over the bare contents of some_cell_array?
I don't think there is a way to avoid this problem in the general case. But there is a way if your cell array has all numbers or all chars. You can convert to an array and let the for loop iterate over that.
For example, this:
some_cell_array = {1,2,3}
for s = [some_cell_array{:}] % convert to array
s
end
Gives:
s =
1
s =
2
s =
3
Another option is to create a function that operates on every cell of the array. Then you can simply call cellfun and not have a loop at all.
I don't have any ideas about who would want this behavior or how it could be useful. My guess as to why it works this way, however, is that it's an implementation thing. This way the loop iterator doesn't change type on different iterations. It is a cell every time, even if the contents of that cell are different types.
Just a small add-on to Sam Robert's comment to the original question, on why you should prefer s{:} over s{1} : easier bug tracking.
Imagine you mistakenly stored your cell s as a column instead of a line. Then
for s = some_cell_array
will simply return a cell s which is equal to some_cell_array. Then the syntax s{1} will return the first element of some_cell_array, whereas s{:} will produce a list of all elements in some_cell_array. This second case will much more surely lead to an execution error in the following code. Whereas the first case could sometimes create a hard bug to detect.
I have a struct array called AnalysisResults, that may contain any MATLAB datatypes, including other struct arrays and cell arrays.
Then I have a string called IndexString, which is the index to a specific subfield of StructArray, and it may contain several indices to different struct arrays and cell arrays, for example:
'SubjectData(5).fmriSessions{2}.Stats' or 'SubjectData(14).TestResults.Test1.Factor{4}.Subfactor{3}'.
And then I have a variable called DataToBeEntered, which can be of any MATLAB datatype, usually some kind of struct array, cell array or matrix.
Using eval, it is easy to enter the data to the field or cell indexed by IndexString:
eval([ 'AnalysisResults.', IndexString, ' = DataToBeEntered;' ])
But is it possible to avoid using eval in this? setfield doesn't work for this.
Thank you :)
Well, eval surely is the easiest way, but also the dirtiest.
The "right" way to do so, I guess, would be to use subsasgn. You will have to parse the partial MATLAB command (e.g. SubjectData(5).fmriSessions{2}.Stats) into the proper representation for those functions. Part of the work can be done by substruct, but that is the lightest part.
So for example, SubjectData(5).fmriSessions{2}.Stats would need to be translated into
indexes = {'.' , 'SubjectData',
'()', {5},
'.' , 'fmriSessions',
'{}', {2},
'.' , 'Stats'};
indexStruct = substruct(indexes{:});
AnalysisResult = subsasgn(AnalysisResult, indexStruct, DataToBeEntered);
Where you have to develop the code such that the cell array indexes is made as above. It shouldn't be that hard, but it isn't trivial either. Last year I ported some eval-heavy code with similar purpose and it seemed easy, but it is quite hard to get everything exactly right.
You can use dynamic field names:
someStruct.(someField) = DataToBeEntered;
where someField is a variable holding the field name, but you will have to parse your IndexString to single field name and indices.
I have a function that takes a variable number of inputs, say myfun(x1,x2,x3,...).
Now if I have the inputs stored in a structure array S, I want to do something like
myfun(S.x1,S.x2,...). How do I do this?
You can first convert your structure to a cell array using STRUCT2CELL, and then use that to generate the list of multiple inputs.
S = struct('x1','something','x2','something else');
C = struct2cell(S);
myfun(C{:});
Note that the order in which the fields in S are defined are the order in which the inputs are passed. To check that the fields are in the proper order, you can run fieldnames on S, which returns a cell with field names corresponding to the values in C.
Something to add to Jonas' answer: Actually you can omit the struct and go right for the cell which is then expanded into a list for the function arguments:
c = {125, 3};
nthroot(c{:})