Nested table with adaptive numbers of columns

5 views (last 30 days)
Hi please help if you can,
I am trying to create an adaptive table that looks something like this:
However both the number of test cases, and number of repeats can be 1,2,...n etc.
I have made an attempt at this using the following method:
output = inputdlg({'Enter number of test cases'},'Input',[1 35],{'4'});
n_testcase = str2double(output{1, 1}); %Number of test cases
pre = 'Case';
case_names = {};
for i = 1:n_testcase
case_names = [case_names;strcat([pre,num2str(i,'%01d')])];
end
case_names = case_names'; %Names of test cases
output = inputdlg({'Enter number of repeats per test case'},'Input',[1 35],{'3'});
n_repeats = str2double(output{1, 1}); %Number of repeats
pre = 'R';
repeat_names = {};
for i = 1:n_repeats
repeat_names = [repeat_names;strcat([pre,num2str(i,'%01d')])];
end
repeat_names = repeat_names'; %Names of repeats
for i = 1:n_testcase
tab(i) = {array2table(zeros(3,n_repeats), 'VariableNames', repeat_names(1:n_repeats))};
end
%Attempt 1
table1 = table(tab{1,1:n_testcase}, 'VariableNames', shortname(1:n_testcase));
table1.Properties.RowNames = {'Onset (°C)', 'Peak (°C)', 'Heat released (J/g)'}
%Attempt 2
table1 = table(tab(1,1),tab(1,2),tab(1,3),tab(1,4), 'VariableNames', shortname(1:n_testcase));
Attempt 1 is close and it is adaptive. However, I need to be able to access specific columns to asign values eg. Case1,R1 which this table doesnt allow me.
Attempt 2 allows me to select a column e.g.
table1.Case1{1,1}.R1
However it is not adaptive and also does not allow me to assign row names.
I would also ideally like to be able to write the table to a csv file.
I would be extremely grateful for any help.
Robin

Accepted Answer

TADA
TADA on 13 Sep 2021
Edited: TADA on 13 Sep 2021
I know that this doesn't exacly answer your question and that its gonna sound like a case of "Tomayto, Tomahto"
But I think your table design is backwords.
When designing a data table, the convention is that columns represent the properties or fields of your data, and each datum or record is represented by a row in the table. This is especially relevant for tabular databases, but also applies to Matlab tables (and excel in my oppinion, simply because vertical scrolling is by far more convenient than horizontal scrolling).
Notice that tables have proeprties to access columns, to conveniently access specific fields of your entire dataset. For instance, if you design your table with columns for each property, you can for instance calculate the mean heat release as follows:
meanHeatRelease = mean(table1.HeatRelease);
So how would you represent your case/repeat?
Simple, add another column for case number, and another one for repeat number. That way, each record is uniquely identified by the case/repeat pair (in databases this is called a primary key)
n_testcase = 12;
n_repeats = 3;
% generate random dataset
heat = rand(n_repeats*n_testcase, 1);
onset = rand(n_repeats*n_testcase, 1);
peak = rand(n_repeats*n_testcase, 1);
% generate testcase identifiers
% this is duplicated by the number of repeats.
testCaseId = (1:n_testcase)';
testCaseIdForTab = repelem(testCaseId, n_repeats, 1);
% generate repeat identifiers per testcase
repId = repmat((1:n_repeats)', n_testcase, 1);
% now generate the table
t = table(testCaseIdForTab, repId, onset, peak, heat, ...
'VariableNames', {'TestCase', 'Repeat', 'Onset', 'Peak', 'HeatRelease'});
%
% How to use the table:
%
clf(gcf());
subplot(1, 2, 1);
% Histogram of the full onset data set
hist(t.Onset);
ylabel('Frequency');
xlabel('Onset (\circC)');
% bar chart of heat release averaged for each test case separately
subplot(1, 2, 2);
meanHeatReleasePerTestCase = mean(reshape(t.HeatRelease, n_repeats, n_testcase), 1);
bar(testCaseId, meanHeatReleasePerTestCase(:));
ylabel('Heat Release (J/g)');
xlabel('Test Case #');
% calculate the mean heat release of testcase 2:
testcase2HeatRelease = t{t.TestCase == 2, 'HeatRelease'};
testcase2HeatReleaseAvg = mean(testcase2HeatRelease)
testcase2HeatReleaseAvg = 0.8102
testcase2HeatReleaseStd = std(testcase2HeatRelease)
testcase2HeatReleaseStd = 0.1332
% get repeats 2 & 3 of testcases 4 & 5
values = t(ismember(t.TestCase, [4, 5]) & ismember(t.Repeat, [2, 3]), :)
values = 4×5 table
TestCase Repeat Onset Peak HeatRelease ________ ______ _______ _______ ___________ 4 2 0.92103 0.94974 0.77285 4 3 0.22738 0.47046 0.5113 5 2 0.79754 0.5575 0.94308 5 3 0.95666 0.3999 0.59172
  1 Comment
Robin Hartley
Robin Hartley on 14 Sep 2021
Thank you very much. I was trying to overcomplicate things. Working with the data in this manner is much simpler.

Sign in to comment.

More Answers (0)

Categories

Find more on Data Preprocessing 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!