replace numbers with letters in a vector or matrix
8 views (last 30 days)
Show older comments
summyia qamar
on 15 Dec 2016
Commented: summyia qamar
on 19 Dec 2016
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?
0 Comments
Accepted Answer
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
Geoff Hayes
on 15 Dec 2016
Summyia was basing the code off of an example that was a 4x7 numeric array. I figured that if their m could be something similar, then a 2D cell array could be used to hold the strings mapped from the numbers.
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().
More Answers (4)
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
0 Comments
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.
0 Comments
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
Image Analyst
on 17 Dec 2016
You should also learn that you can :
- use the debugger and you can hover over the variable and a popup message will show you the value of the variable, or
- you can type the value onto the command line to report the value to the command window, or
- you can look at the variable value in the workspace panel, or
- you can double click the variable name in the workspace panel to view the variable in the variable editor window.
So there are lots of ways you can see what the variable is other than just leaving off a semicolon to echo it to the command window.
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));
0 Comments
See Also
Categories
Find more on Whos in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!