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

Respuestas (3)

Geoff
Geoff el 19 de Mzo. de 2012
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 comentarios

Aldin
Aldin el 19 de Mzo. de 2012
Look at my answer it is same as yours
Geoff
Geoff el 19 de Mzo. de 2012
No, it isn't.
Aldin
Aldin el 19 de Mzo. de 2012
How?
Aldin
Aldin el 19 de Mzo. de 2012
Please explain
Ubu
Ubu el 19 de Mzo. de 2012
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
Aldin
Aldin el 19 de Mzo. de 2012
Which is the correct answer. Please press 'Accept answer' that we know that's the question closed successfully
Geoff
Geoff el 19 de Mzo. de 2012
@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).
Aldin
Aldin el 19 de Mzo. de 2012
@Geoff: Yes, but Your code is not exactly clear for beginners in MATLAB.
Ubu
Ubu el 19 de Mzo. de 2012
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?
Ubu
Ubu el 19 de Mzo. de 2012
column removal
A(row,column) = []
Geoff
Geoff el 19 de Mzo. de 2012
@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.
Ubu
Ubu el 19 de Mzo. de 2012
Geoff that's so kind of you.. We'll be waiting!
Aldin
Aldin el 19 de Mzo. de 2012
@Geoff: How do you mean?

Iniciar sesión para comentar.

Geoff
Geoff el 19 de Mzo. de 2012
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 comentarios

Geoff
Geoff el 19 de Mzo. de 2012
Note: Edited. Needed a call to cell2mat() in the first code section. Added an alternative.
Ubu
Ubu el 19 de Mzo. de 2012
We wanted to copy the filtered column 2 into new_variable.
We'll try your code now..
Ubu
Ubu el 19 de Mzo. de 2012
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.
Ubu
Ubu el 19 de Mzo. de 2012
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..
Geoff
Geoff el 19 de Mzo. de 2012
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;
Ubu
Ubu el 19 de Mzo. de 2012
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!

Iniciar sesión para comentar.

Aldin
Aldin el 19 de Mzo. de 2012
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 comentarios

Ubu
Ubu el 19 de Mzo. de 2012
Hi Aldin,
Thanks for your answer.
However we do not really get what you mean by using '= 2' in
A(i,2) = 2;
Best
Aldin
Aldin el 19 de Mzo. de 2012
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.
Aldin
Aldin el 19 de Mzo. de 2012
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
Aldin
Aldin el 19 de Mzo. de 2012
Have I solved your problem?

Iniciar sesión para comentar.

Categorías

Más información sobre Data Type Identification en Centro de ayuda y File Exchange.

Etiquetas

Preguntada:

Ubu
el 19 de Mzo. de 2012

Community Treasure Hunt

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

Start Hunting!

Translated by