How do I delete cells in a column based on information from another column?
Show older comments
Hi,
I am working on data that I have extracted from an excel sheet. I have extracted the three columns that are necessary but need to do further work until I can use the data. Column three tells me if the data is valid hence I need to write the code that if any cells in column three equals 1 the correspoding cells in column 1 and 2 are equal to nan or 0. I then need that if column 1 equals to zero the corresponding cells in cloumn 2 equals to nan or 0. I then need to sum column 1 and average column 2. Below is the code I have tried. It runs but the output it gives is the sum and average of the columns before the if statements.
X = xlsread('filename.csv');
x = [X(:,2) X(:,3) X(:,9)];
if (x(:,3) == 1), x(:,1)= 0;
end
if (x(:,3) == 1), x(:,2)= 0;
end
if (x(:,1) == 0), x(:,2)= 0;
end
sum(x(:,1))
mean(x(:,2))
3 Comments
dpb
on 28 Feb 2020
"...the output it gives is the sum and average of the columns before the if statements."
Nope. The output is after the if constructs and looks just fine. The problem will be your input data didn't meet your expectations if would appear.
Couple possibilities...
- X data are floating point and the values are close to, but not precisely 1 so the test for equality fails. This probably isn't the case here, but is common enough as to mention it and it is at least possible from the information we have available to us
- There are other data in X that are NaN besides those that your filter has cleaned up so the result of the calculation is still NaN (which, while you don't say what the result returned was, the crystal ball is back from the shop (again!) and it says that's the symptom.
Try
sum(isnan(x))
after the above and report back...
Sonia Lenehan
on 28 Feb 2020
I guess will have to send the crystal ball back out for repair...it seems to still be murky! :)
That said, I'm pretty confident that you've not uncovered a bug in the ML sum() function so I'll assert the answer in ML is 5 and 9E5.
We'd have to see the input file to see what it is precisely that caused the differences.
I'll try the crystal ball one more time before declaring it broken (yet again)--
Does the input file have a header row, perchance? The difference between 3 and 5 is 2 and two headerlines would be a very common occurrence in a spreadsheet. There being some other value in one of those two lines that is also numeric in the second column is also certainly quite possible.
Accepted Answer
More Answers (1)
Pujitha Narra
on 2 Mar 2020
Edited: Pujitha Narra
on 2 Mar 2020
Hi,
According to the code above, the condition for the ‘if’ would return a column vector, but the ‘if’ requires the entire vetor to contain logical true values. This is causing the unexpected results.
Instead use the following code instead of the ‘if’ statements:
x(find(x(:,3)==1),1) =0;
x(find(x(:,3)==1),2) =0;
x(find(x(:,3)==0),2) =0;
5 Comments
Sonia Lenehan
on 2 Mar 2020
Guillaume
on 2 Mar 2020
Note that the find are completely unnecessary. The whole lot can be simplified to
x(x(:, 3) == 1, [1, 2]) = 0;
x(x(:, 1) == 0, 2) = 0;
"Is there anyway to write code so that column 2 only averages the correct times"
Whatever it is you're trying to do, it will be possible to do it. Most likely, it can be done in just one line in a much more efficient way that what you have now (with no need to replace any value). For us to figure it out, we would need an example file and a better explanation of what the data represent.
Also, what version of matlab are you using that you're still stuck with the deprecated xlsread?
Stephen23
on 2 Mar 2020
"...but the ‘if’ checks only the first element."
Not according to MATLAB'S if documentation, which states "An expression is true when its result is nonempty and contains only nonzero elements (logical or real numeric). Otherwise, the expression is false". It does not mention "first element" anywhere, and makes it clear that if takes into account all elements of the condition expression.
This is easy to confirm too:
>> if [1,0]; disp('only checks first element'); else disp('checks all elements'); end
checks all elements
Note that find is totally superfluous and should be removed: logical indexing is simpler and more efficient.
Pujitha Narra
on 2 Mar 2020
I agree with Guillaume and Stephen. 'if' tries to check if the entire vector has logical true values in this case, not just the first element (as wrongly mentioned previously)
Sonia Lenehan
on 2 Mar 2020
Edited: Sonia Lenehan
on 2 Mar 2020
Categories
Find more on Language Fundamentals in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!