**Summarizes weighted means of variables in dataset;
%macro summary_means(input_data=,
										 variables=,
										 row_subset=,
										 population_name=All,
										 weight=,
										 outlib=WORK,
										 outname=);
										 
	%local num_variables i;
										 
	%let num_variables = %sysfunc(countw(&variables., %str( )));
										 
	**Calculate means;
	proc means data=&input_data. noprint;
		%if &row_subset. ^= %str() %then %do;
			where &row_subset.;
		%end;
		
		var &variables.;
		
		%if &weight. ^= %str() %then %do;
			weight &weight.;
		%end;
		
		output out=_outmeans mean=variable1-variable&num_variables.;
	run;
	
	**Create summary dataset;
	data &outlib..&outname. (keep = population variable statistic value);
		set _outmeans;
		
		length population $200.;
		length variable $32.;
		length statistic $200.;
		
		population = "&population_name.";
		
		%do i = 1 %to &num_variables.;
		
			variable = scan("&variables.", &i., " ");
			statistic = "Mean";
			value = variable&i.;
			
			output;
		%end;
	run;
%mend summary_means;

**Summarizes weighted quantiles of variables in dataset;
%macro summary_quantiles(input_data=,
												 variables=,
												 row_subset=,
												 population_name=All,
												 weight=,
												 quantiles=5 25 50 75 95,
												 outlib=WORK,
												 outname=);
												 
	%local num_variables variable j
				 num_quantiles;
	
	%let num_variables = %sysfunc(countw(&variables., %str( )));
	%let num_quantiles = %sysfunc(countw(&quantiles., %str( )));
	
	data _indata;
		set &input_data.;
		
		%if &row_subset. ^= %str() %then %do;
		
			if &row_subset.;
		%end;
	run;											 
	
	%do j = 1 %to &num_variables.;
	
		%let variable = %sysfunc(scan(&variables, &j., %str( )));
	
		data _vardata (keep = &variable. &weight.);
			set _indata;
		run;
		
		**Calculate quantiles;
		proc univariate data=_vardata noprint;
		
			var &variable.;
			
			%if &weight. ^= %str() %then %do;
			
				weight &weight.;
			%end;
			
			output out=_outquantiles_var&j. pctlpts=&quantiles. pctlpre=var&j. pctlname=_q1-_q&num_quantiles.;
		run;
		
		**Create summary dataset;
		data _quantiles_var&j. (keep = population variable statistic value);
			set _outquantiles_var&j.;
			
			length population $200.;
			length variable $32.;
			length statistic $200.;
			
			array quantiles{&num_quantiles.} var&j._q1-var&j._q&num_quantiles.;
			
			population = "&population_name.";
			variable = "&variable.";
			
			do i = 1 to &num_quantiles.;
			
				statistic = cats(scan("&quantiles.", i, " "), "%");
				value = quantiles{i};
				
				output;
			end;
		run;
	%end;
	
	data &outlib..&outname.;
		set _quantiles_var1-_quantiles_var&num_variables.;
	run;
%mend summary_quantiles;

**Summarizes proportions of observations in dataset above/below thresholds;
%macro summary_proportions(input_data=,
													 row_subset=,
													 population_name=All,
													 weight=,
													 lower_thresholds=,
													 upper_thresholds=,
													 outlib=WORK,
													 outname=);
													 
	%local j;
	
	data _indata;
		set &input_data.;
		
		%if &row_subset. ^= %str() %then %do;
		
			if &row_subset.;
		%end;
	run;	
													 
	**lower thresholds;
	%if &lower_thresholds. ^= %str() %then %do;
	
		**extract variables and thresholds;
		data _NULL_;
			set &lower_thresholds. end=last;
			
			call symputx(cat("lower_variable", _N_), variable, "L");
			call symputx(cat("lower_threshold", _N_), threshold, "L");
			
			if last = 1 then call symputx("num_lower", _N_, "L");
		run;
		
		**set indicators;
		data _lower_indicators;
			set _indata;
	
			%do j = 1 %to &num_lower.;
			
				_indicator&j. = (&&lower_variable&j.. > &&lower_threshold&j..);
			%end;
		run;
		
		**calculate proportions;
		proc means data=_lower_indicators noprint;
		
			var _indicator1-_indicator&num_lower.;
			
			%if &weight. ^= %str() %then %do;
			
				weight &weight.;
			%end;
			
			output out=_outlower mean=_proportion1-_proportion&num_lower.;
		run;
		
		**create summary dataset;
		data _lower_proportions (keep = population variable statistic value);
			set _outlower;
			
			length population $200.;
			length variable $32.;
			length statistic $200.;
			
			population = "&population_name.";
			statistic = "Proportion";
			
			%do j = 1 %to &num_lower.;
			
				variable = "&&lower_variable&j.. > &&lower_threshold&j..";
				value = _proportion&j.;
				
				output;
			%end;
		run;
	%end;
	
	**upper thresholds;
	%if &upper_thresholds. ^= %str() %then %do;
	
		**extract variables and thresholds;
		data _NULL_;
			set &upper_thresholds. end=last;
			
			call symputx(cat("upper_variable", _N_), variable, "L");
			call symputx(cat("upper_threshold", _N_), threshold, "L");
			
			if last = 1 then call symputx("num_upper", _N_, "L");
		run;
		
		**set indicators;
		data _upper_indicators;
			set _indata;
	
			%do j = 1 %to &num_upper.;
			
				_indicator&j. = (&&upper_variable&j.. < &&upper_threshold&j..);
			%end;
		run;
		
		**calculate proportions;
		proc means data=_upper_indicators noprint;
		
			var _indicator1-_indicator&num_upper.;
			
			%if &weight. ^= %str() %then %do;
			
				weight &weight.;
			%end;
			
			output out=_outupper mean=_proportion1-_proportion&num_upper.;
		run;
		
		**create summary dataset;
		data _upper_proportions (keep = population variable statistic value);
			set _outupper;
			
			length population $200.;
			length variable $32.;
			length statistic $200.;
			
			population = "&population_name.";
			statistic = "Proportion";
			
			%do j = 1 %to &num_upper.;
			
				variable = "&&upper_variable&j.. < &&upper_threshold&j..";
				value = _proportion&j.;
				
				output;
			%end;
		run;
	%end;
	
	data &outlib..&outname.;
		set %if &lower_thresholds. ^= %str() %then %do;
		
					_lower_proportions
				%end;
				
				%if &upper_thresholds. ^= %str() %then %do;
				
					_upper_proportions
				%end;
				;
	run;
%mend summary_proportions;
