replace numbers with letters in a vector or matrix

조회 수: 8 (최근 30일)
summyia qamar
summyia qamar 2016년 12월 15일
댓글: summyia qamar 2016년 12월 19일
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?

채택된 답변

Geoff Hayes
Geoff Hayes 2016년 12월 15일
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
Geoff Hayes
Geoff Hayes 2016년 12월 15일
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
Image Analyst 2016년 12월 16일
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().

댓글을 달려면 로그인하십시오.

추가 답변 (4개)

Image Analyst
Image Analyst 2016년 12월 15일
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 2016년 12월 15일
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 2016년 12월 16일
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
Image Analyst
Image Analyst 2016년 12월 17일
You should also learn that you can :
  1. use the debugger and you can hover over the variable and a popup message will show you the value of the variable, or
  2. you can type the value onto the command line to report the value to the command window, or
  3. you can look at the variable value in the workspace panel, or
  4. 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.
summyia qamar
summyia qamar 2016년 12월 19일
thanks

댓글을 달려면 로그인하십시오.


Andrei Bobrov
Andrei Bobrov 2016년 12월 15일
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));

카테고리

Help CenterFile Exchange에서 Whos에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by