Using Summary on a table to access just the last 2 column stats

5 ビュー (過去 30 日間)
Jason
Jason 2025 年 4 月 24 日
編集済み: dpb 2025 年 4 月 27 日
Hello, I have an array of numbers that I want to apply the "summary" feature associated with tables to. This is because I want to exploit the stats this gives
The issue Im having is that the number of cloumns and clomn names isnt always the same. what is the same is I really want the stats for the last 2 columns always
This is what I have done so far:
T=app.UITable;
d=T.Data;
cn=T.ColumnName
d2=array2table(d,'VariableNames',cn)
% d2.Properties
S=summary(d2)
% B = string(fieldnames(S))
% B(end)
But is is just a struct, so I wanted to access the last 2 column details which I understand is via
S.fieldname.
But thats my issue, the field name is in cn but doing
S.cn(end)
doesn't work

採用された回答

dpb
dpb 2025 年 4 月 25 日
編集済み: dpb 2025 年 4 月 25 日
You fell into a trap of using a routine that isn't suitable for your purposes...while summary does compute a bunch of statistics without much need for user input, its output wasn't designed to return those parameters for other than viewing.
For your purposes I'd suggest doing something more on the line of
tM=array2table(magic(5)); % out friendly sample dataset yet again...
format bank, format compact % just to make output consistent...
% our supporting and engine code...
ourstats={'Min','Max','Mean','Median','StD'}; % a list of wanted statistics
fnS=@(x)[min(x);max(x);mean(x);median(x);std(x)]; % define our wanted statistics as anonymous function
Statistics=fnS(tM.(width(tM)-1)); % compute the statistics as array
tS=array2table(Statistics); % convert to table
tS.Properties.RowNames=ourstats % add the identifier of which is which
tS = 5x1 table
Statistics __________ Min 2.00 Max 21.00 Mean 13.00 Median 14.00 StD 8.06
The statistic names can be augmented as desired or the variable identified as the column header, your choice. It's also straightforward to add the units column.
I haven't messed with the uitable enough to know about all the internal formatting it supports although I know there is quite a bit for presentation-only purposes available, but building the base data is pretty straightforward from a "deadahead" path rather than trying to parse a difficult-to-use builtin function output.
Probably you didn't recognize that can build an anonymous function comprising several of the builtin functions outputs catenated as long as they all reduce to a common data type.
NOTA BENE:
Statistics=fnS(tM.(width(tM)-1));
is yet another addressing mode of using the desired column number. width()-1 is the same as the subscripting expression end-1 without needing the array reference for the end function to key against.
  6 件のコメント
Jason
Jason 2025 年 4 月 26 日

Thankyou for all your excellent explanations

dpb
dpb 2025 年 4 月 26 日
編集済み: dpb 2025 年 4 月 27 日
Glad to help...the table(*) and all its possible addressing rules can get pretty complex; it takes some "time in grade" and a lot of study/practice to learn one's way around thoroughly.
(*) As is also the struct

サインインしてコメントする。

その他の回答 (2 件)

Steven Lord
Steven Lord 2025 年 4 月 24 日
As shown on this documentation page, one of the ways to extract a sub-table from a table is numeric indices.
M = magic(5);
sampleTable = array2table(M)
sampleTable = 5x5 table
M1 M2 M3 M4 M5 __ __ __ __ __ 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
I could use variable names:
subtable1 = sampleTable(:, ["M4", "M5"])
subtable1 = 5x2 table
M4 M5 __ __ 8 15 14 16 20 22 21 3 2 9
Or I could use numbers.
subtable2 = sampleTable(:, [4 5])
subtable2 = 5x2 table
M4 M5 __ __ 8 15 14 16 20 22 21 3 2 9
Using end in the indexing expression also works.
subtable3 = sampleTable(:, [end-1 end])
subtable3 = 5x2 table
M4 M5 __ __ 8 15 14 16 20 22 21 3 2 9
  4 件のコメント
Jason
Jason 2025 年 4 月 24 日
Thanks Steven.
but i need to get the stats and for that i need s.fieldname.
I don't know in advance what the column headings are (= the field names), but I can get it via
T=app.UITable3;
cn=T.ColumnName
So is there a way to use the S.fieldname by just getting the last field name from cn, somehting like
S=summary(d2)
stats_I_want=S.cn{end}
Steven Lord
Steven Lord 2025 年 4 月 24 日
You could use indexing or dynamic {field, variable, property} names, depending on whether S is a {struct, table, object}.
M = magic(5);
sampleTable = array2table(M)
sampleTable = 5x5 table
M1 M2 M3 M4 M5 __ __ __ __ __ 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
n = randi(width(M), 1)
n = 5
varname = "M"+n
varname = "M5"
S1 = sampleTable.(varname) % double vector
S1 = 5×1
15 16 22 3 9
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
S2 = sampleTable(:, varname) % table
S2 = 5x1 table
M5 __ 15 16 22 3 9
S3 = sampleTable{:, varname} % double vector
S3 = 5×1
15 16 22 3 9
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>

サインインしてコメントする。


