<?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 Rolling Skewness with Moving Window in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Rolling-Skewness-with-Moving-Window/m-p/679918#M205371</link>
    <description>&lt;P&gt;I have 5000 daily time series (&lt;CODE&gt;var0001-var5000&lt;/CODE&gt;) from 01/01/2019 to 12/31/2019 and want to compute their rolling skewness each month. &lt;A href="https://communities.sas.com/t5/General-SAS-Programming/Moving-or-rolling-skewness/td-p/216172" target="_blank"&gt;This post&lt;/A&gt; introduces &lt;CODE&gt;proc summary&lt;/CODE&gt; for the rolling skewness.&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have(drop=i);
format t yymmddn6.;
array var(5000) var0001-var5000;
do t="1jan2019"d to "31dec2019"d;
do i=1 to 5000;
var(i)=rannor(1);
end;
output;
end;
run;

proc summary nway;
class t;
format t yymmn6.;
var var0001-var5000;
output out=want skew=;
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;So I can quickly compute the 5000 skewness in January, February, and so on. Now suppose I want to compute each monthly skewness using two—or &lt;EM&gt;N&lt;/EM&gt; more generally—consecutive months rather than just one month—for example, the February skewness using January and February data, the March skewness using February and March data, and so on. Can &lt;CODE&gt;proc summary&lt;/CODE&gt; do this?&lt;/P&gt;</description>
    <pubDate>Thu, 27 Aug 2020 23:13:13 GMT</pubDate>
    <dc:creator>Junyong</dc:creator>
    <dc:date>2020-08-27T23:13:13Z</dc:date>
    <item>
      <title>Rolling Skewness with Moving Window</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Rolling-Skewness-with-Moving-Window/m-p/679918#M205371</link>
      <description>&lt;P&gt;I have 5000 daily time series (&lt;CODE&gt;var0001-var5000&lt;/CODE&gt;) from 01/01/2019 to 12/31/2019 and want to compute their rolling skewness each month. &lt;A href="https://communities.sas.com/t5/General-SAS-Programming/Moving-or-rolling-skewness/td-p/216172" target="_blank"&gt;This post&lt;/A&gt; introduces &lt;CODE&gt;proc summary&lt;/CODE&gt; for the rolling skewness.&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have(drop=i);
format t yymmddn6.;
array var(5000) var0001-var5000;
do t="1jan2019"d to "31dec2019"d;
do i=1 to 5000;
var(i)=rannor(1);
end;
output;
end;
run;

proc summary nway;
class t;
format t yymmn6.;
var var0001-var5000;
output out=want skew=;
run;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;So I can quickly compute the 5000 skewness in January, February, and so on. Now suppose I want to compute each monthly skewness using two—or &lt;EM&gt;N&lt;/EM&gt; more generally—consecutive months rather than just one month—for example, the February skewness using January and February data, the March skewness using February and March data, and so on. Can &lt;CODE&gt;proc summary&lt;/CODE&gt; do this?&lt;/P&gt;</description>
      <pubDate>Thu, 27 Aug 2020 23:13:13 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Rolling-Skewness-with-Moving-Window/m-p/679918#M205371</guid>
      <dc:creator>Junyong</dc:creator>
      <dc:date>2020-08-27T23:13:13Z</dc:date>
    </item>
    <item>
      <title>Re: Rolling Skewness with Moving Window</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Rolling-Skewness-with-Moving-Window/m-p/679922#M205373</link>
      <description>&lt;P&gt;The only way to get proc summary to generate rolling window skewness (or rolling window anything) is to expand the original data set.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Let's say your rolling window sizes are 5.&amp;nbsp;&amp;nbsp; The you could make a data set sorted by the new variable WINDOW_ID, in sequences of 5 records.&amp;nbsp; So for window_id=1, you would have records 1-5, for window_id=2, you would have records 2-6, etc.&amp;nbsp; So that's a dataset 5 times your original dataset.&amp;nbsp; Imagine if you want window sizes of, say, 20 to 30.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;But in any case, you cuold then run the PROC SUMMARY with a BY WINDOW_ID statement.&amp;nbsp; I don't suggest this.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Editted note:&amp;nbsp; However, you might not use too many resources by making a data set VIEW instead of a dataset FILE.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Do you have SAS/ETS (econometrics times series)?&amp;nbsp; If so, then proc expand is what you want.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 28 Aug 2020 00:41:41 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Rolling-Skewness-with-Moving-Window/m-p/679922#M205373</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2020-08-28T00:41:41Z</dc:date>
    </item>
    <item>
      <title>Re: Rolling Skewness with Moving Window</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Rolling-Skewness-with-Moving-Window/m-p/679927#M205375</link>
      <description>&lt;P&gt;OK, I've thought some more about it.&amp;nbsp; Here's a solution that submits an expanded data set (data set view not data set file) to proc summary.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Test this out by using, say 10 or so variables&amp;nbsp; (%let NV=10).&amp;nbsp; Then you can examine results more closely.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let nv=5000;
%let nv=0010;
data have(drop=i);
  format t yymmddn8.;
  array var{&amp;amp;nv} var0001-var&amp;amp;nv;
  do t="1jan2019"d to "31dec2019"d;
    do i=1 to &amp;amp;nv;
      var(i)=rannor(1);
    end;
    output;
  end;
