The SAS Output Delivery System and reporting techniques

Variable length sliders for percentages in Proc Report

Reply
Frequent Contributor
Posts: 77

Variable length sliders for percentages in Proc Report

[ Edited ]

Following this slide show, trying to get slider bars that change in length based on percentages.

 

http://www.slideshare.net/eagebhart/proc-report/18

 

Slide 18 shows the code added to Proc Report and slide 19 shows the output (I've also attached an image of the output).

 

Here is the code I'm trying (and below are my issues):

 

ods tagsets.slider file='example6.html' style=slider;
*ods pdf file='output.pdf'; proc report data=sashelp.class nowd; columns sex name age height weight weight=weight2 weight_pct; define name / display 'Name' width=10; define sex / group 'Gender' width=6; define age / display 'Age' width=4; define height / analysis mean 'Height' format=8.1; define weight / analysis noprint 'Weight' format=8.1; define weight2 / analysis mean 'Weight' format=8.1; define weight_pct / computed '% of Weight' format=percent6. left style(column)=bar[tagattr="slider"]; compute weight_pct; weight_pct = weight.sum/weight_sum; endcomp; compute before sex; weight_sum=weight.sum; endcomp; break after sex / summarize style=header; run; *ods pdf close;

Here are the issues I'm having:

 

  •  In the Results Viewer window as well as the example6.html file, there is what appears to be a place for the bar, but no actual bar. (Looks like image missing). Edit - looking at the source of the .html file, it is calling bar.png - this file is in the folder of the output.
  • I'd prefer to output this to .pdf instead of .html
Attachment
SAS Super FREQ
Posts: 8,641

Re: Variable length sliders for percentages in Proc Report

Hi:
  That author created a custom TAGSET template called TAGSETS.SLIDER in order to create that output. The challenge with your desire to make create this output in PDF is that PDF is NOT a "tagset" destination. So, you can't do in PDF what you can do in either HTML or XML with a TAGSET.

  As for why the image doesn't show, it is probably a mismatch between the path where bar.png is stored and the path where the browser looks for it.

  The bottom line is that the TAGSETS approach will not work for PDF.

 

cynthia

Frequent Contributor
Posts: 77

Re: Variable length sliders for percentages in Proc Report

Thank you.

 

I have the bar.png, example6.html (output), and slider.sas (program name of the code I provided here) all in the same folder. Where else would I set the location of the bar.png so that example6.html use the correct path? (again, example6.html & bar.png are in the same directory and viewing the source on example6.html shows it calling 'bar.png' - no other path details).

 

 

Does anyone know of a way to do this in .pdf directly from SAS?

SAS Super FREQ
Posts: 8,641

Re: Variable length sliders for percentages in Proc Report

I can think of 2 possibilities:

1) use a font character (Thorndale AMT has a "full block" character that, when you "stack" them side by side look like a full bar)

or

2) create a bar with SAS (probably SGPLOT) and then generate small images insert the images into your table.

 

Approach #1 is illustrated here:

with_font_char.png

 

Approach #2 is illustrated here:  http://support.sas.com/resources/papers/proceedings13/212-2013.pdf -- where the author has a trend line plot image in the table, you would replace this with a bar chart.

louise_sparkline.png

 

like this:

 using_images_in_report.png

 

cynthia

Grand Advisor
Posts: 9,315

Re: Variable length sliders for percentages in Proc Report


I love this question.
Check the attachment.




proc sql;
create table temp as
select *,weight/sum(weight) as per format=percent7.
 from sashelp.class as a
  group by sex;
quit;


ods listing gpath='/folders/myfolders/' image_dpi=300  ;
%macro hbar(name=);
ods graphics/reset height=20px width=100px imagename="&name" noborder ;
proc sgplot data=temp(where=(name="&name")) noborder ;
 hbar name/response=per datalabel baselineattrs=(thickness=0)
   nooutline;
 xaxis display=none values=(0 to 1 by 0.1) offsetmax=0 offsetmin=0;
 yaxis display=none offsetmax=0 offsetmin=0;
run;
%mend;

data _null_;
 set temp;
 call execute(cats('%hbar(name=',name,')'));
run;


ods pdf file='/folders/myfolders/want.pdf' dpi=300;
proc report data=sashelp.class nowd out=x;
	columns sex name age height weight weight=weight2 weight_pct picture;
	define name			/ display 'Name' width=10;
	define sex			/ group	'Gender' width=6;	
	define age			/ display 'Age' width=4;
	define height		/ analysis mean 'Height' format=8.1;
	define weight		/ analysis noprint 'Weight' format=8.1;
	define weight2		/ analysis mean 'Weight' format=8.1;
	define weight_pct	/ computed '% of Weight' format=percent6. left style(column)=bar[tagattr="slider"];

    define picture/computed ;
    compute picture/character length=40;
     if lowcase(_break_) ne 'sex' then
     call define(_col_,'style',cats('style={preimage="/folders/myfolders/',name,'.png"}'));
    endcomp;

	compute weight_pct;
		weight_pct = weight.sum/weight_sum;
	endcomp;

	compute before sex;
		weight_sum=weight.sum;
	endcomp;

	break after sex / summarize style=header;
run;
ods pdf close;



Frequent Contributor
Posts: 77

Re: Variable length sliders for percentages in Proc Report

[ Edited ]

This looks somewhat promising, however, when running through the data _null_ step, the files being created are Alice1.png (instead of simply 'Alice.png'). I don't see why it is adding the number for me, and I've even restarted SAS with the same results.

