<?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 SAS macro and proc univariate, change endpoints for each group in SAS Data Management</title>
    <link>https://communities.sas.com/t5/SAS-Data-Management/SAS-macro-and-proc-univariate-change-endpoints-for-each-group/m-p/233872#M5868</link>
    <description>&lt;P&gt;Hi,&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I have 2 variables in my dataset - y and group. For each group, I want to create a histogram with endpoints calculated within the data for each group. My data could change, therefore, &amp;nbsp;the number of observations and number of groups may change for every diffrent data. For each group, i calculated the bandwidth(bw), lower limit (lw) and upper limit (up). I have to use these values to specify the endpoints for each histogram. But I keep on getting errors. Do you have any suggestion to improve and correct my current code? I want to output only the histogram for each group with specific endpoints. Thank you.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;data test;&lt;BR /&gt;input y group @@;&lt;BR /&gt;datalines;&lt;BR /&gt;35 1 46 2&lt;BR /&gt;32 1 43 2&lt;BR /&gt;38 1 46 2&lt;BR /&gt;32 1 46 2&lt;BR /&gt;32 1 40 2&lt;BR /&gt;38 1 50 2&lt;BR /&gt;36 1 49 2&lt;BR /&gt;33 1 40 3&lt;BR /&gt;37 1 42 3&lt;BR /&gt;33 1 40 3&lt;BR /&gt;49 2 42 3&lt;BR /&gt;45 2 43 3&lt;BR /&gt;49 2 45 3&lt;BR /&gt;41 2 45 3&lt;BR /&gt;47 2 49 3&lt;BR /&gt;48 2 40 3&lt;BR /&gt;45 2 58 3&lt;BR /&gt;47 3 59 3&lt;BR /&gt;56 4 56 3&lt;BR /&gt;52 4 51 4&lt;BR /&gt;60 4 57 4&lt;BR /&gt;60 4 53 4&lt;BR /&gt;50 4 50 4&lt;BR /&gt;56 4 52 4&lt;BR /&gt;53 4 51 4&lt;BR /&gt;50 4 52 4&lt;BR /&gt;;&lt;BR /&gt;run;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;%macro histo;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;proc sort data=test out=test1;&lt;BR /&gt;by group;&lt;BR /&gt;run;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;proc means data=test1 min max range;&lt;BR /&gt;by group;&lt;BR /&gt;var y;&lt;BR /&gt;output out=dishist2(drop=_TYPE_ _FREQ_) min=min max=max range=range;&lt;BR /&gt;run;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;data dishist2;&lt;BR /&gt;set dishist2;&lt;BR /&gt;bw=(max-min)/10;&lt;BR /&gt;lw=floor(min/bw)*bw-(3*bw);&lt;BR /&gt;up=floor(((max/bw)+1)*bw)+(3*bw);&lt;BR /&gt;run;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;proc sql noprint ;&lt;BR /&gt; select bw ,lw, up&lt;BR /&gt; into :bw1 separated by ' ',&lt;BR /&gt; :lw1 separated by ' ',&lt;BR /&gt; :up1 separated by ' '&lt;BR /&gt; from dishist2;&lt;BR /&gt; quit;&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;%let cnt=&amp;amp;sqlobs;&lt;/P&gt;
