Skip to content

Instantly share code, notes, and snippets.

@daynebatten
Last active August 29, 2015 14:19
Show Gist options
  • Select an option

  • Save daynebatten/4077f4b3b225c19b1226 to your computer and use it in GitHub Desktop.

Select an option

Save daynebatten/4077f4b3b225c19b1226 to your computer and use it in GitHub Desktop.
/* target_data is the data set you want to suppress
target_var is the variable you want to suppress
dimensions is a pipe-separated list of dimensions to suppress
cutoff is the highest value you want to suppress */
%macro suppress(target_data, target_var, dimensions, cutoff);
/* Count the number of dimensions we're working with */
%let num_dims = %eval(%sysfunc(count(&dimensions, |)) + 1);
/* Build a macro variable array with the dimension names */
%do i = 1 %to &num_dims;
%let dim&i = %sysfunc(scan(&dimensions, &i, |));
%end;
/* Primary suppression - Suppress anything less than or equal to our cutoff */
data &target_data;
set &target_data;
if &target_var <= &cutoff then &target_var = .;
run;
/* Keep looping through secondary suppression until nothing is changing
Keep track of iterations for kicks and giggles */
%let changed = 1;
%let iterations = 0;
%do %while (&changed = 1);
%let changed = 0;
%let iterations = %eval(&iterations + 1);
/* Loop through all of our dimensions and suppress across them */
%do i = 1 %to &num_dims;
/* Get a list of dimensions to sort by (i.e., all dimensions except the one we're suppressing across) */
/* Also, remember the last dimension in that list, for SAS first.___ processing */
%let by_list = ;
%let last_dim = ;
%do j = 1 %to &num_dims;
%if &j ~= &i %then %do;
%let by_list = &by_list &&dim&j;
%let last_dim = &&dim&j;
%end;
%end;
/* Sort by the by variables */
proc sort data = &target_data;
by level &by_list &target_var;
run;
data &target_data;
set &target_data;
by level &by_list;
retain numsuppressed;
/* When we enter a new group, reset the suppression counter */
if first.&last_dim = 1 then numsuppressed = 0;
/* If this needs to be suppressed, suppress it
Also, make sure we know there's been a change, so we need to loop again */
if &target_var ~= . and numsuppressed = 1 then do;
&target_var = .;
call symput('changed', '1');
end;
/* If this cell is suppressed, increment the suppression counter */
if &target_var = . then numsuppressed = numsuppressed + 1;
drop numsuppressed;
run;
%end;
%end;
%put Finished after &iterations iterations...;
%mend;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment