<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Calculate sum of the specific number of row before and after each row ( sum of 250 lags in SAS) in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/852997#M337179</link>
    <description>&lt;P&gt;This should work, (EDIT:but only for the first part of your task):&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
   set have;
   
   length lag_sum v0 - v249 8;
   retain v0 - v249;
   array lags[0:249] v0 - v249;
   
   if _n_ &amp;gt; dim(lags) then do;
      lag_sum = sum(of lags[*]);
   end;
  
   lags[mod(_n_ - 1, dim(lags))] = value;
   
   drop v0 - v249;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Tue, 10 Jan 2023 07:08:23 GMT</pubDate>
    <dc:creator>andreas_lds</dc:creator>
    <dc:date>2023-01-10T07:08:23Z</dc:date>
    <item>
      <title>Calculate sum of the specific number of row before and after each row ( sum of 250 lags in SAS)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/852971#M337167</link>
      <description>&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="John178_0-1673310970637.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/79206iD85C631D45567B20/image-size/medium?v=v2&amp;amp;px=400" role="button" title="John178_0-1673310970637.png" alt="John178_0-1673310970637.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;DIV class=""&gt;&amp;nbsp;&lt;/DIV&gt;&lt;P&gt;I have&amp;nbsp; data&amp;nbsp; like this one&lt;/P&gt;&lt;P&gt;Calculate sum of 250 lags in SAS.&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;I want to do sum of 250 previous rows for each row, starting from the row 250th.&lt;/P&gt;&lt;P&gt;X= lag1(VWRETD)+ lag2(VWRETD)+ ... +lag250(VWRETD)&lt;/P&gt;&lt;P&gt;or X = sum ( lag1(VWRETD), lag2(VWRETD), ... ,lag250(VWRETD) )&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I also want to calculate sum of 250 next rows after each row.&lt;/P&gt;&lt;P&gt;I try to use lag function but it does not work for too many lags;&lt;/P&gt;&lt;P&gt;thank you for your help!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 10 Jan 2023 00:46:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/852971#M337167</guid>
      <dc:creator>John178</dc:creator>
      <dc:date>2023-01-10T00:46:48Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate sum of the specific number of row before and after each row ( sum of 250 lags in SAS)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/852984#M337174</link>
      <description>&lt;P&gt;There are a lot of devils and a lot of details.&amp;nbsp; For example, I would assume you mean starting with the 251st observation, not starting with the 250th observation.&amp;nbsp; Otherwise there can't be 250 previous values to sum.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here's an approach that takes a long time to run.&amp;nbsp; It has to execute 500 SET statements for every observation.&amp;nbsp; I imagine this is time-consuming, but you can always try it and see.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then there are details about cutting off the end of the data set once you have fewer than 250 "post" observations left to sum.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;At any rate, I have some ideas in mind to cut down on the run time.&amp;nbsp; So if the problem is not solved by tomorrow I will revisit it and share more.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;Here is one basic (long-running) approach:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
   set have nobs=totalobs;
   if 251 &amp;lt;= _n_ &amp;lt;= totalobs - 250;
   prior250 = 0;
   do obsno = _n_ - 250 to _n_ - 1;
      set have (keep=vwretd rename=(vwretd=prior_value)) point=obsno;
      prior250 + prior_value;
   end;
   post250 = 0;
   do obsno = _n_ + 1 to _n_ + 250;
      set have (keep=vwretd rename=(vwretd=post_value)) point=obsno;
      post250 + post_value;
   end;
   drop prior_value post_value obsno;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Tue, 10 Jan 2023 03:20:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/852984#M337174</guid>
      <dc:creator>Astounding</dc:creator>
      <dc:date>2023-01-10T03:20:08Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate sum of the specific number of row before and after each row ( sum of 250 lags in SAS)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/852988#M337175</link>
      <description>&lt;P&gt;Here is an example using &lt;STRONG&gt;proc expand&lt;/STRONG&gt; with 5 lags&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have(drop=i);
call streaminit(86589);
do i = 1 to 25;
    x = rand("uniform");
    output;
    end;
run;

proc expand data=have out=want(drop=TIME);
convert x=x_sum5 / transformout = (movsum 5 trimleft 4);
convert x=x_rev5 / transformout = (reverse movsum 5 reverse trimright 4);
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PGStats_0-1673322140220.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/79211iD689CA05055BC0AA/image-size/medium?v=v2&amp;amp;px=400" role="button" title="PGStats_0-1673322140220.png" alt="PGStats_0-1673322140220.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;proc expand is part of SAS/ETS, SAS econometrics and time series procedures.&lt;/P&gt;</description>
      <pubDate>Tue, 10 Jan 2023 03:44:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/852988#M337175</guid>
      <dc:creator>PGStats</dc:creator>
      <dc:date>2023-01-10T03:44:46Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate sum of the specific number of row before and after each row ( sum of 250 lags in SAS)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/852997#M337179</link>
      <description>&lt;P&gt;This should work, (EDIT:but only for the first part of your task):&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
   set have;
   
   length lag_sum v0 - v249 8;
   retain v0 - v249;
   array lags[0:249] v0 - v249;
   
   if _n_ &amp;gt; dim(lags) then do;
      lag_sum = sum(of lags[*]);
   end;
  
   lags[mod(_n_ - 1, dim(lags))] = value;
   
   drop v0 - v249;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 10 Jan 2023 07:08:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/852997#M337179</guid>
      <dc:creator>andreas_lds</dc:creator>
      <dc:date>2023-01-10T07:08:23Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate sum of the specific number of row before and after each row ( sum of 250 lags in SAS)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853000#M337180</link>
      <description>&lt;P&gt;Create a temporary array with 250 elements.&lt;/P&gt;
