replace numbers with letters in a vector or matrix
조회 수: 8 (최근 30일)
이전 댓글 표시
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
채택된 답변
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
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
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
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
댓글 수: 0
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.
댓글 수: 0
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
2016년 12월 17일
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
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));
댓글 수: 0
참고 항목
카테고리
Help Center 및 File Exchange에서 Whos에 대해 자세히 알아보기
제품
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!