Non-numerical data is still being loaded onto table. Need advice.

I don't want files with non-numerical data to be load on the UI Table but its still happening despite statment given. Need advice on where I went wrong.
% Check if the property fullPath is empty
if ~isempty(app.fullPath)
% Load the table from the file
app.dataTable = readtable(app.fullPath, 'VariableNamingRule', 'preserve');
% Ensure the data is numerical
% Apply a function across each variable in the table to check if all are numeric
if any(varfun(@(x) ~isnumeric(x), app.dataTable, 'OutputFormat', 'uniform'))
errordlg('This file contains non-numerical data.', 'Data Error', 'modal');
return;
else
% If data is numerical, display it in the UI Table
app.UITable.Data = app.dataTable;
app.UITable.ColumnName = app.dataTable.Properties.VariableNames;
end
else
errordlg('Please select a file first.', 'MISSING DATA', 'modal');
end

 Accepted Answer

Note that the table returned by readtable is stored in app.dataTable before it's checked for non-numeric variables, so other parts of the code might do stuff with that table including putting it in app.UITable.Data.
If that's the cause of the problem, you can prevent it by either:
(1) not updating app.dataTable until after the table is validated:
% Load the table from the file
temp = readtable(app.fullPath, 'VariableNamingRule', 'preserve');
% Ensure the data is numerical
% Apply a function across each variable in the table to check if all are numeric
if any(varfun(@(x) ~isnumeric(x), temp, 'OutputFormat', 'uniform'))
errordlg('This file contains non-numerical data.', 'Data Error', 'modal');
return;
else
% If data is numerical, store it and display it in the UI Table
app.dataTable = temp;
app.UITable.Data = app.dataTable;
app.UITable.ColumnName = app.dataTable.Properties.VariableNames;
end
or (2) setting app.dataTable to an appropriate value, e.g., an empty table, in case it is found to contain non-numerics:
% Load the table from the file
app.dataTable = readtable(app.fullPath, 'VariableNamingRule', 'preserve');
% Ensure the data is numerical
% Apply a function across each variable in the table to check if all are numeric
if any(varfun(@(x) ~isnumeric(x), app.dataTable, 'OutputFormat', 'uniform'))
app.dataTable = table(); % empty table
errordlg('This file contains non-numerical data.', 'Data Error', 'modal');
return;
else
% If data is numerical, display it in the UI Table
app.UITable.Data = app.dataTable;
app.UITable.ColumnName = app.dataTable.Properties.VariableNames;
end
If updating app.dataTable incorrectly does not appear to be the cause of the problem, then please share the mlapp file.

6 Comments

I've tried both suggestions and its still being shown. Here is my file.
Check the table returned by readtable. In particular, does the condition
any(varfun(@(x) ~isnumeric(x), temp, 'OutputFormat', 'uniform'))
actually work as expected? It may be that the table readtable returns has converted some text in the file to numeric values in the table.
Please also share one of your .xls* files that has non-numeric variables, and I can check on that as well.
This is the excel file. The table is read and all the everything was shown on the UITable. For the non numeric data is displayed as NaN on the UI Table
OK, I think the problem is actually some confusing nomenclature. Despite NaN meaning "not-a-number", its class is numeric, so isnumeric(NaN) returns true
class(NaN)
ans = 'double'
isnumeric(NaN)
ans = logical
1
as opposed to other data types you might have in a table, like strings
class("ok")
ans = 'string'
isnumeric("ok")
ans = logical
0
The point is that this
varfun(@(x) ~isnumeric(x), temp, 'OutputFormat', 'uniform')
returns false for variables containing NaNs, because NaNs are of a numeric class (but it would return true for a string array variable, for instance).
So, since it seems you really want to exclude tables that have any NaNs, what you can do is:
% Load the table from the file
temp = readtable(app.fullPath, 'VariableNamingRule', 'preserve');
% Ensure the data is numerical
% Apply a function across each variable in the table to check if all are numeric
if all(varfun(@isnumeric, temp, 'OutputFormat', 'uniform'))
% ALL variables are numeric variables, so
% get the table data out as a matrix
M = temp{:,:};
% is_good is true when there are no NaNs in that matrix
is_good = ~any(isnan(M(:)));
else
is_good = false;
end
if ~is_good
% some non-numeric or NaN data
errordlg('This file contains non-numerical data.', 'Data Error', 'modal');
return
end
% If data is numeric and all non-NaN, store it and display it in the UI Table
app.dataTable = temp;
app.UITable.Data = app.dataTable;
app.UITable.ColumnName = app.dataTable.Properties.VariableNames;
Thanks for the assistance it worked.

Sign in to comment.

More Answers (0)

Asked:

on 4 Mar 2024

Commented:

on 4 Mar 2024

Community Treasure Hunt

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

Start Hunting!