Conditionally Flip Sign in Table

조회 수: 6 (최근 30일)
Federico Canè
Federico Canè 2014년 11월 4일
댓글: Federico Canè 2014년 11월 4일
I have a very simple question. Based on a matrix like this one:
A = [repmat({'Yes'},3,1) , repmat({'2'},3,1); repmat({'No'},3,1) , repmat({'2'},3,1)];
I want to flip the sign of column 2 if the entry in colum one is 'No', but leave it as is if the entry in colun one is 'Yes'.
The result should be the following:
B = [repmat({'Yes'},3,1) , repmat({'2'},3,1); repmat({'No'},3,1) , repmat({'-2'},3,1)];
I suppose I can do this using one line of code using cellfun, but I am not sure what is the most optimized way.
Thx for your help!

채택된 답변

Matt Tearle
Matt Tearle 2014년 11월 4일
편집: Matt Tearle 2014년 11월 4일
One liner:
A(strcmp(A(:,1),'No'),2) = strcat('-',A(strcmp(A(:,1),'No'),2))
Slightly cleaner with two lines:
idx = strcmp(A(:,1),'No');
A(idx,2) = strcat('-',A(idx,2))
But... if you're worrying about efficiency, I'd want to know if A has to be in the form it is. Does the second column have to text, rather than numeric?
And do you have 13b or later (or Statistics TB)? Because I think you might have an easier time using tables and categoricals. For example:
% Make a table version of A
Atable = cell2table(A,'VariableNames',{'YesOrNo','Number'})
% Convert strings to categories and string numbers to actual numbers
Atable.YesOrNo = categorical(Atable.YesOrNo)
Atable.Number = str2double(Atable.Number)
% Now, do the sign flipping
Atable.Number(Atable.YesOrNo == 'No') = -Atable.Number(Atable.YesOrNo == 'No')
  댓글 수: 6
Matt Tearle
Matt Tearle 2014년 11월 4일
Ah, right, now I see what you mean. If you want to keep them as strings, then you could do:
idx = strcmp(A(:,1),'No');
A(idx,2) = cellstr(num2str(-str2double(A(idx,2))))
But, again, I think you should really think about how you're storing the data, and whether it has to be that way. (I can't answer that without knowing more about your application.) If you could store it as two variables -- a cell array of strings and a numeric vector -- then this would be simpler and more efficient:
% separate out columns
YesOrNo = A(:,1)
numbers = str2double(A(:,2))
% flip signs
idx = strcmp(YesOrNo,'No')
numbers(idx) = -numbers(idx)
Federico Canè
Federico Canè 2014년 11월 4일
This works like a charm. Thx! :)

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

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Matrices and Arrays에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by