&lt;P&gt;%do i=1 %to &amp;amp;cnt;&lt;BR /&gt;%let lww= %scan(&amp;amp;lw1,&amp;amp;i);&lt;BR /&gt;%let upp= %scan(&amp;amp;up1,&amp;amp;i);&lt;BR /&gt;%let bww= %scan(&amp;amp;bw1,&amp;amp;i);&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;proc univariate data=test1 noprint ;&lt;BR /&gt; by group;&lt;BR /&gt; histogram y/ grid normal name='MyHist' vscale=proportion hoffset=10 vaxis=0 to 1 by .5&lt;BR /&gt; endpoints = &amp;amp;lww to &amp;amp;upp by &amp;amp;bww;&lt;BR /&gt;run;&lt;BR /&gt;%end;&lt;BR /&gt;%mend histo;&lt;/P&gt;
&lt;P&gt;%histo;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Mon, 09 Nov 2015 18:09:39 GMT</pubDate>
    <dc:creator>statz</dc:creator>
    <dc:date>2015-11-09T18:09:39Z</dc:date>
    <item>
      <title>SAS macro and proc univariate, change endpoints for each group</title>
      <link>https://communities.sas.com/t5/SAS-Data-Management/SAS-macro-and-proc-univariate-change-endpoints-for-each-group/m-p/233872#M5868</link>
      <description>&lt;P&gt;Hi,&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I have 2 variables in my dataset - y and group. For each group, I want to create a histogram with endpoints calculated within the data for each group. My data could change, therefore, &amp;nbsp;the number of observations and number of groups may change for every diffrent data. For each group, i calculated the bandwidth(bw), lower limit (lw) and upper limit (up). I have to use these values to specify the endpoints for each histogram. But I keep on getting errors. Do you have any suggestion to improve and correct my current code? I want to output only the histogram for each group with specific endpoints. Thank you.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;data test;&lt;BR /&gt;input y group @@;&lt;BR /&gt;datalines;&lt;BR /&gt;35 1 46 2&lt;BR /&gt;32 1 43 2&lt;BR /&gt;38 1 46 2&lt;BR /&gt;32 1 46 2&lt;BR /&gt;32 1 40 2&lt;BR /&gt;38 1 50 2&lt;BR /&gt;36 1 49 2&lt;BR /&gt;33 1 40 3&lt;BR /&gt;37 1 42 3&lt;BR /&gt;33 1 40 3&lt;BR /&gt;49 2 42 3&lt;BR /&gt;45 2 43 3&lt;BR /&gt;49 2 45 3&lt;BR /&gt;41 2 45 3&lt;BR /&gt;47 2 49 3&lt;BR /&gt;48 2 40 3&lt;BR /&gt;45 2 58 3&lt;BR /&gt;47 3 59 3&lt;BR /&gt;56 4 56 3&lt;BR /&gt;52 4 51 4&lt;BR /&gt;60 4 57 4&lt;BR /&gt;60 4 53 4&lt;BR /&gt;50 4 50 4&lt;BR /&gt;56 4 52 4&lt;BR /&gt;53 4 51 4&lt;BR /&gt;50 4 52 4&lt;BR /&gt;;&lt;BR /&gt;run;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;%macro histo;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;proc sort data=test out=test1;&lt;BR /&gt;by group;&lt;BR /&gt;run;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;proc means data=test1 min max range;&lt;BR /&gt;by group;&lt;BR /&gt;var y;&lt;BR /&gt;output out=dishist2(drop=_TYPE_ _FREQ_) min=min max=max range=range;&lt;BR /&gt;run;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;data dishist2;&lt;BR /&gt;set dishist2;&lt;BR /&gt;bw=(max-min)/10;&lt;BR /&gt;lw=floor(min/bw)*bw-(3*bw);&lt;BR /&gt;up=floor(((max/bw)+1)*bw)+(3*bw);&lt;BR /&gt;run;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;proc sql noprint ;&lt;BR /&gt; select bw ,lw, up&lt;BR /&gt; into :bw1 separated by ' ',&lt;BR /&gt; :lw1 separated by ' ',&lt;BR /&gt; :up1 separated by ' '&lt;BR /&gt; from dishist2;&lt;BR /&gt; quit;&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;%let cnt=&amp;amp;sqlobs;&lt;/P&gt;
&lt;P&gt;%do i=1 %to &amp;amp;cnt;&lt;BR /&gt;%let lww= %scan(&amp;amp;lw1,&amp;amp;i);&lt;BR /&gt;%let upp= %scan(&amp;amp;up1,&amp;amp;i);&lt;BR /&gt;%let bww= %scan(&amp;amp;bw1,&amp;amp;i);&lt;/P&gt;
&lt;P&gt;&lt;BR /&gt;proc univariate data=test1 noprint ;&lt;BR /&gt; by group;&lt;BR /&gt; histogram y/ grid normal name='MyHist' vscale=proportion hoffset=10 vaxis=0 to 1 by .5&lt;BR /&gt; endpoints = &amp;amp;lww to &amp;amp;upp by &amp;amp;bww;&lt;BR /&gt;run;&lt;BR /&gt;%end;&lt;BR /&gt;%mend histo;&lt;/P&gt;
&lt;P&gt;%histo;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 09 Nov 2015 18:09:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Data-Management/SAS-macro-and-proc-univariate-change-endpoints-for-each-group/m-p/233872#M5868</guid>
      <dc:creator>statz</dc:creator>
      <dc:date>2015-11-09T18:09:39Z</dc:date>
    </item>
    <item>
      <title>Re: SAS macro and proc univariate, change endpoints for each group</title>
      <link>https://communities.sas.com/t5/SAS-Data-Management/SAS-macro-and-proc-univariate-change-endpoints-for-each-group/m-p/234087#M5896</link>
      <description>&lt;P&gt;Hi,&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Since&amp;nbsp;your parameters are generated dynamically, it makes sense to trap for certain invalid conditions before passing them to proc univariate. First, I added&amp;nbsp;"&lt;STRONG&gt;options symbolgen mprint;&lt;/STRONG&gt;" since that is&amp;nbsp;helpful when looking at log output for dynamically generated variables.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Second, I added debugging code within the do loop that does a few things:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN style="line-height: 20px;"&gt;traps for two invalid conditions (&lt;/SPAN&gt;&lt;STRONG&gt;&amp;amp;bww=0&lt;/STRONG&gt;&lt;SPAN style="line-height: 20px;"&gt; and &lt;/SPAN&gt;&lt;STRONG&gt;&amp;amp;lww &amp;gt; &amp;amp;upp&lt;/STRONG&gt;&lt;SPAN style="line-height: 20px;"&gt;), which&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;proc univariate&lt;/STRONG&gt;&lt;SPAN style="line-height: 20px;"&gt; finds acceptable&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN style="line-height: 20px;"&gt;outputs the invalid condition&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="line-height: 20px;"&gt;to the results pane&lt;/SPAN&gt;&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Hope this helps. Have a look at the attached PDF file too.&amp;nbsp;&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;%macro histo;

