Reputation: 43
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
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
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