<?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: Macro code to create nested, spanning column headers in PROC REPORT in ODS and Base Reporting</title>
    <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/455029#M20853</link>
    <description>&lt;P&gt;Is there a way to create the output report by working directly on the raw data ?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 18 Apr 2018 05:31:22 GMT</pubDate>
    <dc:creator>Ronein</dc:creator>
    <dc:date>2018-04-18T05:31:22Z</dc:date>
    <item>
      <title>Macro code to create nested, spanning column headers in PROC REPORT</title>
      <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/427858#M20173</link>
      <description>&lt;P&gt;I'm trying to create a table that summarizes variables (e.g. by their mean and standard deviation) across levels of multiple class variables. Here's an example of what I want, in which the variables x1 and x2 are summarized across levels of two class variables (which you can guess are sex and age):&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Table 1. Spanning headers" style="width: 365px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/17892iE25BB382573CCF55/image-size/large?v=v2&amp;amp;px=999" role="button" title="Table - 2 classes - good.PNG" alt="Table 1. Spanning headers" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Table 1. Spanning headers&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;Note that age is nested within sex, and the "Female" and "Male" headers span the levels of age. I'm trying to write a macro that automatically generates the COLUMN statement in PROC REPORT to create this style of header, for any number of class variables. E.g., I would be able to nest another class variable, height (short vs tall) within levels of age.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I currently have code that creates a table similar to what I want, but the headers don't span. Like this:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Table 2. Headers do not span" style="width: 365px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/17893i460036010CCFBBBA/image-size/large?v=v2&amp;amp;px=999" role="button" title="Table - 2 classes - bad.PNG" alt="Table 2. Headers do not span" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Table 2. Headers do not span&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;My code is below.&amp;nbsp;Currently, it (1) creates some fake data to play with, (2) summarizes the data with PROC MEANS, (3) transposes the data so it's in the desired form, and (4) prints the data with PROC REPORT. If you run the code as is,&amp;nbsp;it should reproduce the above Table 2. You can set the &lt;FONT face="lucida sans unicode,lucida sans"&gt;nClasses&lt;/FONT&gt; macro variable to a different value to create a table with 1, 2, 3, or 4 class variables.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;* simulate data. The c vars are the class variables, and the x vars are
  the data to be summarized within levels of the classes.;
data test;
	call streaminit(12345);
	do id = 1 to 200;
		if rand('Bernoulli', 0.6) then c1 = 'Female'; else c1 = 'Male';
		if rand('Bernoulli', 0.3) then c2 = 'Young';  else c2 = 'Old';
		if rand('Bernoulli', 0.5) then c3 = 'Short';  else c3 = 'Tall';
		if rand('Bernoulli', 0.8) then c4 = 'Alive';  else c4 = 'Dead';
		x1 = rand('Normal', 60, 15);
		x2 = rand('Normal', 3, 1);
		output;
	end;
run;

%let nClasses = 2; * how many class variables should we use? Set to 1, 2, 3, or 4;

* summarize the x variables by class;
proc means data=test mean std stackodsoutput;
	class c1-c&amp;amp;nClasses;
	var x1 x2;
	ods output summary=means;
run;

data means;
	set means;
	class = catx(' ', of c1-c&amp;amp;nClasses); * concatenate all the class variables, space-delimited;
	stat = catx(' ', put(mean,6.1), cats('(', put(stdDev,6.1), ')')); * combine mean and sd into a char var;
run;

