<?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 a moving sum/average depending on date in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/488888#M127501</link>
    <description>&lt;P&gt;See if this satisfies your needs:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
    infile datalines delimiter='    ';
    input customerid : 8.
        date : date9.
        opens : 3.
    ;
    format date yymmddd10.;
    datalines;
2123780 11APR2017   0
2123780 13APR2017   0
2123780 16APR2017   1
2123780 18APR2017   0
2123780 19APR2017   2
2123780 20APR2017   0
2123780 21APR2017   0
2123780 23APR2017   0
2123780 25APR2017   0
2123780 26APR2017   0
2123780 28APR2017   0
2123780 29APR2017   3
2123780 01MAY2017   3
2123780 03MAY2017   2
2123780 04MAY2017   5
2123780 05MAY2017   1
2123780 07MAY2017   2
2123780 09MAY2017   2
2123780 11MAY2017   3
2123780 13MAY2017   3
2123780 14MAY2017   0
2123780 16MAY2017   2
2123780 17MAY2017   2
;
run;

%let window=7;

data want;
set have;
by customerid;
array window {&amp;amp;window};
retain window:;
format lastdate yymmddd10.;
lastdate = lag(date);
if first.customerid
then do;
  do i = 1 to &amp;amp;window - 1;
    window{i} = 0;
  end;
  window{dim(window)} = opens;
  total = opens;
end;
else do;
  diff = date - lastdate;
  do i = 1 to dim(window) - diff;
    window{i} = window{i + diff};
  end;
  do i = dim(window) - diff + 1 to dim(window) - 1;
    window{i} = 0;
  end;
  window{dim(window)} = opens;
  total = sum(of window:);
end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;I intentionally did not drop anything, so you can see the evolution of the array.&lt;/P&gt;
&lt;P&gt;If you want to get more than one window, define additional arrays and implement the code for every array (with a separate totals variable).&lt;/P&gt;</description>
    <pubDate>Wed, 22 Aug 2018 14:05:55 GMT</pubDate>
    <dc:creator>Kurt_Bremser</dc:creator>
    <dc:date>2018-08-22T14:05:55Z</dc:date>
    <item>
      <title>Calculate a moving sum/average depending on date</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/488853#M127479</link>
      <description>&lt;DIV class="post-text"&gt;&lt;P&gt;My data has the following structure&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;data have;
    infile datalines delimiter='    ';
    input customerid : 8.
        date : date9.
        opens : 3.
    ;
    datalines;
