The doc at the link is addressing an array input which array can be one of the various types listed. It isn't describing a cell array. It appears, in fact, the documentation, while giving an example for a cell array of string values, doesn't address cell array inputs at all in the input description.
Hence, not sure it can be called a bug but appears to be a quality of implementation failure, for sure.
Looks like the workaround will be to either cast the logical to a numeric value before sorting or convert the cell array to a table and sortrows it--I'm guessing that would work.
I would submit a bug report, though...at least make TMW commit on what it is supposed to do.
ADDENDUM
Well, after the earlier comments, turns out we can go further and it can undoubtedly be made to work...the wrapper around the mex guts routines that do the bulk of the work is an m-file so can (at least thru R2014b here) see what's going on...in the end one gets to the following in the internal function sort_cell_back_to_front that is the one that errors.
if ~isempty(x)
for k = n:-1:1
if isnumeric(x{1, k})
...
tmp = cell2mat(x(ndx, k));
ind = sortrowsc(tmp, col(k));
ndx = ndx(ind);
else
tmp = char(x(ndx,k));
ind = sortrowsc(tmp, sign(col(k))*(1:size(tmp,2)));
ndx = ndx(ind);
end
end
and we see that since a LOGICAL is not numeric, it's going to be treated as string. Fixing up this test in a copy of sortrows might correct the issue. I'd suggest pasting this code snippet with the bug report.
ADDENDUM 2
I tried the simple expedient of
if isnumeric(x{1, k}) || islogical(x{1, k})
but it then errored on the subsequent cell2mat line with mixed types inside cell2mat. I don't have sufficient time at the moment to try to delve more deeply into the guts to work on a fixup, but that's where the issues are, anyways.
You can try to either patch this or use the workaround of making the type change or use table that may be more robust; not sure on that count. Well, let's just try and see...
>> res=table2cell(sortrows(cell2table(TCRes),-2));
>>
does seem to work ok. It didn't seem to take long for your dataset size to create the table and doing it as above makes it a temporary so doesn't clutter up workspace afterwards. The additional conversion back to cell didn't seem to take a reliably measurable additional amount of time over that without. If datasets got really large possibly...
The base case still deserves a bug report probably, but TMW may not treat it with great urgency...
ADDENDUM 3
I had a few minutes to look at this a little more--seemed puzzling that the above fixup failed on mixed metaphors so I dug into the dataset you supplied a little more...first try out of the box croaks--
>> tmp=cell2mat(TCRes(:,2));
Error using cell2mat (line 45)
All contents of the input cell array must be of the same data type.
>>
So, the error in the modified sortrows really isn't anything to do with it at all...
So, let's just look at the elements--
>> cellfun(@(x) x,TCRes(:,2));
Error using cellfun
Mismatch in type of outputs, at index 16, output 1 (logical versus double).
Set 'UniformOutput' to false.
>>
Your data are corrupt; the 16th value is a double instead of logical, how many more?
>> sum(cellfun(@islogical,arrayfun(@(x) x,TCRes(:,2))))
ans =
554
>>
so there are 16 bad apples in the barrel. Fixing those and the above code change likely will then work.
IN FINE
>> idx=find(cellfun(@isnumeric,arrayfun(@(x) x,TCRes(:,2))))'
idx =
16 54 92 130 168 206 244 282 320 358 396 434 472 510 548 552
>> diff(idx)
ans =
38 38 38 38 38 38 38 38 38 38 38 38 38 38 4
>>
It looks like whatever logic you used to build the array has some regularity in setting values and every 38th after the 16th plus the last is a double instead of logical. This is a bug in your code logic that needs fixing.
With that and the change to sortrows noted above, then the "classic" sortrows works on your cell array.
>> for i=1:length(idx),TCPRes(idx(i),2)={logical(TCPRes{idx(i),2})};end
>> out=sortrows(TCPRes,-2);
>>
after the aforementioned code change. I made local copy to alias the original for the test; I'd recommend if you choose to go this route to make a copy of the original and name it something else.
Best Answer