Table of tables. Subtables have variable height

17 views (last 30 days)
I created and initialized a table of tables, termed as 'master table'. The master table is 5x3 (but will grow in height). Each of the 3 columns contains subtables, where each column of subtables has the same width, but varying lengths.
% make subTable of width 3
varTypes = {'string','string','string'};
varNames = {'Data1','Data2','Data3'};
subTable3 = table('Size',[1,3],'VariableTypes',varTypes,'VariableNames',varNames);
% make subTable of width 4
varTypes = {'string','string','string','string'};
varNames = {'Data1','Data2','Data3','Data4'};
subTable4 = table('Size',[1,4],'VariableTypes',varTypes,'VariableNames',varNames);
% make subTable of width 5
varTypes = {'string','string','string','string','string'};
varNames = {'Data1','Data2','Data3','Data4','Data5'};
subTable5 = table('Size',[1,5],'VariableTypes',varTypes,'VariableNames',varNames);
% create vectors of each dummy table
numRowsInMasterTable = 5;
subTable3Vector = repmat({subTable3},numRowsInMasterTable,1);
subTable4Vector = repmat({subTable4},numRowsInMasterTable,1);
subTable5Vector = repmat({subTable5},numRowsInMasterTable,1);
% join vectors to create master table
masterTable = table(subTable3Vector,subTable4Vector,subTable5Vector);
I would like to keep adding to the subtables, and different subtables will have different heights. (each of the subtables in a given column will always have the same number of columns)
masterTable.SubTable1Vector(1,:) = vertcat(masterTable.SubTable1Vector(1,:),myData);
Here I receive the error:
Is this something possible to do in Matlab?
I originally coded this using a struct of tables, but due to processing time, trying to convert to table of tables instead.

Answers (1)

Peter Perkins
Peter Perkins on 24 Mar 2022
Joanna, I suspect that you are 95% of the way there, but it's hard to tell. You say, "each column of subtables has the same width, but varying lengths", but in your example code, each table has exactly one row. You've store those subtables in cell columns in a table, so it looks like you are aware that if the DO have different heights, they need to be in a cell array. If all three subtables in each row of masterTable has the same number of rows, you could vertcat all your subtables and have tables in a table, rather than tables in cell arrays in a table.
Hard to say from what you have shown.
In any case, I don't know what SubTable1Vector and myData in
masterTable.SubTable1Vector(1,:) = vertcat(masterTable.SubTable1Vector(1,:),myData);
are supposed to be, so I don't know what's doing wrong. Your solution may be as simple as removing the "(1,:)" from the LHS of that assignment.
  2 Comments
Joanna Parkes
Joanna Parkes on 4 Apr 2022
Thanks for the response. That's exactly it - I'm having trouble getting the subtables to be of varying lengths. Perhaps the piece I am missing is that they need to be cell arrays (not tables) to store varying length (so it would be a master table of sub cell arrays). Do you agree?
masterTable.SubTable1Vector(1,:) is simply the contents of the first subtable (row 1, all columns). I would like to grow masterTable.SubTable1Vector in height by using vertcat in my loop. The height of the masterTable.SubTable1Vector(1:,) is 1, but the second subtable masterTable.SubTable1Vector(2:,) might be 5.
What would the syntax of the sub cell arrays be?
Peter Perkins
Peter Perkins on 5 Apr 2022
Edited: Peter Perkins on 8 Apr 2022
I'm not really following. It sounds like you need to do something that is somewhat advanced. Let's break it down.
(By the way, you will notice that I'm using the new-in-R2022a Name=value syntax for passing named parameters into a function, in this case for passing VariableNames into the table function. If you are using R2022a, I recommend that. Otherwise, use 'Name',value as you always have.)
Let's say you have 2 tables each with 2 variables, and another 2 tables, each with 3 variables. Let's say that at first, all those have exactly one row.
t11 = table(11,"a",VariableNames=["X" "Y"]);
t21 = table(21,"b",VariableNames=["X" "Y"]);
t12 = table(12,"A",false,VariableNames=["P" "Q" "R"]);
t22 = table(22,"B",true,VariableNames=["P" "Q" "R"]);
T2col = {t11; t21};
T3col = {t12; t22};
masterTable = table(T2col,T3col)
masterTable = 2×2 table
T2col T3col ___________ ___________ {1×2 table} {1×3 table} {1×2 table} {1×3 table}
What is that? It's a 2-rows-by-2-vars table, both variables are 2x1 cell arrays. Here's the first var:
masterTable.T2col
ans = 2×1 cell array
{1×2 table} {1×2 table}
That 2x1 cell array contains 1x2 tables in both cells. Get at them the same way as any other cell array, with braces:
masterTable.T2col{1}
ans = 1×2 table
X Y __ ___ 11 "a"
That's a 1x2 table. This other element of the second var is a 1x3 table:
masterTable.T3col{2}
ans = 1×3 table
P Q R __ ___ _____ 22 "B" true
We have to talk about the size of masterTable, and the sizes of each table that's in (the cell arrays that are in) masterTable. I think your goal is to allow the tables in masterTable to have different sizes. That's the whole reason why you need cell arrays here. Otherwise, things would be simpler. I think maybe you want masterTable.T2col{1} and masterTable.T2col{2} to have the same variables, but possibly different numbers of rows. I think maybe you want masterTable.T2col{1} and masterTable.T3col{1} to have the same numbers of rows, but possibly different variables. Because you need cell arrays here, you will need to enforce those constraints yourself -- the cell array is too general to do it for you. If your requirements are simpler than what I'm thinking, then all this can probably be simpler. But you haven't really provided enough information to go on.
How to add rows to the inner tables? Same way you'd add rows to any table, except now you have a table in a cell array in a table, so you need to subscript to the right level. First way: Append a row and overwrite the old table:
t11NewRow = table(11.1,"aa",VariableNames=["X" "Y"]);
masterTable.T2col{1} = [masterTable.T2col{1}; t11NewRow]
masterTable = 2×2 table
T2col T3col ___________ ___________ {2×2 table} {1×3 table} {1×2 table} {1×3 table}
masterTable.T2col{1}
ans = 2×2 table
X Y ____ ____ 11 "a" 11.1 "aa"
Second way: Assign off the end with a one-row table:
t22NewRow = table(22.2,"BB",true,VariableNames=["P" "Q" "R"]);
masterTable.T3col{2}(end+1,:) = t22NewRow
masterTable = 2×2 table
T2col T3col ___________ ___________ {2×2 table} {1×3 table} {1×2 table} {2×3 table}
masterTable.T3col{2}
ans = 2×3 table
P Q R ____ ____ _____ 22 "B" true 22.2 "BB" true
Third way: Assign off the end of each variable:
masterTable.T2col{2}.X(end+1) = 21.1;
Warning: The assignment added rows to the table, but did not assign values to all of the table's existing variables. Those variables are extended with rows containing default values.
masterTable.T2col{2}.Y(end) = "bb"
masterTable = 2×2 table
T2col T3col ___________ ___________ {2×2 table} {1×3 table} {2×2 table} {2×3 table}
masterTable.T2col{2}
ans = 2×2 table
X Y ____ ____ 21 "b" 21.1 "bb"

Sign in to comment.

Categories

Find more on Tables in Help Center and File Exchange

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!