replace numbers with letters in a vector or matrix

38 views (last 30 days)
optEnergyCost=[42 36 28.5 26 39.7 25 57047]
optEnergyCostString=sprintf('%g',optEnergyCost)
optEnergyCostString=strrep(optEnergyCostString,'42','Route_1');
optEnergyCostString=strrep(optEnergyCostString,'36','Route_1');
optEnergyCostString=strrep(optEnergyCostString,'28.5','Route_2');
optEnergyCostString=strrep(optEnergyCostString,'26','Route_2');
optEnergyCostString=strrep(optEnergyCostString,'39.7','Route_1');
optEnergyCostString=strrep(optEnergyCostString,'25','Route_1');
but results are
optEnergyCostString =
423628.52639.72557046.5
How do I correct this?

Accepted Answer

Geoff Hayes
Geoff Hayes on 15 Dec 2016
summyia - look at the dimensions of your res array
>> size(res)
ans =
1 8
So it is a single row array with eight columns (or characters since this is a char array). Now, when you look for those elements that are 2 (in your m), the
m == 2
will return a array with a one in the first and fourth position. You then try to insert the string 'worker1' into each of these elements. But remember - the res array is only characters long and you are trying to put the 'worker1' string (which is seven characters) into single character position. The reason that this works in the example is because they are inserting a single character ('z' for example) into any one position of the array. You could do the same here and use a single character to represent your strings, or you would have to use a cell array for res.
res = cell(size(m));
so that you can insert strings into the array. But you will not be able to use your code from above because you are trying to use the equality operator with floating point numbers and this is never recommended or guaranteed to work. I suggest that you loop through each element in your m array and then do a comparison as appropriate
for u=1:size(m,1)
for v=1:size(m,2) % assume 2D only
val = m(u,v);
valAsStr = num2str(val);
if ~isempty(strfind(valAsStr,'3'))
res{u,v} = 'worker4';
elseif val == 2
res{u,v} = 'worker1';
elseif abs(val - 2.5) < eps
res{u,v} = 'worker2';
elseif abs(val - 2.8) < eps
res{u,v} = 'worker3';
end
end
end
For the 2.5 and 2.8 comparisons, we look at the absolute difference between the value and the number we are comparing to. If that difference is less than a small number (our tolerance) then we consider them to be equal.
To check to see if a number contains the number three, we just convert it to a string and look (using strfind) for any occurrences of the '3' character.
  3 Comments
Image Analyst
Image Analyst on 16 Dec 2016
He gave a new example, unfortunately totally getting rid of the first one. In this example he uses the method I gave (with a small error) and uses strings and strrep().

Sign in to comment.

More Answers (4)

Image Analyst
Image Analyst on 15 Dec 2016
You need to convert it to a string, then use strrep():
m=[2 2.8 2.5 2 2.5 2.8 2.5 37243]
mString = sprintf('%g ', m)
mString = strrep(mString, '2 ', 'worker1 ');
mString = strrep(mString, '2.8 ', 'worker2 ');
mString = strrep(mString, '2.5 ', 'worker3 ')
You see in the command window:
mString =
2 2.8 2.5 2 2.5 2.8 2.5 37243
mString =
worker1 worker2 worker3 worker1 worker3 worker2 worker3 37243

the cyclist
the cyclist on 15 Dec 2016
The reason the code is not working is that the example was substituting individual characters, not longer strings.
This will work, if you can use a cell array to store the values.
m = [2 2.8 2.5 2 2.5 2.8 2.5 37243];
res = cell(size(m));
[unique_m, ~, idxFromUniqueBackToAll] = unique(m);
for i = 1:numel(unique_m)
res(idxFromUniqueBackToAll==i) = {['worker',sprintf('%d',i)]};
end
There are admittedly a lot of little tricks in there to make things work, so it might take you some time to fully understand what is happening in this code.

Image Analyst
Image Analyst on 16 Dec 2016
summiya:
With your new example, you didn't quite follow what I gave you in my answer before. You forgot to put spaces after the %g, after the numbers, and after the words that you want to replace the numbers with. Try doing that, like this:
optEnergyCost=[42 36 28.5 26 39.7 25 57047]
optEnergyCostString=sprintf('%g ',optEnergyCost)
optEnergyCostString=strrep(optEnergyCostString,'42 ','Route_1 ');
optEnergyCostString=strrep(optEnergyCostString,'36 ','Route_1 ');
optEnergyCostString=strrep(optEnergyCostString,'28.5 ','Route_2 ');
optEnergyCostString=strrep(optEnergyCostString,'26 ','Route_2 ');
optEnergyCostString=strrep(optEnergyCostString,'39.7 ','Route_1 ');
optEnergyCostString=strrep(optEnergyCostString,'25 ','Route_1 ');
The result is now:
optEnergyCostString =
Route_1 Route_1 Route_2 Route_2 Route_1 Route_1 57047
  4 Comments

Sign in to comment.


Andrei Bobrov
Andrei Bobrov on 15 Dec 2016
m=[2 2.8 2.5 2 2.5 2.8 2.5 37243]';
[~,~,c] = unique(m,'stable');
str = arrayfun(@(x)sprintf('worker%d',x),(1:4)','un',0);
out = num2cell(m);
t = m < 4;
out(t) = str(c(t));

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!