Table of Tables or cell of Tables

216 visualizzazioni (ultimi 30 giorni)
Hi,
I am preforming machine learning on 13 channels of data and am currently at the feature extraction stage. I have created 13 seperate tables and now which to bring these together into one variable.
I had been trying to create a 1*13 table in which each table element was another table, however I cannot get this to work. I have been able to create a 1*13 cell with each cell element being a table instead. My question is this, is there any benifit to using a tables within cells over tables within tables and vice versa. I will also include some code below, I would like to know how to also make this work for tables within tables too for furture use!
filesTable = array2table(fileNames); % Generate file names to identify each entry
sTruthBuffer = sTruthBuffer';
truthTable = array2table(sTruthBuffer); % Generate ground (clinical) truth
channels = cell(13,1); % generate empty cell for later
for i = 1:13 % For each of the 13 channels
actTable = rows2vars(array2table(act(:,:,i))); % act(ivity) is a 1*2538*13 double
actTable = removevars(actTable,'OriginalVariableNames'); % remove the orignal variale names as junk
actTable.Properties.VariableNames = {'Activity'} % Rename column as something sensible
mobTable = rows2vars(array2table(mob(:,:,i))) % mob(ility) is a 1*2538*13 double
mobTable = removevars( mobTable,'OriginalVariableNames');
mobTable.Properties.VariableNames = {'Mobility'}
complxTable = rows2vars(array2table(complx(:,:,i))) % complx(ity) is a 1*2538*13 double
complxTable = removevars(complxTable,'OriginalVariableNames');
complxTable.Properties.VariableNames = {'Complexity'}
channel = [filesTable,actTable,mobTable,complxTable,truthTable]; % Concatinate all the tables into one table 'channel'
channels{i} = channel ; % for each channel write the generated table 'channel' into a cell array called 'channels',
% this is okay but I think a nested table would be easier to work with?
end

Risposta accettata

Seth Furman
Seth Furman il 12 Nov 2021
Hi Christopher,
I had been trying to create a 1*13 table in which each table element was another table, however I cannot get this to work.
  • What is your reason for wanting to store these 13 tables in a single 1x13 table? Are you doing this because you want to have a label for each table?
  • Where are you getting stuck? Is the issue that the tables are different heights? Table variables must have the same height, but one way to get around this is to put the tables in cell arrays, e.g.
t1 = table([1;2;3]);
t2 = table([1;2]);
table({t1}, {t2}, 'VariableNames', ["MyLabel1", "MyLabel2"])
ans = 1×2 table
MyLabel1 MyLabel2 ___________ ___________ {3×1 table} {2×1 table}
It's also worth mentioning that you can store additional metadata in the UserData property of each table, e.g.
t1.Properties.UserData = "MyLabel1";
t2.Properties.UserData = "MyLabel2";
{t1, t2}
ans = 1×2 cell array
{3×1 table} {2×1 table}
  5 Commenti
Seth Furman
Seth Furman il 19 Nov 2021
Christopher, please let me know which of the following workflows meet your requirements and why. From your description it sounds like indexing syntax is most important to you, in which case (2) and (3) seem like they should be the most convenient.
1) Storing the channels as separate elements of a cell array
% Create sample data
rng default
act = 1000 * rand(1, 2538, 5);
mob = 1000 * rand(1, 2538, 5);
complx = 1000 * rand(1, 2538, 5);
% Preallocate a template channel
channel = table('Size', [2538 3], 'VariableTypes', ["double","double","double"], ...
'VariableNames', ["Activity","Mobility","Complexity"]);
% Preallocate 5 channels by copying 'channel'
channels = repmat({channel}, 1, 5);
% Populate channels
for i = 1:length(channels)
channels{i}.Activity = act(:,:,i)';
channels{i}.Mobility = mob(:,:,i)';
channels{i}.Complexity = complx(:,:,i)';
end
channels
channels = 1×5 cell array
{2538×3 table} {2538×3 table} {2538×3 table} {2538×3 table} {2538×3 table}
channels{1}.Activity
ans = 2538×1
814.7237 905.7919 126.9868 913.3759 632.3592 97.5404 278.4982 546.8815 957.5068 964.8885
2) Storing the channels as sub-tables
% Preallocate a template channel
channel = table('Size', [2538 3], 'VariableTypes', ["double","double","double"], 'VariableNames', ["Activity","Mobility","Complexity"]);
% Preallocate 5 channels by copying 'channel'
channels = repmat(table(channel), 1, 5);
channels.Properties.VariableNames = "Channel_" + (1:width(channels));
% Populate channels
for i = 1:width(channels)
channels.(i).Activity = act(:,:,i)';
channels.(i).Mobility = mob(:,:,i)';
channels.(i).Complexity = complx(:,:,i)';
end
head(channels)
ans = 8×5 table
Channel_1 Channel_2 Channel_3 Channel_4 Channel_5 Activity Mobility Complexity Activity Mobility Complexity Activity Mobility Complexity Activity Mobility Complexity Activity Mobility Complexity __________________________________ __________________________________ __________________________________ __________________________________ __________________________________ 814.72 949.91 441.85 877.63 417.46 245.85 768.77 986.38 926.66 548.45 719.43 144.62 181.33 720.86 444.1 905.79 173.42 640.23 469.1 844.88 793.38 388.08 623.95 407.95 9.5179 902.01 951.38 946.59 557.23 791.41 126.99 0.9046 220.18 437.42 551.51 903.76 453.26 596.26 16.093 828.36 195.18 152.9 100.85 449.51 546.85 913.38 878.46 49.502 746.18 813.15 907.45 132.85 577.29 88.012 908.54 897.67 39.922 388.04 345.53 414.56 632.36 850.54 210.45 467.91 315.4 225.58 758.51 403.03 705.9 705.3 821.61 387.15 289.22 60.251 229.84 97.54 336.41 864.19 860.83 859.36 334.14 565.24 545.45 899.41 243.33 665.95 288.97 73.087 444.04 213.81 278.5 98.33 110.84 466.51 217.37 16.859 648.64 777.43 829.93 589.23 656.68 339.9 194.61 220.88 806.04 546.88 628.12 964.97 498.1 115.36 417.57 798.06 470.4 485.04 938.9 535.54 658.7 417.49 724.76 942.14
channels.Channel_1.Activity
ans = 2538×1
814.7237 905.7919 126.9868 913.3759 632.3592 97.5404 278.4982 546.8815 957.5068 964.8885
3) Storing the channels as pages of a 3-dimensional array
channels = table(pagetranspose(act), pagetranspose(mob), pagetranspose(complx), ...
'VariableNames', ["Activity","Mobility","Complexity"]);
head(channels)
ans = 8×3 table
Activity Mobility Complexity ____________ ____________ ____________ 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double 1×1×5 double
channels.Activity(:,:,1)
ans = 2538×1
814.7237 905.7919 126.9868 913.3759 632.3592 97.5404 278.4982 546.8815 957.5068 964.8885
Christopher McCausland
Christopher McCausland il 20 Nov 2021
Hi Seth,
This helped me massively thank you! I went down the approach of (2) storing multiable channels as sub tables, this worked for me as tables are accepted by MATLAB ML tools and what I had failed to realise is that multiple channels should be fed in side by side for ML rather than independetly. I have some initial results from my ML which are as I would expect, now I just have to improve these with additional channel and feature selection. Thank you again for all you help!!!
Christopher

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Workspace Variables and MAT-Files in Help Center e File Exchange

Tag

Prodotti


Release

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by