<?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 Loop in Macro in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Loop-in-Macro/m-p/193951#M36467</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi SAS Experts -&lt;/P&gt;&lt;P&gt;I have a macro that calculates acceptable range of a variable. An acceptable range is defined by :&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Lower Limit = Q1 - 1.5*(Q3-Q1)&lt;/P&gt;&lt;P&gt;Upper Limit = Q3 + 1.5*(Q3-Q1)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;It's a boxplot method of calculating outliers. The macro is working fine. But it is inefficient in terms of its processing as it calculates outliers for each variable in a loop and then capping values. I want proc univariate to be run for all the variables (not in loop) and save output in a dataset and then capping for variables using IF THEN at one time only.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Code : -&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;options mprint symbolgen; &lt;/P&gt;&lt;P&gt;%macro outliers(input=, vars=, output= );&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data &amp;amp;output;&lt;/P&gt;&lt;P&gt;set &amp;amp;input;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%let n=%sysfunc(countw(&amp;amp;vars));&lt;/P&gt;&lt;P&gt;%do i= 1 %to &amp;amp;n;&lt;/P&gt;&lt;P&gt;%let val = %scan(&amp;amp;vars,&amp;amp;i);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/* Calculate the quartiles and inter-quartile range using proc univariate */&lt;/P&gt;&lt;P&gt;proc univariate data=&amp;amp;output noprint;&lt;/P&gt;&lt;P&gt;var &amp;amp;val;&lt;/P&gt;&lt;P&gt;output out=temp QRANGE= IQR Q1= First_Qtl Q3= Third_Qtl;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/* Extract the upper and lower limits into macro variables */&lt;/P&gt;&lt;P&gt;data _null_;&lt;/P&gt;&lt;P&gt;set temp;&lt;/P&gt;&lt;P&gt;call symput('QR', IQR);&lt;/P&gt;&lt;P&gt;call symput('Q1', First_Qtl);&lt;/P&gt;&lt;P&gt;call symput('Q3', Third_Qtl);&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%let ULimit=%sysevalf(&amp;amp;Q3 + 1.5 * &amp;amp;QR);&lt;/P&gt;&lt;P&gt;%let LLimit=%sysevalf(&amp;amp;Q1 - 1.5 * &amp;amp;QR);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/* Final dataset excluding outliers*/&lt;/P&gt;&lt;P&gt;data &amp;amp;output;&lt;/P&gt;&lt;P&gt;set &amp;amp;output;&lt;/P&gt;&lt;P&gt;if &amp;amp;val &amp;lt; &amp;amp;Llimit then &amp;amp;val = &amp;amp;Llimit;&lt;/P&gt;&lt;P&gt;if &amp;amp;val &amp;gt; &amp;amp;Ulimit then &amp;amp;val = &amp;amp;Ulimit;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;%end;&lt;/P&gt;&lt;P&gt;%mend;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%outliers(Input=abcd, Vars = a, output= test);&lt;/P&gt;&lt;P&gt;o &lt;/P&gt;&lt;P&gt;Thanks in anticipation!&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Sun, 12 Apr 2015 09:18:01 GMT</pubDate>
    <dc:creator>Riya88</dc:creator>
    <dc:date>2015-04-12T09:18:01Z</dc:date>
    <item>
      <title>Loop in Macro</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Loop-in-Macro/m-p/193951#M36467</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi SAS Experts -&lt;/P&gt;&lt;P&gt;I have a macro that calculates acceptable range of a variable. An acceptable range is defined by :&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Lower Limit = Q1 - 1.5*(Q3-Q1)&lt;/P&gt;&lt;P&gt;Upper Limit = Q3 + 1.5*(Q3-Q1)&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;It's a boxplot method of calculating outliers. The macro is working fine. But it is inefficient in terms of its processing as it calculates outliers for each variable in a loop and then capping values. I want proc univariate to be run for all the variables (not in loop) and save output in a dataset and then capping for variables using IF THEN at one time only.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Code : -&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;options mprint symbolgen; &lt;/P&gt;&lt;P&gt;%macro outliers(input=, vars=, output= );&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;data &amp;amp;output;&lt;/P&gt;&lt;P&gt;set &amp;amp;input;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%let n=%sysfunc(countw(&amp;amp;vars));&lt;/P&gt;&lt;P&gt;%do i= 1 %to &amp;amp;n;&lt;/P&gt;&lt;P&gt;%let val = %scan(&amp;amp;vars,&amp;amp;i);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/* Calculate the quartiles and inter-quartile range using proc univariate */&lt;/P&gt;&lt;P&gt;proc univariate data=&amp;amp;output noprint;&lt;/P&gt;&lt;P&gt;var &amp;amp;val;&lt;/P&gt;&lt;P&gt;output out=temp QRANGE= IQR Q1= First_Qtl Q3= Third_Qtl;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/* Extract the upper and lower limits into macro variables */&lt;/P&gt;&lt;P&gt;data _null_;&lt;/P&gt;&lt;P&gt;set temp;&lt;/P&gt;&lt;P&gt;call symput('QR', IQR);&lt;/P&gt;&lt;P&gt;call symput('Q1', First_Qtl);&lt;/P&gt;&lt;P&gt;call symput('Q3', Third_Qtl);&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%let ULimit=%sysevalf(&amp;amp;Q3 + 1.5 * &amp;amp;QR);&lt;/P&gt;&lt;P&gt;%let LLimit=%sysevalf(&amp;amp;Q1 - 1.5 * &amp;amp;QR);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;/* Final dataset excluding outliers*/&lt;/P&gt;&lt;P&gt;data &amp;amp;output;&lt;/P&gt;&lt;P&gt;set &amp;amp;output;&lt;/P&gt;&lt;P&gt;if &amp;amp;val &amp;lt; &amp;amp;Llimit then &amp;amp;val = &amp;amp;Llimit;&lt;/P&gt;&lt;P&gt;if &amp;amp;val &amp;gt; &amp;amp;Ulimit then &amp;amp;val = &amp;amp;Ulimit;&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;%end;&lt;/P&gt;&lt;P&gt;%mend;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;%outliers(Input=abcd, Vars = a, output= test);&lt;/P&gt;&lt;P&gt;o &lt;/P&gt;&lt;P&gt;Thanks in anticipation!&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sun, 12 Apr 2015 09:18:01 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Loop-in-Macro/m-p/193951#M36467</guid>
      <dc:creator>Riya88</dc:creator>
      <dc:date>2015-04-12T09:18:01Z</dc:date>
    </item>
    <item>
      <title>Re: Loop in Macro</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Loop-in-Macro/m-p/322449#M71330</link>
      <description>&lt;P&gt;Hi.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I guest you are looking for something like this:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro outliers(input=, vars=, output= );&lt;BR /&gt;&lt;BR /&gt;%let nvars=%sysfunc(countw(&amp;amp;vars));
%do i= 1 %to &amp;amp;nvars;
%let val = %scan(&amp;amp;vars,&amp;amp;i);&lt;BR /&gt;
/* Calculate the quartiles and inter-quartile range using proc univariate */
proc univariate data=&amp;amp;input noprint;
var &amp;amp;vars;
* get qr, q1, q3 for each vars;
output out=&amp;amp;output QRANGE= %do j=1 %to &amp;amp;nvars; IQR_&amp;amp;j %end;
                 Q1= %do j=1 %to &amp;amp;nvars; First_Qtl_&amp;amp;j %end;
                 Q3= %do j=1 %to &amp;amp;nvars; Third_Qtl_&amp;amp;j %end;
       ;
run;&lt;BR /&gt;
/* Extract the upper and lower limits into macro variables */
data _null_;
set &amp;amp;output;&lt;BR /&gt;
* get lower/upper limits for each vars;
%do j=1 %to &amp;amp;nvars;
call symput("Llimit_&amp;amp;j",put(First_Qtl_&amp;amp;j+1.5*IQR_&amp;amp;j,best.));
call symput("Ulimit_&amp;amp;j",put(Third_Qtl_&amp;amp;j+1.5*IQR_&amp;amp;j,best.));
%end;
run;&lt;BR /&gt;
/* Final dataset excluding outliers*/
data &amp;amp;output;
set &amp;amp;input;
* adjust limits for each vars;
%do j=1 %to &amp;amp;nvars;
%let var=%scan(&amp;amp;vars,&amp;amp;j,%str( ));
%put Var=&amp;amp;var Llimit=&amp;amp;&amp;amp;Llimit_&amp;amp;j Ulimit=&amp;amp;&amp;amp;Ulimit_&amp;amp;j;
if &amp;amp;var &amp;lt; &amp;amp;&amp;amp;Llimit_&amp;amp;j then &amp;amp;var = &amp;amp;&amp;amp;Llimit_&amp;amp;j;
if &amp;amp;var &amp;gt; &amp;amp;&amp;amp;Ulimit_&amp;amp;j then &amp;amp;var = &amp;amp;&amp;amp;Ulimit_&amp;amp;j;
%end;
run;
%end;&lt;BR /&gt;&lt;BR /&gt;* get rid of temporaries;&lt;BR /&gt;proc datasets lib=work nolist;&lt;BR /&gt;delete _:;&lt;BR /&gt;quit;
%mend;
%outliers(Input=abcd, Vars = a b, output= test);&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;Hope it helps.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Daniel Santos&amp;nbsp;@ &lt;A href="http://www.cgd.pt" target="_blank"&gt;www.cgd.pt&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 04 Jan 2017 17:47:29 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Loop-in-Macro/m-p/322449#M71330</guid>
      <dc:creator>Daniel-Santos</dc:creator>
      <dc:date>2017-01-04T17:47:29Z</dc:date>
    </item>
  </channel>
</rss>

