Converting string to number in table with mixed values
1 view (last 30 days)
Show older comments
Hey, trying to replace a letter with a number in a table but having a lot of trouble with competing data types. I've tried some of the other answers (thanks!) but I can't get everything back into one table. I can get the letters to transform into a numbers, but then it isn't recognized by MATLAB as a number. In the end, I need the data to be in a table as numeric values to be compatible with other scripts I have written. Thanks in advance for you help.
data=table([1;2;3],{'C';'C';'H'},[0;0;0],[4.04;5.26;5.50],[3.4;2.72;2.18],[6.55;6.49;7.23], ...
'VariableNames',{'number','atom','charge','x','y','z'});
letters=table2array(data(:,2));
[lngth,wdth]=size(data);
conv=cell(lngth,1);
%
% for k=1:lngth
% conv(k)=strrep(letters(k),'C','6')
% conv(k)=strrep(letters(k),'H','1')
% conv(k)=strrep(letters(k),'B','5')
% conv(k)=strrep(letters(k),'S','16')
%
% end
for k=1:lngth
if strcmp(letters(k),'C');
conv(k)=6;
elseif strcmp(letters(k),'H');
conv(k)=1;
elseif strcmp(letters(k),'B');
conv(k)=5;
elseif strcmp(letters(k),'S');
conv(k)=16;
end
end
%place back into table
0 Comments
Accepted Answer
dpb
on 18 Nov 2017
Edited: dpb
on 18 Nov 2017
Use a lookup table; since it is the atomic table; build it for completeness(*) once in the app but for the specific case the example of how is--
>> table={'H';'B';'C';'S'}; elem=[1;5;6;16]; % build lookup table
>> [~,iloc]=ismember(data.atom,table); % get the right element location
>> data.atNum=elem(iloc); % add the atomic number variable
data =
number atom charge x y z atNum
______ ____ ______ ____ ____ ____ _____
1.00 'C' 0.00 4.04 3.40 6.55 6.00
2.00 'C' 0.00 5.26 2.72 6.49 6.00
3.00 'H' 0.00 5.50 2.18 7.23 1.00
>>
This would also be a good candidate for categorical variable where the display value is the letter character but the variable value is the ordinal value. See
doc categorical
for details. Would require rewriting the other scripts to use the datatype, but I'd guess could simplify enough to be worth it--plus the values in the table show up as just C, etc., rather than with the extra tick marks around the cellstr values. Plus, lookup and reference is generally much simpler than for string comparison.
(*) If you build the full table, then you don't need the ancillary numbers; it is simply the position within the table of the element.
ADDENDUM
There are many ways to write the lookup table and use it; one way that can use the above formulation without the need for the intermediate variable since ismember doesn't return location except in second optional output is
interp1(double(char(table)),elem,double(char(data.atom)))
that treats the cellstr as numeric. This is, essentially, emulating the categorical variable.
2 Comments
dpb
on 18 Nov 2017
No problem; just a note--the interp1 solution only works for 1-character element names, though...using categorical would keep the ability to do comparisons with equality operator and such other niceties without the messiness of cellstr operations.
More Answers (0)
See Also
Categories
Find more on Data Type Conversion in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!