&lt;P&gt;Use mod(_n_,250) to determine which element to set.&lt;/P&gt;
&lt;P&gt;Once _n_ is larger than 250, use&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;sum(of array{*})&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;to do the calculation.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;For code, provide usable example data in a data step with datalines.&lt;/P&gt;</description>
      <pubDate>Tue, 10 Jan 2023 07:24:41 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853000#M337180</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2023-01-10T07:24:41Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate sum of the specific number of row before and after each row ( sum of 250 lags in SAS)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853080#M337205</link>
      <description>&lt;P&gt;As others have mentioned, you can set up an array to track the prior 250 values.&amp;nbsp; That's probably the fastest way (don't know about the ETS solution).&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here's a way to address the subsequent 250 values, using common tools.&amp;nbsp; It can be combined with a solution for the previous 250 values, but that would get kind of messy to present in the same DATA step.&amp;nbsp; So I leave to you the combination of prior and post.&amp;nbsp; Anyway, here's the way to get the post-250 sum.&amp;nbsp; It won't be that fast, but it won't be superslow either (like my original post was).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
   pre250 = 0;
   post250 = 0;&lt;BR /&gt;   retain pre250 post250;
   if _n_=1 then do until (done);
      set have (firstobs=251 obs=500 keep=vwretd) end=done;
      post250 + vwretd;
   end;
   set have nobs = totalobs;
   pre250 + vwretd;  /* for clarity and focus, omit logic for calculating */ 
            /* previous 250 sum but it could be re-inserted here */
   if _n_ &amp;gt;= 251 and _n_ &amp;lt;= totalobs - 250 then do;
      post250 = post250 - vwretd;
      obsno = _n_ + 250;
      set have point=obsno (keep=vwretd rename = (vwretd = increment) );
      post250 = post250 + increment;
   end;
run;
      &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;It needs to execute a SET statement to get the value 251 observations down the road, and use it to replace the current value of VWRETD.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It's untested code since you have the data and we don't.&amp;nbsp; But it looks like it should work.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Good luck.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This solution WILL ALSO BE REVISED to make it run faster by eliminating point= ... as soon as I have the time to devote to it.&amp;nbsp; Definitely can be done.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In retrospect, the posted solution from&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/76464"&gt;@s_lassen&lt;/a&gt;&amp;nbsp;is close enough to the revision I would have made.&amp;nbsp; So no more updates coming from me.&lt;/P&gt;</description>
      <pubDate>Wed, 11 Jan 2023 18:55:47 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853080#M337205</guid>
      <dc:creator>Astounding</dc:creator>
      <dc:date>2023-01-11T18:55:47Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate sum of the specific number of row before and after each row ( sum of 250 lags in SAS)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853092#M337213</link>
      <description>&lt;P&gt;You do not need to call LAG() 250 times.&lt;/P&gt;
&lt;P&gt;Just build a running total and subtract the value that is being bumped off the back.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
   set have;
   running_sum + VWRETD- sum(0,lag250(VWRETD));
   if _n_ &amp;gt;= 250 then x=running_sum;
