Astrid
Astrid

Reputation: 43

convert different chars to number in matlab

Please help me with the following problem:

In matlab, I have an Nx3 char variable, where N can vary depending on the input. Let's say N = 5 and I have the following variable A (5x3 char):

A = [' 1M';
     ' 5D';
     '10Y';
     '15W';
     '20Y']

A is always Nx3, and can take only 'D', 'W', 'M', 'Y', so no microseconds.
Is there a way to define a new variable B having as values the numbers in variable A, expressed in years, i.e. B=[1/12; 5/365; 10; 15/52; 20]?

What I tried so far and didn't work (example for M):

outc = mat2cell(A, ones(size(A,1),1), size(A,2));
for k = 1:length(outc) 
    if  outc{k} = '\w*M' 
        outc{k} = strrep(outc, 'M', '');
        outc2(k) = cellfun(@str2num, outc);
        outc2(k) = outc2(k)./12;
    end
end

Thank you for your help!

Upvotes: 1

Views: 92

Answers (2)

Luis Mendo
Luis Mendo

Reputation: 112699

Here's an approach similar to @rayryeng's, but using a regular expression (regexprep) instead of a map:

B = mat2cell(A, ones(size(A,1),1)); %// convert each line to a cell
B = regexprep(B, {'Y' 'M' 'W' 'D' }, {'' '/12' '/52' '/365'}); %// replace letters
B = cellfun(@str2num, B); %// convert from strings to numbers

For

A = [' 1M';
     ' 5D';
     '10Y';
     '15W';
     '20Y'];

this gives

B =
    0.0833
    0.0137
   10.0000
    0.2885
   20.0000

Upvotes: 2

rayryeng
rayryeng

Reputation: 104515

What you can do is set up a lookup table that maps characters to numbers. In your case, you'd have a lookup table that maps 'D' to 365, 'W' to 52, 'M' to 12 and 'Y' to 1. You can easily do that with a containers.Map. Specifically, you would to this to set it up:

map = containers.Map({'D', 'W', 'M', 'Y'}, {365, 52, 12, 1});

This maps each of the characters to each number that we talked about. Next, referencing your previous post, you'd convert each row of your character matrix to a cell array. However, I would also trim out any whitespace via strtrim so that our analysis is easier:

B = mat2cell(A, ones(size(A,1),1));
B = strtrim(B); %// Trim out whitespace

Now, all you have to do is go through each cell, convert all of the characters before the last one into a number, then use the last character and reference our lookup table to spit out the right number:

out = cellfun(@(x) str2num(x(1:end-1)) / map(x(end)), B);

We get:

out =

    0.0833
    0.0137
   10.0000
    0.2885
   20.0000

Compare this with the actual numbers in fractional form before converting to floating point:

>> out2 = [1/12, 5/365, 10, 15/52, 20]

out2 =

    0.0833    0.0137   10.0000    0.2885   20.0000

Looks good to me!


For copying and pasting:

A = [' 1M';
     ' 5D';
     '10Y';
     '15W';
     '20Y'];
map = containers.Map({'D', 'W', 'M', 'Y'}, {365, 52, 12, 1});
B = mat2cell(A, ones(size(A,1),1));
B = strtrim(B); %// Trim out whitespace
out = cellfun(@(x) str2num(x(1:end-1)) / map(x(end)), B);

Upvotes: 3

Related Questions