Can anyone please help me to understand the following problem with converting a cell-array to a table?

Hello everybody,
I have created two cell-arrays named test1 and test2, attached in the file testcell.mat.
The ninth cell in both cell-arrays includes a table-array. In test1 this table array has the size [1x18] and in test2 it has the size [5x18]. What I want to do is to convert these cell-arrays to table-arrays via cell2table(). What I am doing:
test1_table=cell2table(test1)
test2_table=cell2table(test2)
Now, I check the class of the ninth column in test1_table and test2_table...
class(test1_table.test19)
class(test2_table.test29)
... and the result is that class(test1_table.test19) is table and class(test2_table.test29) is cell!
Can anyone explain me the different class? Thank you very much!

2 Comments

Which version of MATLAB are you using? Your code/example is working fine on 2017b/Win.
Side note: as far as I am concerned, tables are not at a mature enough stage to be really reliable.. and this may last as long as they are implemented in pure MATLAB because they have all the limitations of MATLAB OOP (especially regarding the overload of indexing methods).
Thank you for your fast answer!
I am using version 2017a/Win. Maybe some extra information to concretize my problem. I have developed a tool that automatically generates these cell-arrays with variable size of the table-arrays in the ninth cell.
After converting the superior cell-arrays (test1 & test2) to table-arrays (test1_table & test2_table) I have to index the elements in the ninth column (test1_table.test19 & test2_table.test29). But the class of these elements seems to be dependend on the number of rows. If the table-array in the cell-array has only one row then cell2table converts it to class table and if it has more than one row then cell2table converts it to class cell.
The indexing methods for cell- and table-arrays are different, so I cannot find a consistent solution for both cases, except for a case-by-case analysis but I hope to find a better solution.

Sign in to comment.

 Accepted Answer

Tobias, as puzzling as it may seem at first, cell2table is doing the right thing.
t = cell2table(c) wants to take each column of c, c(:,j) and make it variable in t by, literally, vercat'ing the contents of all the cells in that column of c. That means that the contents in each cell of c had better all be one row. If they aren't, cell2table have to leave that column of c as a cell array variable in t. Consider the following simple examples:
>> c = {1 2; 3 4}
c =
2×2 cell array
{[1]} {[2]}
{[3]} {[4]}
>> t = cell2table(c)
t =
2×2 table
c1 c2
__ __
1 2
3 4
Everything in c{:,1) is a scalar double, so t.c1 is a 2x1 double. Likewise for t.c2. But compare to this:
>> c = {1 2; 3 [4;5]}
c =
2×2 cell array
{[1]} {[ 2]}
{[3]} {2×1 double}
>> t = cell2table(c)
t =
2×2 table
c1 c2
__ ____________
1 [ 2]
3 [2×1 double]
There's no way that c{2,2}, which is [4;5], can become one row in a numeric variable in t. So t.c2 has to become a cell array. That's what's happening in your case too.
Hard to say what you want to do here without more info. I'm guessing that eventually you are building up a table, each of whose rows is created from one of your cell row vectors. If your cell row vectors are always "all scalar numeric" except for the tables in the 9th cell, and those tables are always more than one row, then the table you'll be building up will necessarily have to look something like this:
>> t = table([1;2;3],[4;5;6],{array2table(rand(3,2)); array2table(rand(5,2)); array2table(rand(2,2))})
t =
3×3 table
Var1 Var2 Var3
____ ____ ___________
1 4 [3×2 table]
2 5 [5×2 table]
3 6 [2×2 table]
If the tables in that 9th cell were always one row, the Var3 in my example above could itself be a table, rather than a cell column vector of tables. That's a much simpler thing, but it sounds like that isn't what you have.
So the issue is how to prevent the edge case, where the table in your 9th cell has only one row, from behaving differently than your more general case. I think the simplest thing is "embrace the cell" and wrap those tables in an inner cell. This sounds and seems more complicated than it actually is:
>> test1{9} = {test1{9}};
>> test2{9} = {test2{9}};;
>> c = test1_table = cell2table(c)
>> c = test2; test2_table=cell2table(test2);
>> [test1_table; test2_table]
ans =
2×24 table
c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c23 c24
___ ____ ____ ___ __ __ ___ ___ ____________ ______ ______ ___ __________ ______ ______ ______ ___ __________ _____ ______ ______ __________ __________ ______
350 1100 -500 200 75 0 120 240 [1×18 table] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
350 1100 -500 200 75 0 120 240 [5×18 table] 26.056 31.381 0 1.7764e-15 5.3252 29.115 32.583 0 3.5527e-15 3.468 35.542 32.484 8.8818e-16 1.7764e-15 3.0575

1 Comment

Hello Peter,
thank you very much for your detailed answer. Your suggestion to wrap the tables in an inner cell works fine!

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!