As a result of this, the output shows 'missing image'.

SAS Super FREQ
Posts: 8,641

Re: Variable length sliders for percentages in Proc Report

Typically, if there is an existing file named Alice.png, then a new, numbered file will be created. You can generally restart the numbering by doing this:
ods graphics /reset=all;
or
ods graphics / reset=index;

Usually, I go out and delete all the stray PNG files when I am doing multiple runs of the same program to avoid the numbering issue.
cynthia
Frequent Contributor
Posts: 77

Re: Variable length sliders for percentages in Proc Report

Hi Cynthia,

 

There were no files with these names in the directory.

 

However, the ods graphics /reset=all; sounds like it may help.

 

Also, for your solution above using Thorndale AMT, it is printing: 

 

^(unicode 2588) ^(unicode 2588) ^(unicode 2588) ^(unicode 2588) ^(unicode 2588) ^(unicode
2588) ^(unicode 2588) ^(unicode 2588) ^(unicode 2588) ^(unicode 2588) ^(unicode 2588) ^(unicode
2588) ^(unicode 2588) ^(unicode 2588) ^(unicode 2588) ^(unicode 2588) ^(unicode 2588) ^(unicode 2588)
67.26%

 

in the pchar column. I verified that I have Thorndale AMT installed.

 

I wasn't sure how to implement your second alternative, but thank you again for all of your help.

SAS Super FREQ
Posts: 8,641

Re: Variable length sliders for percentages in Proc Report

[ Edited ]

Hi: for the Thorndale AMT example to work, you need to be sure you have an ODS ESCAPECHAR statement before you use the data:
ods escapechar='^';

My approach to the second alternative was similar to Ksharp's method, I just did not macro-ize the code. I will dig it up and post it.

cynthia

 

Here's all the code I used:

** Make Test Data;
data testdata;
length pchar $4000 unibar $15 plabl $9;
  retain unibar '^{unicode 2588}';
  set sashelp.class;
  where age in (12,13);
  percent=height/weight;
  plabl = put(percent,percent9.2);
  pround = round((percent*25),1);
  pchar = catt(repeat(unibar,pround),put(percent,percent9.2));
  put _all_;
run;
 
**1)  Thorndale AMT approach works for me in ODS PDF and ODS HTML;
ods escapechar='^';
ods html file='c:\temp\bar_with_font.html' style=htmlblue;
ods pdf file='c:\temp\bar_with_font.pdf';
proc report data=testdata;
  column name age sex height weight percent pchar;
  define pchar / style(column)={color=red font_face='Thorndale AMT'};
format percent percent9.2;
run;
ods pdf close;
ods html close;

** 2)  make an image using SGPLOT approach;
**     be sure to create images are in c:\temp using GPATH=;
ods html path='c:\temp' (url=none)
         gpath='c:\temp' (url=none)
         file='checkbars.html';

** make images fairly small to fit in final table;
** run one SGPLOT for every student;
** could "macro-ize" this piece of code;
ods graphics / reset=all height=.5in width=3.5in imagename="Alice" imagefmt=png;
proc sgplot data=testdata noborder;
  where name = "Alice";
  hbar name / response=percent name="Alice"
       dataskin=matte
       datalabel=plabl 
       datalabelattrs=(Color=Navy Family='Courier New' Size=14 )
       datalabelfitpolicy=none;
  xaxis values=(0 to 1 by .1) display=none;
  yaxis display=none;
run;

ods graphics / height=.5in width=3.5in imagename="John" imagefmt=png;
proc sgplot data=testdata noborder;
  where name = "John";
  hbar name / response=percent name="John"
       dataskin=matte
       datalabel=plabl 
       datalabelattrs=(Color=Navy Family='Courier New' Size=14 )
       datalabelfitpolicy=none;
  xaxis values=(0 to 1 by .1) display=none;
  yaxis display=none;
run;

ods graphics / height=.5in width=3.5in imagename="Robert" imagefmt=png;
proc sgplot data=testdata noborder;
  where name = "Robert";
  hbar name / response=percent name="Robert"
       dataskin=matte
       datalabel=plabl 
       datalabelattrs=(Color=Navy Family='Courier New' Size=14 )
       datalabelfitpolicy=none;
  xaxis values=(0 to 1 by .1) display=none;
  yaxis display=none;
run;

ods html close;

** not entirely happy with resolution of datalabel in PDF output;
** but I would probably work with Tech Support on how to improve that;
** or design the report so that percent was in a separate column;

ods html gpath='c:\temp' (url=none)
         path='c:\temp' (url=none)
		 file = 'final.html';

ods pdf file='c:\temp\final.pdf';
proc report data=testdata
     style(column)={vjust=m};
  where name in ('Alice' 'Robert' 'John');
  column name age sex height weight percent pcell;
  define pcell / computed;
  compute pcell;
     pcell = ' ';     
     if name = 'Alice' then do;
	    call define(_col_,'style','style={preimage="c:\temp\Alice.png"}');
     end;
     else if name = 'John' then do;
	    call define(_col_,'style','style={preimage="c:\temp\John.png"}');
     end;
     else if name = 'Robert' then do;
	    call define(_col_,'style','style={preimage="c:\temp\Robert.png"}');
     end;
  endcomp;
format percent percent9.2;
run;

ods _all_ close;
Post a Question
Discussion Stats
  • 8 replies
  • 457 views
  • 2 likes
  • 3 in conversation