MATLAB Answers

How to sum a specific range of values in a column?

37 views (last 30 days)
Hello,
I'm trying to build a function that would read all the elements in a column matrix "a" then find the same value in column matrix "b" read the exact row and lastly sum all rows from exact row to exact row-30, and make it save all the answers in a new matrix.
This is what I have so far, but something is wrong.
function [psum, nsum] = datac (a, b, c)
lngth=length(a);
for i=1:lngth
eyear=a(i, 1);
row=find(b(:,1)==eyear);
row2=row-30;
psum(1,i)=sum(c(row2:row, 1) >0);
nsum(1,i)=sum(c(row2:row, 1) <0);
end
  1 Comment
Edmundas Povilavicius
Edmundas Povilavicius on 6 Nov 2016
With you suggestions, this is what I finally wrote:
Superset = datenum(datedif);
Subset = datenum(electiondates);
[isfound, daterows] = ismember(electiondates, datedif);
for i=1:numel(daterows)
if isfound(i)==0
Subset(i)=Subset(i)-1;
electiondates(i)=datestr(Subset(i));
[isfound(i),~] = ismember(electiondates(i), datedif);
if isfound(i)==0
Subset(i)=Subset(i)-1;
electiondates(i)=datestr(Subset(i));
end
end
end
[~, daterows] = ismember(electiondates, datedif);
for j = 1:numel(daterows)
sumdif = difrence(daterows(j) : daterows(j)+29);
psum(j) = sum(sumdif(sumdif> 0));
nsum(j) = sum(sumdif(sumdif< 0));
end
Any suggestions for improvement?

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 5 Nov 2016
A few notes first. 1) Avoid length, it's a dangerous function. Use numel or size with an explicit dimension. 2) There's no point indexing the singleton dimension with vectors, a(i) is simpler and clearer than a(i, 1) for vectors. 3) Use meaningful variable names.
Assuming that your election dates are stored as datenum or datetime (preferable), then:
%variables:
%electiondates: datenum or datetime vector
%datedif: datenum or datetime vector (or better column of a table)
%difrence: numeric vector (or better column of a table)
[~, daterows] = ismember(electiondates, datedif); %find location of each election date in datedif. Assumes all dates are found
positivesum = zeros(size(electiondates));
negativesum = zeros(size(electiondates));
for row = 1:numel(daterows))
summationdifrence = difrence(max(1, daterows(row)-29) : daterows(row)); %assume you want 30 elements (hence -29). makes sure you don't go before the first element with max
positivesum(row) = sum(summationdifrence(summationdifrence> 0));
negativesum(row) = sum(summationdifrence(summationdifrence< 0));
end
  2 Comments
Guillaume
Guillaume on 7 Nov 2016
Well, the simplest thing might be to adjust the electiondates vector to shift the date to friday if it's saturday or sunday.
Another approachis to change the creation of daterows to:
[isexact, daterows] = ismember(electiondates, datedif);
missingdates = electiondates(~isexact);
[isprevious, prevrows] = ismember(missingdates - 1, datedif);
[~, beforerows] = ismember(missingdates(~isprevious) - 1, datedif);
prevrows(~isprevious) = beforerows(~isprevious);
daterows(~isexact) = prevrows(~isexact);

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 5 Nov 2016
Edited: Image Analyst on 5 Nov 2016
It's not clear what you want. Can you supply some data and expected output. If you want to just sum in a sliding 30 row window, why don't you simply use conv()? And don't use data for your variable name since that is a built-in functions. And it's not clear why you're using cell arrays instead of simpler double arrays, and why you're putting all the results into the first element of psum instead of the i'th element.
  3 Comments
Edmundas Povilavicius
Edmundas Povilavicius on 5 Nov 2016
Thank you, however, I don't need to sum up every value because most of the data is useless and I need to skip it. I only need to sum up data 1 to 30 days before a specific date, i.e. election date.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!

Translated by