MATLAB Answers


Issues with for loop

Asked by Noah Wilson on 29 Jul 2019
Latest activity Commented on by Noah Wilson on 29 Jul 2019
I currently have this for loop in my code. Where RawDataMatrix is a 549x41 matrix.
for i = 1:length(RawDataMatrix(:,1))
if RawDataMatrix(i,35) > 10
RawDataMatrix(i,:) = [];
RawDataMatrix(:,35) = [];
I want this loop to go through each row and if the value of that row at column 35 is greater than 10 I want to delete the entire row from the matrix. Then after that I would like to delete the entire column 35 which is what that last line of code is for. I am currently getting this error code:
Index in position 1 exceeds array bounds (must not exceed 549).
Error in SEMMaster_DustIncluded_EdgeExcluded_withCuK_V1 (line 31)
if RawDataMatrix(i,35) > 10
I believe I am getting this error because in the workspace it says that i = 550 which I am not sure why. Thank you in advance if you can help me!


Sign in to comment.

1 Answer

Steven Lord
Answer by Steven Lord
on 29 Jul 2019
 Accepted Answer

MATLAB determines the upper limit of your for loop once, when the for loop starts. Changing what that expression will return (by deleting rows from your vector, for example) does not cause MATLAB to re-evaluate that expression each time through the loop.
As an aside, you shouldn't use length with a matrix. Use size and specify the dimension input to retrieve the size of the array in that dimension (dim = 1 for rows, dim = 2 for columns, dim = 3 for pages, etc.)
So you start off, say, with a matrix with 100 rows. When i = 3 you delete a row, so you now have a matrix with 99 rows. But your for loop is still going to count to 100, meaning at that last iteration you're going to ask for the 100th row of a 99 (or fewer) row matrix.
How can you avoid this problem? You could iterate your for loop backwards, starting with the last row and working your way to the front. You could create a vector indicating whether to keep or delete the row and use that after the loop has finished to perform the deletion.
Alternately you could skip the loop entirely. I'm going to create an example data matrix of size [10 7] whose elements are integer values between 1 and 20. I'm going to specify a seed value to make sure that this example demonstrates what I want it to demonstrate.
rng(1, 'twister')
rawDataMatrix = randi(20, 10, 7)
Now create a vector indicating where the third column of rawDataMatrix is greater than 10.
isGreaterThan10 = rawDataMatrix(:, 3) > 10
Now use that vector to delete the rows whose third column is greater than 10.
rawDataMatrix(isGreaterThan10, :) = []
You can do this without the intermediary variable if you want, but I wanted to show each step for clarity.
rng(1, 'twister')
rawDataMatrix = randi(20, 10, 7)
rawDataMatrix(rawDataMatrix(:, 3) > 10, :) = []

  1 Comment

Noah Wilson on 29 Jul 2019
That works phenomenally! Thank you

Sign in to comment.