<?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: Bizarre Issue with subsetting where var= macro var in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Bizarre-Issue-with-subsetting-where-var-macro-var/m-p/490903#M128598</link>
    <description>&lt;P&gt;Thanks very much for the detailed answer!!&lt;BR /&gt;&lt;BR /&gt;It's something I will be sure to keep in mind from now on.&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 29 Aug 2018 16:14:23 GMT</pubDate>
    <dc:creator>sm4</dc:creator>
    <dc:date>2018-08-29T16:14:23Z</dc:date>
    <item>
      <title>Bizarre Issue with subsetting where var= macro var</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Bizarre-Issue-with-subsetting-where-var-macro-var/m-p/490485#M128329</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I am trying to&amp;nbsp;set a dataset only where the value of a particular column (let's call it col1) is equal to the value of a macro var (let's call it test1) . This works perfectly until, bizarrely, I multiply col1 by 100 to form col2 so that now I am setting only where col2= &amp;amp;test1..&amp;nbsp;With this change, it&amp;nbsp;only works for certain rows, not others.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I know this sounds really confusing, here's the full code:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;*create test dataset;&lt;BR /&gt;proc sql;                  
          create table test                 
                   (hello char(40), col1 num);             

          insert into test                  
                   values('a',0.059)                
                   values('b',0.064)                
                   values('c',0.044)                
                   values('d',0.082)
                   values('e',0.061)                
                   values('f',0.082)                
                   values('g',0.066)                
                   values('h',0.042)
                   values('i',0.055)
;                 
quit;             

*multiply by 100, create a new column:;
data test0 (drop = col1);
         set test;
         col2 = col1*100;
run;
&lt;BR /&gt;*create macro vars out of all values of col2 above;
%let test1 = 5.9;*;
%let test2 = 6.4;
%let test3 = 4.4;*;
%let test4 = 8.2;*;
%let test5 = 6.1;
%let test6 = 6.6;*;
%let test7 = 4.2;
%let test8 = 5.5;
&lt;BR /&gt;*try to subset to each of these;
data test1;
         set test0;
         where col2 = &amp;amp;test1.;
run;
proc print;
run;

data test2;
         set test0;
         where col2 = &amp;amp;test2.;
run;
proc print;
run;

data test3;
         set test0;
         where col2 = &amp;amp;test3.;
run;
proc print;
run;

data test4;
         set test0;
         where col2 = &amp;amp;test4.;
run;
proc print;
run;

data test5;
         set test0;
         where col2 = &amp;amp;test5.;
run;
proc print;
run;

data test6;
         set test0;
         where col2 = &amp;amp;test6.;
run;
proc print;
run;

data test7;
         set test0;
         where col2 = &amp;amp;test7.;
run;
proc print;
run;

data test8;
         set test0;
         where col2 = &amp;amp;test8.;
run;
proc print;
run;&lt;/PRE&gt;&lt;P&gt;When I run it (I also had a friend run it and she got the same issue), I only get 4 datasets w/ observations, those whose macro var does not have a commented star (to the right of the let statement). Here's the log statement I get for one of the ones that did not print:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;NOTE: There were 0 observations read from the data set WORK.TEST0.&lt;BR /&gt;WHERE col2=5.9;&lt;BR /&gt;NOTE: The data set WORK.TEST1 has 0 observations and 2 variables.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I originally had tried something like:&lt;/P&gt;&lt;PRE&gt;data test1;&lt;BR /&gt; set test;&lt;BR /&gt; where col1 = &amp;amp;test1./100;&lt;BR /&gt;run;&lt;BR /&gt;proc print;&lt;BR /&gt;run;&lt;BR /&gt;&lt;BR /&gt;&lt;/PRE&gt;&lt;P&gt;Here's the log statement I get for that:&lt;/P&gt;&lt;P&gt;NOTE: There were 0 observations read from the data set WORK.TEST.&lt;BR /&gt;WHERE col1=0.059;&lt;BR /&gt;NOTE: The data set WORK.TEST1 has 0 observations and 2 variables.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;So then I&amp;nbsp;tried switching&amp;nbsp;to this col2 thing.&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&lt;BR /&gt;I must be missing something obvious, but I'm at my wit's end - would really appreciate if someone could point it out.&lt;BR /&gt;&lt;BR /&gt;&lt;BR /&gt;Thanks very much,&lt;/P&gt;</description>
      <pubDate>Tue, 28 Aug 2018 14:43:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Bizarre-Issue-with-subsetting-where-var-macro-var/m-p/490485#M128329</guid>
      <dc:creator>sm4</dc:creator>
      <dc:date>2018-08-28T14:43:57Z</dc:date>
    </item>
    <item>
      <title>Re: Bizarre Issue with subsetting where var= macro var</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Bizarre-Issue-with-subsetting-where-var-macro-var/m-p/490489#M128330</link>
      <description>&lt;P&gt;It's a numerical precision issue.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data test1;
         set test0;
         where round(col2, 0.1) = round(&amp;amp;test1., 0.1);
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Tue, 28 Aug 2018 14:51:19 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Bizarre-Issue-with-subsetting-where-var-macro-var/m-p/490489#M128330</guid>
      <dc:creator>Reeza</dc:creator>
      <dc:date>2018-08-28T14:51:19Z</dc:date>
    </item>
    <item>
      <title>Re: Bizarre Issue with subsetting where var= macro var</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Bizarre-Issue-with-subsetting-where-var-macro-var/m-p/490515#M128340</link>
      <description>&lt;P&gt;Thanks very much!!!!! So is the general rule that I need to explicitly round macro vars when comparing them to values in a dataset?&lt;/P&gt;</description>
      <pubDate>Tue, 28 Aug 2018 15:22:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Bizarre-Issue-with-subsetting-where-var-macro-var/m-p/490515#M128340</guid>
      <dc:creator>sm4</dc:creator>
      <dc:date>2018-08-28T15:22:33Z</dc:date>
    </item>
    <item>
      <title>Re: Bizarre Issue with subsetting where var= macro var</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Bizarre-Issue-with-subsetting-where-var-macro-var/m-p/490605#M128391</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/175387"&gt;@sm4&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;So is the general rule that I need to explicitly round macro vars when comparing them to values in a dataset?&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;No, it has nothing to do with macro variables. On the contrary, macro variables contain &lt;EM&gt;text&lt;/EM&gt;. Hence, they are not affected by numeric representation issues. (However, when they resolve to numeric values, such as 5.9, these values are, of course, subject to the same rules as any other numeric literal.)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The "general rule" is: Whenever SAS performs a calculation involving at least one non-integer number (such as 5.9), there is a substantial risk that, due to rounding error, the result differs slightly (by a very small number, e.g. 1E-15) from what it should be mathematically. If you apply the ROUND function to such a result (with a suitable rounding unit as the second argument), you'll &lt;EM&gt;adjust&lt;/EM&gt; it to a multiple of the rounding unit. Thus, if the original result differs slightly from this value just due to rounding error, you will now obtain the correct result.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The tiny differences mentioned above are harmful in all&amp;nbsp;sorts of &lt;EM&gt;comparisons&lt;/EM&gt;. This includes explicit comparisons using a comparison operator (=, &amp;gt;, &amp;lt;=, ~=, etc.) like in your example, but also comparisons made internally, e.g., by MERGE statements, PROC SORT, PROC COMPARE or when a numeric format is applied.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So, you could have avoided all the issues if you had rounded the result of your calculation immediately, e.g.:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;col2 = round(col1*100, 1e-9);&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Otherwise, you'd have to apply the ROUND function to &lt;FONT face="courier new,courier"&gt;col2&lt;/FONT&gt; in all comparisons (see&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/13879"&gt;@Reeza&lt;/a&gt;'s suggestion -- where it was actually redundant to round the macro variable value &lt;FONT face="courier new,courier"&gt;&amp;amp;test1&lt;/FONT&gt;, see first paragraph).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The rounding unit has to be chosen small enough not to influence results, but big enough to correct rounding errors. In your example, where you know in advance that the exact result will have (at most) one decimal, 0.1 is a suitable rounding unit, but many smaller values, e.g. 0.01&lt;SPAN&gt;=1e-2&lt;/SPAN&gt;&amp;nbsp;or 0.001=1e-3 would be suitable as well.&amp;nbsp;I chose 1e-9 in my suggestion because you could routinely use the same value if your exact result had two, three, ..., eight or even nine decimals. And it's still much greater than typical rounding errors incurred due to numerical accuracy issues (unless your results have very large absolute values, e.g. &amp;gt; 1 million).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;To see why some but not all of your comparisons failed, look at the results of the following data step (which shows the internal binary representation of the respective numbers in hexadecimal format) in the log window:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