proc sort data=test out=test1;
by group;
run;
 
proc means data=test1 min max range;
by group;
var y;
output out=dishist2(drop=_TYPE_ _FREQ_) min=min max=max range=range;
run;
 
data dishist2;
set dishist2;
bw=(max-min)/10;
lw=floor(min/bw)*bw-(3*bw);
up=floor(((max/bw)+1)*bw)+(3*bw);
run;
 
proc sql noprint ;
select bw ,lw, up
into :bw1 separated by ' ',
:lw1 separated by ' ',
:up1 separated by ' '
from dishist2;
quit;

%let cnt=&amp;amp;sqlobs;

options symbolgen mprint;
%do i=1 %to &amp;amp;cnt;
  
  %let lww= %scan(&amp;amp;lw1,&amp;amp;i);
  %let upp= %scan(&amp;amp;up1,&amp;amp;i);
  %let bww= %scan(&amp;amp;bw1,&amp;amp;i);
  %let bad_flag=0;
  %let bad_reason="";

  /* flag certain invalid conditions */
  %IF %EVAL(&amp;amp;bww=0) %THEN %DO; 
      %let bad_flag=1;
      %let bad_reason=%STR(Cannot execute due to bad parameters: bww = 0);
  %END;
  %ELSE %IF %EVAL(&amp;amp;lww &amp;gt; &amp;amp;upp) %THEN %DO;
      %let bad_flag=2;
      %let bad_reason=%STR(Cannot execute due to bad parameters: lww &amp;gt; upp);
  %END;
  /* if there are other invalid condition that you want to detect, add them here: */
  /*  %ELSE %IF %EVAL( test_for_bad_condition_here ) %THEN %DO;                   */
  /*    %let bad_flag=3;                                                          */
  /*    %let bad_reason=%STR( description_of_bad_condition_here );                */
  /*  %END; */

  %IF %EVAL(&amp;amp;bad_flag=0) %THEN %DO;

    proc univariate data=test1 noprint ;
    by group;
    histogram y/ grid normal name='MyHist' vscale=proportion hoffset=10 vaxis=0 to 1 by .5
    endpoints = &amp;amp;lww to &amp;amp;upp by &amp;amp;bww;
    run;

  %END;
  %ELSE %DO;

    /* output explanation why procedure cannot be executed ... */

    DATA work.debug_table;
      cnt = &amp;amp;cnt;
      lww = &amp;amp;lww;
      upp = &amp;amp;upp;
      bww = &amp;amp;bww;
    RUN;
    
    PROC PRINT DATA=debug_table; 
      TITLE color=red "&amp;amp;bad_reason";
    RUN;

    PROC SQL; DROP TABLE work.debug_table; QUIT;

    TITLE; *reset title;

  %END;

%end;
options nosymbolgen nomprint;

%mend histo;
%histo;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 10 Nov 2015 18:36:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Data-Management/SAS-macro-and-proc-univariate-change-endpoints-for-each-group/m-p/234087#M5896</guid>
      <dc:creator>hbi</dc:creator>
      <dc:date>2015-11-10T18:36:20Z</dc:date>
    </item>
  </channel>
</rss>

