Why does having only one row in table, break dot indexing?
60 ビュー (過去 30 日間)
古いコメントを表示
I have a cell that looks like this:

Using this line of code (see below), I can pull out the height of the tables in column 9. For context, 'master_cell' is the name of the 21x12 cell. This line of code is also in a for loop, so the variable 'i' will be changing with each iteration.
height(cell2table(master_cell(i,9)).Var1{1})
If 'i' were to equal 15, the code will spit out '16'. Which is the height of the 16x7 table in row 15. Exactly what I'm after. And this works for almost all lines in the cell, except for line 21, the 1x7 table.
For some reason, this line of code will not work with single row tables, the resulting error is this.
Subscripting into a table using one subscript (as in t(i)) is not supported. Specify a row
subscript and a variable subscript, as in t(rows,vars). To select variables, use t(:,i) or for
one variable t.(i). To select rows, use t(i,:).
Why does the line of code above work for all the other tables (tables with more than one row), but not the table in row 21? And what change can I make to my code so that I can get the height of all tables in the cell with the same line of code?
Thanks for reading!
1 件のコメント
Stephen23
約23時間 前
編集済み: Stephen23
約20時間 前
"what change can I make to my code so that I can get the height of all tables in the cell with the same line of code?"
Get rid of superfluous CELL2TABLE.
The correct indexing would make things simpler and clearer and does not throw an error:
height(master_cell{i,9})
採用された回答
Mathieu NOE
2025 年 12 月 3 日 16:38
hello
why not simply ask : size(master_cell{i,9})
this works for all cases (see last iteration)
demo :
% create dummy master cell
for r = 1:21
for c = 1:9
if c ==9
% create some dummy tables with descending size
T = array2table(rand(22-r,3));
master_cell{r,c} = T;
else
master_cell{r,c} = r+c;
end
end
end
%% main code
master_cell
for i = 1:size(master_cell,1)
% height(cell2table(master_cell(i,9)).Var1{1}) % this will fail
s = size(master_cell{i,9},1) % this works in all cases
end
0 件のコメント
その他の回答 (2 件)
Steven Lord
2025 年 12 月 3 日 16:45
Let's make some sample data.
C = cell(10, 1);
actualHeights = zeros(size(C));
for k = 1:height(C)
h = randi(10);
actualHeights(k) = h;
C{k} = array2table(rand(h, 7));
end
% Make sure it contains at least one one-row table
C{6} = array2table(rand(1, 7));
C
I'd use cellfun here.
heights = cellfun(@height, C)
If you don't want to use cellfun, but need/want to use a loop, you can still simplify your line of code quite a bit using curly-brace indexing into the cell array. This avoids the cell2table call. Also, you don't need to index into the table variable if you're just interested in the height of the table as a whole.
% height(cell2table(master_cell(i,9)).Var1{1})
heights2 = zeros(size(C));
for k = 1:numel(heights2)
heights2(k) = height(C{k});
end
Let's check that cellfun and loop give the same results as the actual heights used to create the tables.
[heights, heights2, actualHeights]
0 件のコメント
Stephen23
約20時間 前
編集済み: Stephen23
約16時間 前
"Why does having only one row in table, break dot indexing?"
Short answer: it doesn't break anything, you are not indexing what you think you are.
Long answer: the relevant behavior is described in the CELL2TABLE documentation as "If the contents of the cells in a column of C have:"
- "Compatible sizes and data types, and each cell has an array with one row, then the corresponding table variable is a homogeneous array..."
- "Different sizes, incompatible data types, or any cell has either an object that must be a scalar or an array with more than one row, then the corresponding table variable is a cell array.(For example, dictionaries and function handles are always scalars. Objects that must be scalars cannot be concatenated into a homogenous array. Therefore, cell2table must collect them into a cell array.)"
So before we even get to running any code we can expect that:
- a single-row table is clearly an "array with one row", so Var1 will consist of that (sub)table itself,
- a multiple-row table has "more than one row", so Var1 will consist of a cell array which in turn contains the (sub)table.
See also other threads on this topic:
Lets test this right now, starting with a 3-row table which replicates the relevant data from your examples:
A34 = cell2table({array2table(rand(3,4))}) % 3x4 table in a scalar cell -> scalar table
Note that A34.Var1 is clearly indicated as a cell array, not a table, exactly as the documentation explained... which means that in your examples without errors the indexing is not into a table, it is actually into a cell array. This is why checking the data types in MATLAB is a vital step to debugging. So lets take a look at the content of Var1:
B34 = A34.Var1 % cell array
This means that what you perhaps thought is indexing into a table is in fact linear indexing into a cell array:
B34{1} % linear indexing into a CELL ARRAY.
The contents of that cell array are the (sub)table, which is returned without any problems.
Now lets run exactly the same code again, but with a 1-row table:
A14 = cell2table({array2table(rand(1,4))}) % 1x4 table in a scalar cell -> scalar table
B14 = A14.Var1 % a TABLE (not a cell array!)
B14{1} % linear indexing into a TABLE throws an error.
The table documentation https://www.mathworks.com/help/matlab/matlab_prog/access-data-in-a-table.html
clearly states that "Linear indexing is not supported. When you index with curly braces or parentheses, you must specify both rows and variables." Which means that this behavior is entirely documented and expected.
In short, CELL2TABLE is not suitable for your task.
The much simpler (and more reliable) approach is to use curly-brace indexing to access the content of a cell array:
height(master_cell{i,9})
Which is also documented: https://www.mathworks.com/help/matlab/matlab_prog/access-data-in-a-cell-array.html
0 件のコメント
参考
カテゴリ
Help Center および File Exchange で Matrices and Arrays についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!