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.