Problem with converting uitable to table (array2table) with strange number of column names

Hello, I have a UITable that on startup has 4 columns.
I want to create some dummy data (3 columns) and play with the different save options (writecell, writematrix and writetable) to see which one handles NaNs the best and can save the column names.
I am hence steering towards writetable.
However, when I clear the table and re-enter my dummy data via:
uit=app.UITable;
uit.Data=[];
r = randi([0,10],10,3)
uit.Data = [r];
I notice that the number of column names is still 4 and not 3, yet the data size in columns is 3!
T=app.UITable;
vn=T.ColumnName
vn = %UITable Column Names
4×1 cell array
{'Column 1'}
{'Column 2'}
{'Column 3'}
{'Column 4'}
ans = % UITable Data size
10 3
hence the following fails
T = array2table(data, 'VariableNames',vn')
Error using array2table
The VariableNames property must contain one name for each variable in the table.
Any suggestions please?
(and a 2nd question, most of the time my data is doubles, however occasionally its a cell array - when I want e.g. some text. I assume the only chnage I would need is when creating the table I would use cell2table instead of array2table?)

1 Comment

"... when I clear the table and re-enter my dummy data ... Any suggestions please?"
My suggestion would be to update ColumnName whenever necessary, including when the number of columns of Data changes.

Sign in to comment.

 Accepted Answer

This seems to work, but is quite a lot for such a simple task
T=app.UITable;
vn=T.ColumnName;
vn=vn' %Transpose so horizontal
data=T.Data;
[row,cols]=size(data);
[sy,nnames]=size(vn)
val=nnames-cols;
vn2=vn;
switch true
case val<0
ReportMessage(app,'less than zero, need less Vn')
n=abs(val) % number of headings less than data cols
vn2=vn(1:nnames);
for i=1:n
vn2(end+i)={'NA'}
end
case val>0
ReportMessage(app,'Greater than zero - need more vn')
vn2=vn(1:cols);
end
T = array2table(data, 'VariableNames',vn2)

6 Comments

for i=1:n
vn2(end+i)={'NA'}
end
When n > 1, you're going to have a problem with that
n = 3; % number of elements to append to vn2
vn2 = cellstr("Column "+(1:1)); % some initial vn2
for i=1:n
vn2(end+i)={'NA'}
end
vn2 = 1x2 cell array
{'Column 1'} {'NA'}
vn2 = 1x4 cell array
{'Column 1'} {'NA'} {0x0 double} {'NA'}
vn2 = 1x7 cell array
{'Column 1'} {'NA'} {0x0 double} {'NA'} {0x0 double} {0x0 double} {'NA'}
because the ith iteration appends a new element to vn2 which is i elements off the end. Instead, on each iteration, one element should be appended directly onto the end of vn2, which is always location end+1.
n = 3; % number of elements to append to vn2
vn2 = cellstr("Column "+(1:1)); % some initial vn2
for i=1:n
vn2(end+1)={'NA'} % end+i changed to end+1
end
vn2 = 1x2 cell array
{'Column 1'} {'NA'}
vn2 = 1x3 cell array
{'Column 1'} {'NA'} {'NA'}
vn2 = 1x4 cell array
{'Column 1'} {'NA'} {'NA'} {'NA'}
However, another problem exists (still in the case of appending multiple elements to vn2), which is that those new variable names need to be unique (and distinct from the existing variable names)
data = randi([0,10],10,numel(vn2)); % data with the same number of columns as vn2 has elements
T = array2table(data, 'VariableNames',vn2)
Error using array2table (line 57)
Duplicate table variable name: 'NA'.
Thanks Vos. so this should work right:
case val<0
ReportMessage(app,'less than zero more less Vn')
vn
val
n=abs(val)
vn2=vn(1:nnames);
for i=1:n
s='col'+num2str(i)
vn2(end)={s}
end
Also, as I dont always need to add column names when adding data, rather than adding column names every time I add data to the uitable, would just doing this be a good solution too.
% Before adding any data to uitable - clear column names from cellarray
UITable.Data=[];
UITable.ColumnName={}
... add data as required

Thanks Walter.

But this doesnt append at the index end

Jason

Sign in to comment.

More Answers (0)

Categories

Products

Release

R2023b

Asked:

on 25 Jan 2025

Commented:

on 27 Jan 2025

Community Treasure Hunt

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

Start Hunting!