Skip to content

Instantly share code, notes, and snippets.

@edwinhu
Last active August 29, 2015 13:56
Show Gist options
  • Save edwinhu/8942401 to your computer and use it in GitHub Desktop.
Save edwinhu/8942401 to your computer and use it in GitHub Desktop.
Macro to [Helmert transform](http://en.wikipedia.org/wiki/Helmert_transformation) (forward mean-difference) panel data
/*******************READ ME*********************************************
* - Macro to Helmert transform (forward mean-difference) panel data -
*
* SAS VERSION: 9.4.0
* DATE: 2013-05-05
* AUTHOR: eddyhu at the gmails
*
****************END OF READ ME******************************************/
%macro HELMERT(dsetin = &syslast.,
dsetout = ,
byvar = none,
vars = ,
lag = yes
);
/*****************************************************************
* MACRO: HELMERT()
* GOAL: Macro to Helmert transform (forward mean-difference) panel data
* PARAMETERS: libname = SAS library (default USER)
* dsetin = input dataset containing variables to helmert transform
* dsetout = output dataset (leave blank to overwrite DSETIN)
* byvar = variable(s) used to form groups (leave blank for total sample)
* vars = variable(s) that will be helmert transformed
* pass = Postgre user password
* db = Postgre database
* format = DATA step format statement (optional)
* rename = DATA step rename statement (optional)
* debug = if y then send BULKLOAD trace info to SAS log
* useful for figuring out if you have badly formatted
* columns, and if so what specific row is being rejected
*
* DESCRIPTION: This macro takes the input variables and performs the Helmert transform.
* The Helmert transform is a forward mean-differencing transformation, in
* this case normalized and computed based on the BYVAR macro variables
*****************************************************************/
%if &dsetout = %then %let dsetout = &dsetin;
%let xn=1;
%let h_vars = ;
%let x_vars = ;
%let z_vars = ;
/* Forward sum */
proc expand data=&dsetin out=xtemp;
by &byvar;
%do %until (%scan(&vars,&xn)= );
%let token = %scan(&vars,&xn);
%let h_vars = &h_vars h_&token;
convert &token = h_&token / transform = (reverse sum reverse lead 1);
%let xn = %EVAL(&xn + 1);
%end;
/* Count number of elements in sum */
proc expand data=xtemp out=xtemp2;
by &byvar;
convert TIME = N / transform = (reverse);
%let xn=1;
/* Forward mean difference and weighting */
data &dsetout;
retain &byvar &vars &h_vars;
set xtemp2;
by permno;
%do %until (%scan(&vars,&xn)= );
%let token = %scan(&vars,&xn);
h_&token = (&token-h_&token/N)*(N/(N+1))**.5;
%let xn = %EVAL(&xn + 1);
%end;
drop TIME N;
run;
%if &lag = Yes | &lag = yes | &lag = Y | &lag = y %then %do;
%let xn=1;
/* Lags */
proc expand data=&dsetout out=&dsetout;
by &byvar;
%do %until (%scan(&vars,&xn)= );
%let token = %scan(&vars,&xn);
%let x_vars = &x_vars x_&token;
%let z_vars = &z_vars z_&token;
convert h_&token = x_&token / transform = (lag 1);
convert &token = z_&token / transform = (lag 1);
%let xn = %EVAL(&xn + 1);
%end;
data &dsetout;
retain &byvar &vars &h_vars &x_vars &z_vars;
set &dsetout;
drop TIME;
run;
%end;
/*Delete temporary datasets created during macro execution*/
proc datasets library=work nolist;
delete xtemp xtemp2; quit; run;
%mend;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment