{"id":156,"date":"2020-01-12T11:48:10","date_gmt":"2020-01-12T09:48:10","guid":{"rendered":"http:\/\/jvdl.me\/wordpress\/?p=156"},"modified":"2023-05-16T11:31:39","modified_gmt":"2023-05-16T09:31:39","slug":"sas-and-the-forward-re-scan-rule","status":"publish","type":"post","link":"https:\/\/jvdl.me\/blog\/?p=156","title":{"rendered":"SAS and the Forward Re-scan Rule"},"content":{"rendered":"\n<p>The &#8220;Forward Re-scan Rule&#8221; (FRR) is used by SAS to resolve macro variables over several passes. This is especially useful when having one macro variable point to another macro variable, or when trying to resolve numbered macro variables.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Advanced SAS - The Forward Rescan Rule\" width=\"960\" height=\"540\" src=\"https:\/\/www.youtube.com\/embed\/un_fCt4PPDo?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>The SAS Advanced Prep Guide summarises the FRR as follows:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>When multiple ampersands or percent signs precede a name token, the macro processor resolves two ampersands (&amp;&amp;) to one ampersand (&amp;), and re-scans the reference.<\/li>\n\n\n\n<li>To re-scan a reference, the macro processor scans and resolves tokens from left to right from the point where multiple ampersands or percent signs are coded, until no more triggers can be resolved.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Example: numbered list of macro variables<\/h2>\n\n\n\n<p>To illustrate this example for a numbered list of macro variables, we can load each unique car manufacturer from SASHELP.CARS into a unique macro variable:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas line-numbers\">data cars;\n\tset sashelp.cars;\nrun;\n\nproc sql;\n\tselect distinct make into :car1-:car999\n\tfrom cars;\nquit;\n\n%put Number of obs = &amp;sqlobs;<\/code><\/pre>\n\n\n\n<p>SAS will not create more macro variables than necessary. We have accounted for the possibility of 999 distinct manufacturers, but in reality the dataset contains only 38. SAS will only reserve the variables car1 to car38.<\/p>\n\n\n\n<p>We can loop through the variables we&#8217;ve just created, by using the FRR. To further illustrate, also turn on the MPRINT, MLOGIC, and SYMBOLGEN options. Note the use of the double ampersand (&amp;&amp;).<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas line-numbers\">options mprint mlogic symbolgen;\n%macro printCars;\n\t%do i = 1 %to &amp;sqlobs;\n\t\t%put &amp;&amp;car&amp;i;\n\t%end;\n%mend printCars;\n%printCars;<\/code><\/pre>\n\n\n\n<pre title=\"SAS Log Output\" class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas\"> MLOGIC(PRINTCARS):  %DO loop beginning; index variable I; start value is 1; stop value is 38; by value is 1.  \n MLOGIC(PRINTCARS):  %PUT &amp;&amp;car&amp;i\n SYMBOLGEN:  &amp;&amp; resolves to &amp;.\n SYMBOLGEN:  Macro variable I resolves to 1\n SYMBOLGEN:  Macro variable CAR1 resolves to Acura<\/code><\/pre>\n\n\n\n<p>From the log output, we can trace the FRR resolution as follows:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>&amp;&amp;car&amp;i<\/li>\n\n\n\n<li>&amp;car1<\/li>\n\n\n\n<li>Acura<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Example: nested macro variables<\/h2>\n\n\n\n<p>Suppose we declare the following macro variables:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas line-numbers\">%let one = two;\n%let two = three;\n%let three = one;<\/code><\/pre>\n\n\n\n<p>To test your understanding of the FRR, can you accurately predict the resolution of these macro variables?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas line-numbers\">%put &amp;one;\n%put &amp;&amp;one;\n%put &amp;&amp;&amp;one;\n%put &amp;&amp;&amp;&amp;one;\n%put &amp;&amp;&amp;&amp;&amp;one;\n%put &amp;&amp;&amp;&amp;&amp;&amp;one;\n%put &amp;&amp;&amp;&amp;&amp;&amp;&amp;one;\n%put &amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;one;\n%put &amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;one;\n%put &amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;one;<\/code><\/pre>\n\n\n\n<p>The FRR will process from left to right. Any double ampersand (&amp;&amp;) will be resolved to a single ampersand (&amp;) and any instances of a single ampersand will be resolved.<\/p>\n\n\n\n<p>Let&#8217;s work through two examples together.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas\">%put &amp;&amp;&amp;&amp;&amp;one;<\/code><\/pre>\n\n\n\n<p>To better organise our desk-checking of the code, we can rewrite it in a more human-readable, and -friendly format:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas\">&amp;&amp; &amp;&amp; &amp;one;<\/code><\/pre>\n\n\n\n<p>Each double ampersand (&amp;&amp;) resolves to a single ampersand, and the remaining single ampersand and macro reference is resolved.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas\">&amp; &amp; two;<\/code><\/pre>\n\n\n\n<p>The remaining two ampersands are resolved to a single ampersand:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas\">&amp;two;<\/code><\/pre>\n\n\n\n<p>Which resolves to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas\">three<\/code><\/pre>\n\n\n\n<p>And upon checking the SAS log, we can see our result has been confirmed:<\/p>\n\n\n\n<pre title=\"SAS Log Output\" class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas\">%put &amp;&amp;&amp;&amp;&amp;one;\nthree<\/code><\/pre>\n\n\n\n<p>As a final example, let&#8217;s work through:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas\">%put &amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;one;<\/code><\/pre>\n\n\n\n<p>Organise the ampersands into a more human-readable format, group and resolve double ampersands, and finally resolve remaining single ampersands:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas\">&amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;one;\n&amp;&amp; &amp;&amp; &amp;&amp; &amp;&amp; one;\n&amp; &amp; &amp; &amp; one;     compress ==&gt;  &amp;&amp; &amp;&amp; one;\n&amp; &amp; one;         compress ==&gt;  &amp;&amp; one;\n&amp;one;\ntwo<\/code><\/pre>\n\n\n\n<p>Our result is once again confirmed by the SAS log:<\/p>\n\n\n\n<pre title=\"SAS Log Output\" class=\"wp-block-code\"><code lang=\"sas\" class=\"language-sas\">%put &amp;&amp;&amp;&amp;&amp;&amp;&amp;&amp;one;\ntwo<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>The &#8220;Forward Re-scan Rule&#8221; (FRR) is used by SAS to resolve macro variables over several passes. This is especially useful when having one macro variable point to another macro variable, or when trying to resolve numbered macro variables. The SAS Advanced Prep Guide summarises the FRR as follows: Example: numbered list of macro variables To [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[53,54],"tags":[],"class_list":["post-156","post","type-post","status-publish","format-standard","hentry","category-programming","category-sas"],"_links":{"self":[{"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/posts\/156","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=156"}],"version-history":[{"count":8,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/posts\/156\/revisions"}],"predecessor-version":[{"id":508,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=\/wp\/v2\/posts\/156\/revisions\/508"}],"wp:attachment":[{"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=156"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=156"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jvdl.me\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=156"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}