input x;
a=x*100;
b=round(a, 0.1);
if a=b then put 'No problem with ' x= +(-1) '. a and b have the same internal representation:';
else put x= 'is problematic. a and b look like ' b +(-1) ', but their internal representations differ:';
put (a b) (=hex16. /) /;
cards;
0.059
0.064
0.044
0.082
0.061
0.066
0.042
0.055
;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Here are some more seemingly "bizarre" examples:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
if 0.1+0.7~=0.8   then put 'This';
if 1.2*1.5&amp;lt;1.8    then put 'looks';
if 9.9/3&amp;gt;3.3      then put 'quite';
if 1e-5 ne 1.0e-5 then put 'bizarre!';
run;

data _null_;
if round(0.1+0.7, 1e-9)~=0.8   then put 'This';
if round(1.2*1.5, 1e-9)&amp;lt;1.8    then put 'will';
if round(9.9/3, 1e-9)&amp;gt;3.3      then put 'not';
if 1e-5 ne round(1.0e-5, 1e-9) then put 'appear!';
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The first of the above two data steps is likely to&amp;nbsp;execute some if not all four PUT statements (this is platform dependent) because of numeric representation issues. The second step avoids these issues by using the ROUND function. None of&amp;nbsp;its PUT statements will be executed. The example involving 1.0e-5 is one of the rare cases where these issues occur even without performing a calculation.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Please see the&amp;nbsp;&lt;A href="https://documentation.sas.com/?docsetId=lefunctionsref&amp;amp;docsetTarget=p0tj6cmga7p8qln1ejh6ebevm0c9.htm&amp;amp;docsetVersion=9.4&amp;amp;locale=en" target="_blank"&gt;ROUND function documentation&lt;/A&gt;&amp;nbsp;for further information. Still more details can be found in&amp;nbsp;&lt;A href="https://documentation.sas.com/?docsetId=lrcon&amp;amp;docsetTarget=p0ji1unv6thm0dn1gp4t01a1u0g6.htm&amp;amp;docsetVersion=9.4&amp;amp;locale=en" target="_blank"&gt;Numerical Accuracy in SAS Software&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 28 Aug 2018 19:57:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Bizarre-Issue-with-subsetting-where-var-macro-var/m-p/490605#M128391</guid>
      <dc:creator>FreelanceReinh</dc:creator>
      <dc:date>2018-08-28T19:57:02Z</dc:date>
    </item>
    <item>
      <title>Re: Bizarre Issue with subsetting where var= macro var</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Bizarre-Issue-with-subsetting-where-var-macro-var/m-p/490903#M128598</link>
      <description>&lt;P&gt;Thanks very much for the detailed answer!!&lt;BR /&gt;&lt;BR /&gt;It's something I will be sure to keep in mind from now on.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 29 Aug 2018 16:14:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Bizarre-Issue-with-subsetting-where-var-macro-var/m-p/490903#M128598</guid>
      <dc:creator>sm4</dc:creator>
      <dc:date>2018-08-29T16:14:23Z</dc:date>
    </item>
  </channel>
</rss>