run;

%let win_size=5;
%let up_bound=%eval(&amp;amp;win_size-1);

data need (rename=(t=t_end) drop=_:)  / view=need ;
  retain window_id;
  format t_beg yymmddn8. ;
  set have;
  t_beg=lag&amp;amp;up_bound(t);

  array vars {&amp;amp;nv} var0001-var&amp;amp;nv ;
  array win_data{0:&amp;amp;up_bound,&amp;amp;nv} _temporary_;

  _row=mod(_n_,&amp;amp;win_size);
  do _v=1 to dim(vars);
    win_data{_row,_v}=vars{_v};
  end;

  if _n_&amp;gt;=&amp;amp;win_size;
  window_id+1;

  output ;   /* Output the current record */
  /* Now output the earlier window constituents */
  do _obs= _n_-1 to _n_-&amp;amp;up_bound by -1;
    _row=mod(_obs,&amp;amp;win_size);
	do _v=1 to dim(vars);
	  vars{_v}=win_data{_row,_v};
	end;
	output;
  end;
run;

proc summary data=need noprint ;
  by window_id t_beg t_end ;
  var var: ;
  output out=want  skew= / autoname;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The strategy above is to keep a 2-dimensional array with 5 rows (for winsize=5) and 5000 columns (number of variables.&amp;nbsp; Each incoming observation replaces the row of the array that is 5 observations old.&amp;nbsp; Also for each incoming observation calculate t_beg=lag4(t) - i.e. the starting date of the size 5 window.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then comes the output.&amp;nbsp; Once you have a full window, increment window_id by 1.&amp;nbsp; OUTPUT the record-in-hand.&amp;nbsp; Then for the prior 4 days, transcribe the corresponding row of the array to the original variables, and output.&amp;nbsp; You now have a dataset, sorted by WINDOW_ID (with associated variables T_BEG and T_END) with 5 records per id.&amp;nbsp; Note it doesn't matter if the observations within the window are in chronological order - you're calculating skewness, not some time-series statistic.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Then submit to PROC SUMMARY, with a BY WINDOW_ID T_BEG T_END; statement.&lt;/P&gt;</description>
      <pubDate>Fri, 28 Aug 2020 01:24:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Rolling-Skewness-with-Moving-Window/m-p/679927#M205375</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2020-08-28T01:24:08Z</dc:date>
    </item>
    <item>
      <title>Re: Rolling Skewness with Moving Window</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Rolling-Skewness-with-Moving-Window/m-p/679989#M205418</link>
      <description>&lt;P&gt;Using a data row in a rolling window computation means the data row needs to be replicated for association to each window it will be part of (i.e. partitions).&lt;/P&gt;
&lt;P&gt;A data row will thus need to be repeated with an appropriate window identifier that iterates from window (date) to window+N (of date). A month based window id from a date (your variable t) can be computed with INTCK('month',...)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Example:&lt;/P&gt;
&lt;P&gt;Using&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/31461"&gt;@mkeintz&lt;/a&gt;&amp;nbsp;data generator and summary.&lt;/P&gt;
&lt;PRE&gt;* generate some data;&lt;BR /&gt;&lt;BR /&gt;%let nv=5000;
*%let nv=0010;
data have(drop=i);
  format t yymmddn8.;
  array var{&amp;amp;nv} var0001-var&amp;amp;nv;
  do t="1jan2019"d to "31dec2019"d;
    do i=1 to &amp;amp;nv;
      var(i)=rannor(1);
    end;
    output;
  end;
  format var: 8.4;
run;
&lt;BR /&gt;* compute max month based window id;
proc sql noprint;
  select max(intck('month', '01jan1960'd, t)) 
  into :max_seqnum 
  from have;

%let MONTH_WINDOW = 2;

data stage(index=(seqdate));
  length seqnum 8;

  set have;
  by t;  * enforce requirement of data being sorted by t;

  * convert date to a month based sequence number (window id);
  seqnum = intck('month', '01jan1960'd, t); 

  * create replicates of row, associating data to N different month window partitions;
  do seqnum = seqnum to min(seqnum + &amp;amp;MONTH_WINDOW - 1, &amp;amp;MAX_SEQNUM);
    seqdate = intnx('month', '01jan1960'd, seqnum);  * first of month for later reporting;
    output;
  end;
  format seqdate monyy7.;
run;

proc summary data=stage;
  by seqdate;
  var var:;
  output out=want skew= / autoname;
run;&lt;/PRE&gt;
&lt;P&gt;Sample output:&lt;/P&gt;
&lt;P&gt;_FREQ_ is number of dates contributing to MONTH_WINDOW = 2 rolling month statistic (skew).&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="RichardADeVenezia_0-1598613674258.png" style="width: 400px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/48756i2A7466200593D02D/image-size/medium?v=v2&amp;amp;px=400" role="button" title="RichardADeVenezia_0-1598613674258.png" alt="RichardADeVenezia_0-1598613674258.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 28 Aug 2020 11:22:58 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Rolling-Skewness-with-Moving-Window/m-p/679989#M205418</guid>
      <dc:creator>RichardDeVen</dc:creator>
      <dc:date>2020-08-28T11:22:58Z</dc:date>
    </item>
  </channel>
</rss>

