Why does 'groupsummary' error when applying function handle to an ordinal categorical table variable?

11 views (last 30 days)
I execute the following commands in MATLAB:
>> load hospital
>> patients = dataset2table(hospital);
>> patients.AgeBand = discretize(patients.Age, 0:10:100, 'categorical');
>> assert(isordinal(patients.AgeBand))
The last line should be enough to guarantee that 'patients.AgeBand' is an ordinal categorical.
However, while I am able to apply a method through a function handle to the table variable 'Age', which is a column of doubles:
>> groupsummary(patients, "Sex", @max, "Age")
trying to do so on the column 'AgeBand', which is guaranteed to be an ordinal categorical column, results in an error which wrongly claims that 'AgeBand' is categorical and NOT ordinal:
>> groupsummary(patients, "Sex", @max, "AgeBand")
Error using groupsummary (line 335)
Unable to apply method 'fun1' to data variable AgeBand.
Caused by:
Error using categorical/max (line 77)
Relational comparisons are not allowed for categorical arrays that are not
ordinal.

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 12 Oct 2019
The reason the call is errorring, is at line 321 of the MATLAB's 'groupsummary' function:
  1. This line calculates the value to be used in the output for empty groups ('NaN' is one of the possible outcomes, but not the only one).
  2. This is only really needed if an explicit request for empty group is done by setting the 'IncludeEmptyGroups' option to 'true', which is 'false' by default.
  3. However, this value is computed nonetheless.
  4. Therefore we need to calculate this value by calling the function on an empty object of the same type as the data variable.
  5. The empty categorical we make is not ordinal, and therefore errors during the call to '@min'.
Points 3 and 5 are the true reason that trigger the error.
There are two possible workarounds: * Using a builtin method (e.g. 'max', ...), since this makes the value to be used for empty groups know ('NaN' or whatever, depending on the method).
  • Using 'splitapply'. With reference to this specific case, the following should suffice:
>> splitapply(bottom, patients(:, {'AgeBand'}), findgroups(patients.Sex))

More Answers (0)

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!