2123780 11APR2017   0
2123780 13APR2017   0
2123780 16APR2017   1
2123780 18APR2017   0
2123780 19APR2017   2
2123780 20APR2017   0
2123780 21APR2017   0
2123780 23APR2017   0
2123780 25APR2017   0
2123780 26APR2017   0
2123780 28APR2017   0
2123780 29APR2017   3
2123780 01MAY2017   3
2123780 03MAY2017   2
2123780 04MAY2017   5
2123780 05MAY2017   1
2123780 07MAY2017   2
2123780 09MAY2017   2
2123780 11MAY2017   3
2123780 13MAY2017   3
2123780 14MAY2017   0
2123780 16MAY2017   2
2123780 17MAY2017   2
;
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;What I like to achieve is a moving total, average, sd, etc. for the &lt;CODE&gt;opens&lt;/CODE&gt; variable (and many more), which contain the values which fall within the last 7, 14, 30, etc. days PRIOR to the current observation, by &lt;CODE&gt;customerid&lt;/CODE&gt;. As you can see, the observations occur irregularly. Sometimes there are large gaps between, sometimes there are several on the same day. Therefore, I cannot use &lt;CODE&gt;PROC EXPAND&lt;/CODE&gt; (correct me if I'm wrong). Furthermore, I do not want to compress my date into e.g. one observation per week but keep them as they are.&lt;/P&gt;&lt;P&gt;The solution I came up with is an ugly piece of &lt;CODE&gt;LAG()&lt;/CODE&gt;-coding and if-clauses. An example for one variable and 7 days:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;%macro loop;

    data want(drop= lag_kdnr_num -- lag_mahnung min7 -- min365 minimum);
        set have;
        week_opens=0;

        %do i=1 %to 500;
            lag_customerID=lag&amp;amp;i.(customerID);
            date_7=lag&amp;amp;i.(date)+7;
            lag_opens=lag&amp;amp;i(opens);

            if ((customerID=lag_customerID) and (dsate &amp;lt; date_7)) then
                do;
                    week_opens=sum(week_opens + lag_opens);
                end;
        %end;

        min7=minimum + 7;

        if date &amp;lt; min7 then
            do;
                week_opens=.;
            end;
    run;

%MEND;

%loop;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;which is giving me this:&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;data want2;
    infile datalines delimiter='    ';
    input customerid : 8.
        date : date9.
        opens : 3.
        week_opens : 3.
    ;
    datalines;
2123780 11APR2017   0   .
2123780 13APR2017   0   .
2123780 16APR2017   1   .
2123780 18APR2017   0   1
2123780 19APR2017   2   1
2123780 20APR2017   0   3
2123780 21APR2017   0   3
2123780 23APR2017   0   2
2123780 25APR2017   0   2
2123780 26APR2017   0   0
2123780 28APR2017   0   0
2123780 29APR2017   3   0
2123780 01MAY2017   3   3
2123780 03MAY2017   2   6
2123780 04MAY2017   5   8
2123780 05MAY2017   1   13
2123780 07MAY2017   2   11
2123780 09MAY2017   2   10
2123780 11MAY2017   3   5
2123780 13MAY2017   3   7
2123780 14MAY2017   0   8
2123780 16MAY2017   2   6
2123780 17MAY2017   2   8
;
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Due to the huge amount of data, this is really slow and creates a lot of unused variables which I drop at the end. Is there a faster, more elegant way to get this result e.g. via a temporary array or SAS/ETS? Thank you in advance!&lt;/P&gt;&lt;P&gt;Final remark: I want to use this information as covariates in a survival analysis.&lt;/P&gt;&lt;/DIV&gt;</description>
      <pubDate>Wed, 22 Aug 2018 12:59:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/488853#M127479</guid>
      <dc:creator>mat_n</dc:creator>
      <dc:date>2018-08-22T12:59:53Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate a moving sum/average depending on date</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/488888#M127501</link>
      <description>&lt;P&gt;See if this satisfies your needs:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
    infile datalines delimiter='    ';
    input customerid : 8.
        date : date9.
        opens : 3.
    ;
    format date yymmddd10.;
    datalines;
2123780 11APR2017   0
2123780 13APR2017   0
2123780 16APR2017   1
2123780 18APR2017   0
2123780 19APR2017   2
2123780 20APR2017   0
2123780 21APR2017   0
2123780 23APR2017   0
2123780 25APR2017   0
2123780 26APR2017   0
2123780 28APR2017   0
2123780 29APR2017   3
2123780 01MAY2017   3
2123780 03MAY2017   2
2123780 04MAY2017   5
2123780 05MAY2017   1
2123780 07MAY2017   2
2123780 09MAY2017   2
2123780 11MAY2017   3
2123780 13MAY2017   3
2123780 14MAY2017   0
2123780 16MAY2017   2
2123780 17MAY2017   2
;
run;

%let window=7;

data want;
set have;
by customerid;
array window {&amp;amp;window};
retain window:;
format lastdate yymmddd10.;
lastdate = lag(date);
if first.customerid
then do;
  do i = 1 to &amp;amp;window - 1;
    window{i} = 0;
  end;
  window{dim(window)} = opens;
  total = opens;
end;
else do;
  diff = date - lastdate;
  do i = 1 to dim(window) - diff;
    window{i} = window{i + diff};
  end;
  do i = dim(window) - diff + 1 to dim(window) - 1;
    window{i} = 0;
  end;
  window{dim(window)} = opens;
  total = sum(of window:);
end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;I intentionally did not drop anything, so you can see the evolution of the array.&lt;/P&gt;
&lt;P&gt;If you want to get more than one window, define additional arrays and implement the code for every array (with a separate totals variable).&lt;/P&gt;</description>
      <pubDate>Wed, 22 Aug 2018 14:05:55 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/488888#M127501</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2018-08-22T14:05:55Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate a moving sum/average depending on date</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/488904#M127510</link>
      <description>Looks great! the only minor shortcomming is that I do not want to have the current value included, but it is easy to adjust for this. Thanks a lot and I will evaluate it in detail soon &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;</description>
      <pubDate>Wed, 22 Aug 2018 14:39:00 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/488904#M127510</guid>
      <dc:creator>mat_n</dc:creator>
      <dc:date>2018-08-22T14:39:00Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate a moving sum/average depending on date</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/489524#M127848</link>
      <description>&lt;P&gt;After I have checked your solution in more detail I noticed a problem which I did not highlight so far. Sometimes there are two or more observations on the same day. I can put them in the right order since I also do have a timestamp. Due to that, there are some 7-day-intervals which contain more than 7 observations. I would not like to sum them up since this would result in meaningless resluts for calcuations like standard deviation.&lt;/P&gt;&lt;P&gt;Is there any way to create a temporary array for each line which has as many elements as there are observations in the last 7 days and fill the array with these values?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I learned a lot from your first answer, so thank you again!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;data have;
    infile datalines delimiter='    ';
    input customerid : 8.
        date : date9.
        opens : 3.
    ;
    format date yymmddd10.;
    datalines;
2123780 11APR2017   0
2123780 13APR2017   0
2123780 16APR2017   1
2123780 18APR2017   0
2123780 19APR2017   2
2123780 20APR2017   0
2123780 21APR2017   0
2123780 23APR2017   0
2123780 25APR2017   0
2123780 26APR2017   0
2123780 28APR2017   0
2123780 29APR2017   3
2123780 01MAY2017   3
2123780 01MAY2017   2
2123780 04MAY2017   5
2123781 05MAY2017   1
2123781 07MAY2017   2
2123781 09MAY2017   2
2123781 11MAY2017   3
2123781 13MAY2017   3
2123781 14MAY2017   0
2123781 16MAY2017   2
2123781 17MAY2017   2
;
run;&lt;/PRE&gt;</description>
      <pubDate>Fri, 24 Aug 2018 08:50:21 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/489524#M127848</guid>
      <dc:creator>mat_n</dc:creator>
      <dc:date>2018-08-24T08:50:21Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate a moving sum/average depending on date</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/489525#M127849</link>
      <description>&lt;P&gt;Sum the data up first:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc sql;
create table int as
select customerid, date, sum(opens) as opens
from have
group by customerid, date;
quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;and use that as input for my previous code.&lt;/P&gt;</description>
      <pubDate>Fri, 24 Aug 2018 08:59:16 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/489525#M127849</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2018-08-24T08:59:16Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate a moving sum/average depending on date</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/489531#M127855</link>
      <description>&lt;P&gt;I guess your solution also contains a hint that there is no such way to use 'flexible' arrays. Thank you anyway!&lt;/P&gt;</description>
      <pubDate>Fri, 24 Aug 2018 09:43:04 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/489531#M127855</guid>
      <dc:creator>mat_n</dc:creator>
      <dc:date>2018-08-24T09:43:04Z</dc:date>
    </item>
    <item>
      <title>Re: Calculate a moving sum/average depending on date</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/489538#M127860</link>
      <description>&lt;P&gt;I'm quite sure there is a way to do it, but I wouldn't want to read the resulting code &lt;span class="lia-unicode-emoji" title=":winking_face:"&gt;😉&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;The sum by groups OTOH is very simple code. You can also do a sort and use proc summary to achieve the same state.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 24 Aug 2018 10:22:00 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculate-a-moving-sum-average-depending-on-date/m-p/489538#M127860</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2018-08-24T10:22:00Z</dc:date>
    </item>
  </channel>
</rss>