* create two macro vars:
  (1) nClassLevels = the total number of class levels. By level, we mean a combination of
	  all the class vars of interest. So if nClasses=2, then there are 4 levels, since c1
	  and c2 both have two levels. In general for our simulated data, where all the class
	  vars are binary, nClassLevels equals 2^nClasses.
  (2) classLevels = the names of all the levels. E.g. if nClasses=2, the first class level
	  is Female Old and the last is Male Young. The levels are delimited by a | (and within
	  a level, the sublevels are delimited by a space.;
proc sql noprint;
	select count(class), class
	into :nClassLevels, :classLevels separated by '|'
	from means
	where variable = 'x1';
quit;
%put nClassLevels = &amp;amp;nClassLevels;
%put classLevels = &amp;amp;classLevels;

* transpose data from long to wide;
proc sort data=means;
	by variable;
run;
proc transpose data=means out=table prefix=stat;
	by variable;
	var stat;
run;

* print the table. This version does not cause headers to span across nested subheaders.;
%macro print;
proc report data=table nowd;
	column ("Variable" variable)
		%do i = 1 %to &amp;amp;nClassLevels;
			%let classLevelsI = %scan(&amp;amp;classLevels,&amp;amp;i,|);
			%do j = 1 %to &amp;amp;nClasses;
				("%scan(&amp;amp;classLevelsI,&amp;amp;j,,s)"
			%end;
			stat&amp;amp;i
			%do j = 1 %to &amp;amp;nClasses;
				)
			%end;
		%end;
		;
	define variable / "";
	%do i = 1 %to &amp;amp;nClassLevels;
		define stat&amp;amp;i / "" center;
	%end;
run; quit;
%mend print;
%print;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;My question is, how do I alter the &lt;FONT face="lucida sans unicode,lucida sans"&gt;%print&lt;/FONT&gt; macro so that the header labels span nested labels, as in Table 1? This should work no matter the value of &lt;FONT face="lucida sans unicode,lucida sans"&gt;nClasses&lt;/FONT&gt;.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For reference, if you run the above code (with&amp;nbsp;&lt;FONT face="lucida sans unicode,lucida sans"&gt;&lt;SPAN&gt;nClasses = 2&lt;/SPAN&gt;&lt;/FONT&gt;), then the code below will produce Table 1. (I wrote this code by hand, but I want the &lt;SPAN&gt;&lt;FONT face="lucida sans unicode,lucida sans"&gt;%print&lt;/FONT&gt;&amp;nbsp;&lt;/SPAN&gt;macro to do it for me.)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc report data=table nowd;
	column ("Variable" variable)
		("Female"
			("Old"   stat1)
			("Young" stat2)
		)
		("Male"
			("Old"   stat3)
			("Young" stat4)
		);
	define variable / "";
	define stat1 / "" center;
	define stat2 / "" center;
	define stat3 / "" center;
	define stat4 / "" center;
run; quit;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;I'm using SAS 9.4.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks for any suggestions!&lt;/P&gt;</description>
      <pubDate>Mon, 15 Jan 2018 22:10:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/427858#M20173</guid>
      <dc:creator>dagremu</dc:creator>
      <dc:date>2018-01-15T22:10:44Z</dc:date>
    </item>
    <item>
      <title>Re: Macro code to create nested, spanning column headers in PROC REPORT</title>
      <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/427859#M20174</link>
      <description>&lt;P&gt;What happens if you change your data structure and use those variables as ACROSS variables?&amp;nbsp;&lt;BR /&gt;Just wondering if that would automatically format the way you want, without having to delve into Macros.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Note that I'm going to move this post to the ODS reporting forum, since it's more related to reporting than macro's per se.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 15 Jan 2018 22:05:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/427859#M20174</guid>
      <dc:creator>Reeza</dc:creator>
      <dc:date>2018-01-15T22:05:46Z</dc:date>
    </item>
    <item>
      <title>Re: Macro code to create nested, spanning column headers in PROC REPORT</title>
      <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/428075#M20179</link>
      <description>&lt;P&gt;Great suggestion! Using the &lt;FONT face="courier new,courier"&gt;means&lt;/FONT&gt; dataset that I create in my code above, and using &lt;FONT face="courier new,courier"&gt;c1&lt;/FONT&gt; and &lt;FONT face="courier new,courier"&gt;c2&lt;/FONT&gt; as across variables, I just wrote the following code:&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc report data=means nowd;
	column ('Variable' variable) c1, c2, stat;
	define variable / '';
	define c1 / across '';
	define c2 / across '';
	define stat / '';
run; quit;&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;This gets me tantalizingly close to what I want, but for some reason the values of &lt;FONT face="courier new,courier"&gt;stat&lt;/FONT&gt; get spread out over 8 rows instead of 2:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Table 3. Created from means dataset using across variables, but it doesn't quite work" style="width: 365px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/17906i2552F6C2FF5F335E/image-size/large?v=v2&amp;amp;px=999" role="button" title="Table sparse.PNG" alt="Table 3. Created from means dataset using across variables, but it doesn't quite work" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Table 3. Created from means dataset using across variables, but it doesn't quite work&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;Is there some option to collapse the values of &lt;FONT face="courier new,courier"&gt;stat&lt;/FONT&gt;? I tried making &lt;FONT face="courier new,courier"&gt;variable&lt;/FONT&gt; a group&amp;nbsp;variable, but got an error message saying "There is no statistic associated with stat". Any ideas?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;For reference, here's what the &lt;FONT face="courier new,courier"&gt;means&lt;/FONT&gt; dataset looks like (showing just the relevant variables):&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Means dataset with nClasses = 2" style="width: 269px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/17907i9221954B59BA3BAA/image-size/large?v=v2&amp;amp;px=999" role="button" title="Means dataset.PNG" alt="Means dataset with nClasses = 2" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Means dataset with nClasses = 2&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 16 Jan 2018 16:20:14 GMT</pubDate>
      <guid>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/428075#M20179</guid>
      <dc:creator>dagremu</dc:creator>
      <dc:date>2018-01-16T16:20:14Z</dc:date>
    </item>
    <item>
      <title>Re: Macro code to create nested, spanning column headers in PROC REPORT</title>
      <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/429501#M20211</link>
      <description>&lt;P&gt;Try using the N statistic.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc report data=means nowd;
	column ('Variable' variable) c1, c2, stat n;
	define variable / group '';
	define c1 / across '';
	define c2 / across '';
	define stat / '';
	define n / noprint;
run; quit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="PROC REPORT output using N statistic with NOPRINT" style="width: 407px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/18012i0A1D64ABFFBE9305/image-size/large?v=v2&amp;amp;px=999" role="button" title="PROC REPORT output.jpg" alt="PROC REPORT output using N statistic with NOPRINT" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;PROC REPORT output using N statistic with NOPRINT&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://www.mwsug.org/proceedings/2014/SS/MWSUG-2014-SS08.pdf" target="_self"&gt;Sailing Over the ACROSS Hurdle in PROC REPORT&lt;/A&gt;&amp;nbsp;by Cynthia Zender&amp;nbsp;explains this method in more detail, starting on page 4.&lt;/P&gt;</description>
      <pubDate>Sun, 21 Jan 2018 23:03:15 GMT</pubDate>
      <guid>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/429501#M20211</guid>
      <dc:creator>SuzanneDorinski</dc:creator>
      <dc:date>2018-01-21T23:03:15Z</dc:date>
    </item>
    <item>
      <title>Re: Macro code to create nested, spanning column headers in PROC REPORT</title>
      <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/429647#M20212</link>
      <description>Magic! Thank you Suzanne!</description>
      <pubDate>Mon, 22 Jan 2018 15:06:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/429647#M20212</guid>
      <dc:creator>dagremu</dc:creator>
      <dc:date>2018-01-22T15:06:22Z</dc:date>
    </item>
    <item>
      <title>Re: Macro code to create nested, spanning column headers in PROC REPORT</title>
      <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/455029#M20853</link>
      <description>&lt;P&gt;Is there a way to create the output report by working directly on the raw data ?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 18 Apr 2018 05:31:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/455029#M20853</guid>
      <dc:creator>Ronein</dc:creator>
      <dc:date>2018-04-18T05:31:22Z</dc:date>
    </item>
    <item>
      <title>Re: Macro code to create nested, spanning column headers in PROC REPORT</title>
      <link>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/455162#M20854</link>
      <description>&lt;P&gt;Hi:&lt;BR /&gt;&amp;nbsp; You'd have to read the raw data into a SAS dataset in order to use PROC REPORT. Or, you'd have to read the RAW data in a DATA step program and then use PUT statements to create the output table. Either way, SAS is not dealing with the raw data directly.&lt;BR /&gt;&lt;BR /&gt;&amp;nbsp; As an example, here's a DATA step program that reads raw data that has been constructed as described earlier in this post and then the same PROC REPORT code can be used on the file. I just used a DATALINES section to feed "instream" data to the program, but your INFILE statement could have been:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT face="courier new,courier"&gt;infile 'c:\temp\rawdata.txt' dlm=',' dsd;&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;...instead of having a DATALINES for the data.&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;Cynthia&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data means;
  length c1 $10 c2 $5 variable $32 stat $30;
  infile datalines dlm=',' dsd;
  input c1 $ c2 $ Variable $ stat $ ;
return;
datalines;
Female,Old,x1,"60.4 (13.4)"
Female,Young,x1,"64.1 (13.0)"
Male,Old,x1,"59.1 (14.2)"
Male,Young,x1,"52.1 (16.1)"
Female,Old,x2,"3.0 (1.0)"
Female,Young,x2,"2.9 (0.8)"
Male,Old,x2,"3.0 (1.1)"
Male,Young,x2,"2.6 (0.8)"
;
run;
  
proc report data=means nowd;
	column ('Variable' variable) c1, c2, stat n;
	define variable / group '';
	define c1 / across '';
	define c2 / across '';
	define stat / '';
	define n / noprint;
run;  &lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 18 Apr 2018 13:30:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/ODS-and-Base-Reporting/Macro-code-to-create-nested-spanning-column-headers-in-PROC/m-p/455162#M20854</guid>
      <dc:creator>Cynthia_sas</dc:creator>
      <dc:date>2018-04-18T13:30:40Z</dc:date>
    </item>
  </channel>
</rss>

