Peter Perkins on 23 Mar 2018
Open in MATLAB Online
Calling categorical is a data conversion, so
c = categorical([12 12 13])
completely throws away the numeric values. In general, there is no way to get them back unless you have saved them, any more than you can get back the original values from int8([1.1 2.2 3.3]). Calling categorical is a data conversion.
That being said, you can certainly save the unique numeric values, and then index into those using the categorical array:
n = uniqueNumericValues(c)
You can also call double on a categorical, but what you will get back are the category numbers, not the original numeric values.
But here's the question: if you need to convert back to the original numbers, and you are not using meaningful category names when converting from those numbers, why use categorical to begin with? There may be things you haven't mentioned.
4 Comments Show 2 older commentsHide 2 older comments
Show 2 older commentsHide 2 older comments
Ian Blake on 4 Jun 2019
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/264383-convert-categorical-to-numeric#comment_711408
I have the same problem, and the help file.... does not help at all
My data is categorical because the importdata chose that for it, I can force but then if I import new data and don't force it to numerical, my processing will stop working. I'm running a script so I can put a conversion there -> automate not rely on human memory!
In particular I have 160,000 lines of data in a table, one of 46 fields is an odo reading. This has converted to categorical, with 16983 categories - so might be more efficient, fair enough. But now I want to plot data against odo, so I need numerical. example subset:
>> catdata
ans = 1×8 categorical array
37241 37364 37099 4264 6339 38209 38070 16777215
So the original numbers are NOT lost, but are coded in the categories:
>> catcats=categories(catdata);
>> length(catcats)
ans = 16983
As noted above, double () gives the index not the value
>> double(catdata)
ans =
10880 10902 10858 11593 13789 11022 11004 4659
>> catcats(4659)
ans = 1×1 cell array
{'16777215'}
But cell2mat gives you a string not a number:
>> cell2mat(catcats(4659))
ans = '16777215'
So you then need to convert again using str2num (why no cell2num? There is a num2cell):
>> str2num(cell2mat(catcats(4659)))
ans = 16777215
So this works for one item, but when I use the 8 element data with the resulting strings being different length, it fails
>> catcats(double(catdata))
ans = 8×1 cell array
{'37241' }
{'37364' }
{'37099' }
{'4264' }
{'6339' }
{'38209' }
{'38070' }
{'16777215'}
>> cell2mat(catcats(double(catdata)))
Error using cat
Dimensions of matrices being concatenated are not consistent.
Error in cell2mat (line 83)
m{n} = cat(1,c{:,n});
This seems like way more difficult than it should be.
Peter Perkins on 5 Jun 2019
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/264383-convert-categorical-to-numeric#comment_711778
The fundamental problem is that your numeric data are being read in as categorical. I don't have your file, so I can't tell why that is, but I recommend you use detectimportoptions, and set the type, and use that in calls to readtable to read in all of your other data.
Ian Blake on 10 Jun 2019
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/264383-convert-categorical-to-numeric#comment_713274
Edited: Ian Blake on 10 Jun 2019
Open in MATLAB Online
Thanks.
I've come to the conclusion that would have been easiest, although I've developed an effective though crude workaround.
vfdbdata.DD01km is my categorical data array (from a table of data)
odocats = categories (vfdbdata.DD01km);
odoval = zeros (1, length (odocats) ); % preallocate space
for kk=1:length(odocats),
odoval(kk)=str2num(cell2mat(odocats(kk)));
end
So this is run before the main processing, the numeric data can then be extracted as required by
odotemp = double ( vfdbdata.DD01km(vidx) ) ;
odotemp = odoval (max (1, odotemp) ) ;
The max ensures that 'undefined' values are processed without throwing an error (they give a NaN after translation to double, which causes a subscript error), I also have some code to process specific values that can occur (hence the use of a temporary variable).
Matthew Anderson on 13 Apr 2020
Direct link to this comment
https://www.mathworks.com/matlabcentral/answers/264383-convert-categorical-to-numeric#comment_826947
Open in MATLAB Online
a = categorical(["2" "3" "3"])
double(a) % returns [1 2 2] - maybe desired for some reason
double(string(a)) % returns [2 3 3] - maybe desired for some reason
categorical(double(string(a)) % returns the same thing as a
Sign in to comment.