find a value & store in new variable (again)

Dear Matlab friends,
We recently posted a question about finding values and storing them in new variables:
Our question remains in the sense that we would like to know how to procede when we have a matrix rathen than a cell array.
Indeed, we have a 384 x 14 matrix A, and we would like to find all occurrences of number [2] in column 1, and save corresponded value in column 2 in a new variable "new_variable":
A =
3 5 6 ...
2 3 5
2 3 4
1 4 5
5 7 9
...
so the result would be:
new_variable =
2
2
The suggestion for cell arrays was
new_variable = A{2}(A{1} == 2);
We thank you very much for any suggestion!
Best,
Udiubu

Answers (3)

Use logical indexing:
new_variable = A(A(:,1)==2, 2);
This indexes all those rows of A where column 1 is equal to 2, selects column 2 and assigns the result to new_variable.

13 Comments

Look at my answer it is same as yours
No, it isn't.
Please explain
Hey,
So let us understand where we are wrong here: the error we get is
??? undefined function or method 'eq' for input arguments of type 'cell'.
Our script imports a txt file with strings and numbers, converts all columns to cells so to be able to work on them and substitute numbers with strings, then creates a matrix A = [column1 column2 column3 ...]. Our last step is to be able to perform the action above: find a value & store in new variable.
Thanks thanks again for your precious help!
Best
Which is the correct answer. Please press 'Accept answer' that we know that's the question closed successfully
@Aldin: You used several lines and a loop, I used a one-line logical index. The result might be the same, but the solutions are not.
@Ubu: If you construct the matrix A from columns that are cells as you described, it will actually be a cell. If you want A to be a matrix, you need to then call A = cell2mat(A).
@Geoff: Yes, but Your code is not exactly clear for beginners in MATLAB.
The only problem with cell2mat is that I have different types of data - i.e. both strings and numbers. One radical solution would also be to remove those columns with strings. How would you remove them?
column removal
A(row,column) = []
@Ubu: Then you asked the wrong question. Your matrix is actually a cell. I'll answer separately so the code is formatted correctly. =)
@Aldin: Your profile states that you are "here to learn MatLab", yet if you indeed just learned something you don't seem to be very pleased.
Geoff that's so kind of you.. We'll be waiting!
@Geoff: How do you mean?

Sign in to comment.

Okay, since your matrix actually contains cells the equality operator doesn't work. I'll split the code up for extra clarity, since another reader insists ;-)
I'm still not sure if you want to replace column 2 with the value 2 or just copy the filtered column 2 into new_variable... The question was confusing. Anyway,
I would do this:
rowidx = cellfun( @(x) x==2, A(:,1) );
new_variable = cell2mat(A(rowidx,2));
cellfun maps a function over all elements of a cell-array or matrix. The '@(x) x==2' part is an anonymous (on-the-fly/adhoc) function. Here we use it on the first column. The output is a vector of booleans, which we then use as a logical index.
Edit:
The other way is to just extract the numeric columns that are of interest and use my other solution that works on matrices:
B = cell2mat(A(:,1:2));
new_variable = B( B(:,1)==2, 2);

6 Comments

Note: Edited. Needed a call to cell2mat() in the first code section. Added an alternative.
We wanted to copy the filtered column 2 into new_variable.
We'll try your code now..
So Geoff, your cellfun code works - we indeed have a vector of 0 and 1 corresponding to the right matching - but in new_variable only the first matched value has been reported. We just need to tell the script to report all of them. Any 'for' loop suggestion?
As for your second suggestion: the numeric columns have 'NaN' strings as well, and this causes the same problem as before.
Geoff we would love your last effort.
Possibly we found a solution:
rowidx = cellfun( @(x) x==2, A(:,1) );
new_var = A(rowidx(:,1) == 1, 14)
Now we'll gonna check it..
That's odd. Did you use my edited version of the first code segment? Using A{rowidx,2} was incorrect.
I assume your matrix is generally numeric (ie the numbers themselves are not strings), but those NaNs get in the way. You could try converting them to numbers too:
A{cellfun(@(x) strcmpi(x,'nan'), A)} = NaN;
A{cellfun(@(x) strcmpi(x,'nan'), A)} = NaN; right hand side has too few values to satisfy the left hand side.
However, we managed to delete those NaN, transform to mat and execute our mean and SD calculations.
It was a real pleasure to have you. You made a couple of guys very happy tonight.
We thank you very much Geoff!

Sign in to comment.

Here, try this code:
A = [ 2 1 3 2 4; 4 5 3 6 2; 2 3 5 3 6; 1 2 5 3 6; 3 2 5 2 5]
for i = 1:5
if A(i,1) == 2
A(i,2) = 2;
end
end

4 Comments

Hi Aldin,
Thanks for your answer.
However we do not really get what you mean by using '= 2' in
A(i,2) = 2;
Best
A(i,2) = 2; -----> "we would like to find all occurrences of number [2] in column 1, and save corresponded value in column 2 " (by Ubu).
It means to copy "2" in second column.
oooo i know what you want :)
A = [ 2 1 3 2 4; 4 5 3 6 2; 2 3 5 3 6; 1 2 5 3 6; 3 2 5 2 5];
counter = 0;
for i = 1:5
if A(i,1) == 2
counter = counter + 1;
new_variable(count) = A(i,2);
end
end
Have I solved your problem?

Sign in to comment.

Categories

Asked:

Ubu
on 19 Mar 2012

Community Treasure Hunt

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

Start Hunting!