dpb
dpb 2025 年 4 月 24 日
編集済み: dpb 2025 年 4 月 24 日
Use the previous illustrated syntax on the summary table, too...you said you knew the columns of interest are the last two, so
tM=array2table(magic(5));
S=summary(tM(:, [end-1 end]))
S = struct with fields:
Var4: [1x1 struct] Var5: [1x1 struct]
S.Var4
ans = struct with fields:
Size: [5 1] Type: 'double' Description: '' Units: '' Continuity: [] NumMissing: 0 Min: 2 Median: 14 Max: 21 Mean: 13 Std: 8.0623
fnames=fieldnames(S)
fnames = 2x1 cell array
{'Var4'} {'Var5'}
stats_I_want=S.(char(fnames(end)))
stats_I_want = struct with fields:
Size: [5 1] Type: 'double' Description: '' Units: '' Continuity: [] NumMissing: 0 Min: 3 Median: 15 Max: 22 Mean: 13 Std: 7.2457
It might be more simpler to use groupsummary:here depending on just what you are looking for even though may have to create a fake grouping variable...
tM1=tM(:, [end-1 end]);
tM1=addvars(tM1,ones(height(tM1),1),'NewVariableNames','Group','Before',tM1.Properties.VariableNames(1))
tM1 = 5x3 table
Group Var4 Var5 _____ ____ ____ 1 8 15 1 14 16 1 20 22 1 21 3 1 2 9
S=groupsummary(tM1,'Group','all',tM1.Properties.VariableNames(end))
S = 1x14 table
Group GroupCount mean_Var5 sum_Var5 min_Var5 max_Var5 range_Var5 median_Var5 mode_Var5 var_Var5 std_Var5 nummissing_Var5 nnz_Var5 numunique_Var5 _____ __________ _________ ________ ________ ________ __________ ___________ _________ ________ ________ _______________ ________ ______________ 1 5 13 65 3 22 19 15 3 52.5 7.2457 0 5 5
You can select any subset of the above and/or add others as well...
Alternatively, with it you can select which variables to use as the data variables as input rather than subselecting another table...
datavars=false(1,width(tM)); datavars(end)=true; % select only last variable
tM=addvars(tM,ones(height(tM),1),'NewVariableNames','Group','Before',1)
tM = 5x6 table
Group Var1 Var2 Var3 Var4 Var5 _____ ____ ____ ____ ____ ____ 1 17 24 1 8 15 1 23 5 7 14 16 1 4 6 13 20 22 1 10 12 19 21 3 1 11 18 25 2 9
S=groupsummary(tM,'Group','all',datavars)
S = 1x14 table
Group GroupCount mean_Var4 sum_Var4 min_Var4 max_Var4 range_Var4 median_Var4 mode_Var4 var_Var4 std_Var4 nummissing_Var4 nnz_Var4 numunique_Var4 _____ __________ _________ ________ ________ ________ __________ ___________ _________ ________ ________ _______________ ________ ______________ 1 5 13 65 2 21 19 14 2 65 8.0623 0 5 5
  2 件のコメント
Jason
Jason 2025 年 4 月 25 日
編集済み: Jason 2025 年 4 月 25 日
Thankyou, this is exactly what I was looking for to get the last fieldname (=column heading in uitable) when it could be anything. I'd also like to appreciate Stevens effort too which has helped me.
stats_I_want=S.(char(fnames(end)))
Could I ask one more request.
I'd like to display (for the last two columns only), a table in a uitextarea showing the stats
I use this:
% Table approach
T=app.UITable3;
d=T.Data;
cn=T.ColumnName;
d2=array2table(d,'VariableNames',cn); % ,'VariableNames',{'Feet','Inches','Centimeters'}))
S=summary(d2)
fnames=fieldnames(S)
S2=S.(char(fnames(end)))
S3=S.(char(fnames(end-1)))
str = formattedDisplayText(S2) %My add to message area function, see below
where
function ReportMessage(app,msg)
currString=get(app.MessagesTextArea,'Value');
%currString=[{char(msg)};currString]; %add to top of message box
currString=[currString; {char(msg)}]; %add to bottom of message box
app.MessagesTextArea.Value=currString;
drawnow;
scroll(app.MessagesTextArea,'bottom');
end
This displays this in my textarea
Size: [667 1]
Type: 'double'
Description: ''
Units: ''
Continuity: []
NumMissing: 0
Min: -0.000391
Median: -0.000235
Max: -2.2e-05
Mean: -0.00021689
Std: 0.00013186
1: How can I just show these parameters, and justify it like this:
% column heading #1 (=end) column heading #2 (=end-1) (underlined)
Min: -0.000391 % values for this column
Median: -0.000235 % values for this column
Max: -2.2e-05 % values for this column
Mean: -0.00021689 % values for this column
Std: 0.00013186 % values for this column
This is why I used the "table approach" because i thought I could just splat the ouptut of the table summary into the uiarea with a "table" appearance
Jason
Jason 2025 年 4 月 25 日
This seems to work:
T=app.UITable;
d=T.Data;
Mx=max(d); % Gets max of all columns by default
Mn=min(d); % Gets min of all columns by default
% Create Table manually
params = ["Max_Xtilt";"Min_Xtilt";"Max_dx(um)";"Min_dz(um)"];
Vals = [10^6*Mx(1,end);10^6*Mn(1,end);10^6*Mx(1,end-1);10^6*Mn(1,end-1)];
units = ["urads";"urads";"um";"um"];
tbl = table(params,Vals,units)
str = formattedDisplayText(tbl)
str = regexprep(str,'</?strong>','')
ReportMessage(app,str)
params Vals units
____________ _____ _______
"Max_Xtilt" -22 "urads"
"Min_Xtilt" -391 "urads"
"Max_dx(um)" -11 "um"
"Min_dz(um)" -1955 "um"

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

製品


リリース

R2024b

Community Treasure Hunt

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

Start Hunting!

Translated by