run;   &lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;To calculate for the following 250 values just sort the data in descending order and to the same thing.&lt;/P&gt;</description>
      <pubDate>Tue, 10 Jan 2023 16:36:38 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853092#M337213</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2023-01-10T16:36:38Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate sum of the specific number of row before and after each row ( sum of 250 lags in SAS)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853172#M337234</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159"&gt;@Tom&lt;/a&gt;&amp;nbsp;of course you are right for the previous 250.&amp;nbsp; Last time I read the documentation, LAG was limited to LAG100, and LAG250 was not possible.&amp;nbsp; At any rate, getting the subsequent 250 values is going to be the difficult part.&amp;nbsp; Even after two tries, I will need to revise my last solution for that to eliminate point=.&lt;/P&gt;</description>
      <pubDate>Tue, 10 Jan 2023 21:35:36 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853172#M337234</guid>
      <dc:creator>Astounding</dc:creator>
      <dc:date>2023-01-10T21:35:36Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate sum of the specific number of row before and after each row ( sum of 250 lags in SAS)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853287#M337250</link>
      <description>&lt;P&gt;Here is a solution based on the post by&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/15475"&gt;@andreas_lds&lt;/a&gt;&amp;nbsp;, but expanded to include the look-ahead sums as well:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want;
  array next_val (0:249) 8 _temporary_;
  array prev_val (0:249) 8 _temporary_;
  if _N_=1 then do k=1 to 249 while (not done);
    set have end=done;
    next_val(k)=vwretd;
    end;
  if _N_&amp;lt;=nobs-249 then do;
    set have(keep=vwretd firstobs=250);
    next_val(mod(_N_-1,250))=vwretd;
    next_sum=sum(of next_val(*));
    end;
  set have nobs=nobs;
  prev_val(mod(_N_,250))=vwretd;
  if _N_&amp;gt;=250 then
    prev_sum=sum(of prev_val(*));
  drop k;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The solution is made on the assumption that you want the current observation included in both the look-ahead and the look-behind, otherwise you will have to adjust.&lt;/P&gt;</description>
      <pubDate>Wed, 11 Jan 2023 16:32:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853287#M337250</guid>
      <dc:creator>s_lassen</dc:creator>
      <dc:date>2023-01-11T16:32:54Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate sum of the specific number of row before and after each row ( sum of 250 lags in SAS)</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853384#M337301</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159"&gt;@Tom&lt;/a&gt;'s&amp;nbsp;solution structure is the most appropriate for this problem.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;My question is this.&amp;nbsp; You are using variable VWRETD, suggesting to me that you are using CRSP data, in particular value-weighted returns with dividends.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Your stated request is for a rolling 250-period &lt;U&gt;&lt;EM&gt;&lt;STRONG&gt;sum&lt;/STRONG&gt;&lt;/EM&gt;&lt;/U&gt; of VWRETD, with each rolling window ending at the immediately preceding observation.&amp;nbsp; But instead of the sum, do you actually want the 250-period &lt;EM&gt;&lt;STRONG&gt;compounded return&lt;/STRONG&gt;&lt;/EM&gt;?&amp;nbsp; If so, then you really want to add the &lt;EM&gt;&lt;STRONG&gt;logs&lt;/STRONG&gt;&lt;/EM&gt; of VWRETD+1 and then take the antilog (and subtract 1) to get the compound return.&amp;nbsp; That would look like the below:&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data want (drop=_:);
  set have;
  retain _roll_sum_log_ret_plus1 0;

  rolling_preceding_250_return = exp(_roll_sum_log_ret_plus1)-1;

  _roll_sum_log_ret_plus1 = _roll_sum_log_ret_plus1 + log(1+vwretd) -1*sum(0,log(lag250(1+vwretd)));

  if _n&amp;gt;250 ;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Note that the sum of the logs is updated &lt;EM&gt;&lt;STRONG&gt;after&lt;/STRONG&gt;&lt;/EM&gt; the compound return is calculated.&amp;nbsp; This means the calculated compound return does not include the current observation.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;There can be a problem with this technique.&amp;nbsp; This program, like&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/159"&gt;@Tom&lt;/a&gt;'s, constantly updates a rolling total, which means any numeric precision issues, once encountered, can be preserved in subsequent rolling windows, even non-overlapping windows.&amp;nbsp; Solutions that sum arrays of 250 do not have that property.&amp;nbsp; But this solution is much faster, and I doubt that the CRSP data is so pathological as to cause more than a minor difference in results.&amp;nbsp; &amp;nbsp;You can test this assertion by running the data step on your entire dataset, and then only using the last 251 (at least) observations in the dataset.&amp;nbsp; Compare results for corresponding dates.&amp;nbsp; Note this is NOT a SAS problem - it is a numeric precision problem shared by all digital computers.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Editted note:&amp;nbsp;&amp;nbsp;I forgot that you also want the next 250 observations.&amp;nbsp; I.e. for observation 251, you want the compounded return for obs 1 through 250, and also the compounded return for obs 252 through 501.&amp;nbsp; Here's a program that does so:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;
data want (drop=_:);
  if 0 then set have nobs=nperiods ;

  merge have  have (firstobs=252 keep=vwretd rename=(vwretd=_wretd));

  retain _roll_sum_log_ret_plus1 _roll_nxt_log_ret_plus1 0;

  rolling_preceding_250_return = exp(_roll_sum_log_ret_plus1) - 1;
  rolling_following_250_return = exp(_roll_nxt_log_ret_plus1) - 1;

  _roll_sum_log_ret_plus1 = _roll_sum_log_ret_plus1 + log(1+vwretd) -1*sum(0,log(lag250(1+vwretd)));
  _roll_nxt_log_ret_plus1 = _roll_nxt_log_ret_plus1 + log(1+_wretd) -1*sum(0,log(lag250(1+_wretd)));

  if 250&amp;lt; _n_ &amp;lt; nperiods-250;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;This produces results only for those dates that have both a complete window for the preceding 250 observations (i.e. _N_&amp;gt;250) and a complete window for the following 250 observations (_N_ &amp;lt; nperiods-250).&amp;nbsp;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 12 Jan 2023 03:18:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-sum-of-the-specific-number-of-row-before-and-after/m-p/853384#M337301</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2023-01-12T03:18:16Z</dc:date>
    </item>
  </channel>
</rss>

