<?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: Output number closest to X in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Output-number-closest-to-X/m-p/665232#M198870</link>
    <description>&lt;P&gt;Then you need to read each ID series twice.&amp;nbsp; The first time, you track the optimal value (call it _X67) in the range [6,8), and also track the optimal value in the range [5,6), call it _x5 (in case no _X67 is found).&amp;nbsp; &amp;nbsp; &amp;nbsp;Note x in the range [6,8) means 6&amp;lt;=x&amp;lt;8.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Take _x67 if it exists, otherwise take _x5 as the optimal _X value.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In the second reading of each ID, compare c_mos to _X, and set NEWVAR=C_V when C_MOS=_X.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
input
ID	C_MOS	C_V	expected_var;
datalines;
1	5.25	1	.
1	6.02	2	2
1	7.01	3	.
1	5.98	4	.
1	10	5	.
1	5	6	.
2	5.02	1	.
2	5.5	2	.
2	7.5	3	.
2	7.06	4	4
2	8	5	.
run;

data want (drop=_:);
  do until (last.id);
    set have;
    by id;
    if (6&amp;lt;=c_mos&amp;lt;8) then _x67=min(_x67,c_mos) ; else
    if (5&amp;lt;=c_mos&amp;lt;6) then _x5=max(_x5,c_mos);
  end;
  _x=coalesce(_x67,_x5);
  do until (last.id);
    set have;
    by id;
    newvar=ifn(c_mos=_x,c_v,.);
    output;
  end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The "do until (last.id)" loops, with embedded "set have; by id", each reads a complete series for a single ID.&amp;nbsp; The first loop establishes _X5 and _X67.&amp;nbsp; The second loop uses those values to identify the desired record.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If there is a tie, then two records will get a value for NEWVAR.&amp;nbsp; And if there are no values in the range [5,8) then that ID will have only missing values for NEWVAR.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 26 Jun 2020 03:53:18 GMT</pubDate>
    <dc:creator>mkeintz</dc:creator>
    <dc:date>2020-06-26T03:53:18Z</dc:date>
    <item>
      <title>Output number closest to X</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Output-number-closest-to-X/m-p/665025#M198768</link>
      <description>&lt;P&gt;Using SAS 9.4&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I have a variable C_mos indicated the months from event A to event B and I want to create a new variable and choose the C_v score that is closest to 6 month between 5-7 months and leave the rest blank. However, I want to prioritize 6 months as the closest but then prioritize 7 months over 5 months as they have reached the 6 month threshold. So I envision the data to look like below:&lt;/P&gt;
&lt;TABLE style="border-collapse: collapse; width: 192pt;" border="0" width="256" cellspacing="0" cellpadding="0"&gt;
&lt;TBODY&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD width="64" height="20" style="height: 15.0pt; width: 48pt;"&gt;ID&lt;/TD&gt;
&lt;TD width="64" style="width: 48pt;"&gt;C_MOS&lt;/TD&gt;
&lt;TD width="64" style="width: 48pt;"&gt;C_V&lt;/TD&gt;
&lt;TD width="64" style="width: 48pt;"&gt;newvar&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD height="20" align="right" style="height: 15.0pt;"&gt;1&lt;/TD&gt;
&lt;TD align="right"&gt;5.25&lt;/TD&gt;
&lt;TD align="right"&gt;1&lt;/TD&gt;
&lt;TD&gt;.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD height="20" align="right" style="height: 15.0pt;"&gt;1&lt;/TD&gt;
&lt;TD align="right"&gt;6.02&lt;/TD&gt;
&lt;TD align="right"&gt;2&lt;/TD&gt;
&lt;TD align="right"&gt;2&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD height="20" align="right" style="height: 15.0pt;"&gt;1&lt;/TD&gt;
&lt;TD align="right"&gt;7.01&lt;/TD&gt;
&lt;TD align="right"&gt;3&lt;/TD&gt;
&lt;TD&gt;.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD height="20" align="right" style="height: 15.0pt;"&gt;1&lt;/TD&gt;
&lt;TD align="right"&gt;5.98&lt;/TD&gt;
&lt;TD align="right"&gt;4&lt;/TD&gt;
&lt;TD&gt;.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD height="20" align="right" style="height: 15.0pt;"&gt;1&lt;/TD&gt;
&lt;TD align="right"&gt;10&lt;/TD&gt;
&lt;TD align="right"&gt;5&lt;/TD&gt;
&lt;TD&gt;.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD height="20" align="right" style="height: 15.0pt;"&gt;1&lt;/TD&gt;
&lt;TD align="right"&gt;5&lt;/TD&gt;
&lt;TD align="right"&gt;6&lt;/TD&gt;
&lt;TD&gt;.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD height="20" align="right" style="height: 15.0pt;"&gt;2&lt;/TD&gt;
&lt;TD align="right"&gt;5.02&lt;/TD&gt;
&lt;TD align="right"&gt;1&lt;/TD&gt;
&lt;TD&gt;.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD height="20" align="right" style="height: 15.0pt;"&gt;2&lt;/TD&gt;
&lt;TD align="right"&gt;5.5&lt;/TD&gt;
&lt;TD align="right"&gt;2&lt;/TD&gt;
&lt;TD&gt;.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD height="20" align="right" style="height: 15.0pt;"&gt;2&lt;/TD&gt;
&lt;TD align="right"&gt;7.5&lt;/TD&gt;
&lt;TD align="right"&gt;3&lt;/TD&gt;
&lt;TD&gt;.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD height="20" align="right" style="height: 15.0pt;"&gt;2&lt;/TD&gt;
&lt;TD align="right"&gt;7.06&lt;/TD&gt;
&lt;TD align="right"&gt;4&lt;/TD&gt;
&lt;TD align="right"&gt;4&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR style="height: 15.0pt;"&gt;
&lt;TD height="20" align="right" style="height: 15.0pt;"&gt;2&lt;/TD&gt;
&lt;TD align="right"&gt;8&lt;/TD&gt;
&lt;TD align="right"&gt;5&lt;/TD&gt;
&lt;TD&gt;.&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So as this shows the closest to 6.0 is taken as long as 6 is achieved but where there is not a 6 month score month 7 is given the priority over month 5 even though the month 5 (5.02) is closer to 6.0 than then 7 month (7.06). Thank you&lt;/P&gt;</description>
      <pubDate>Thu, 25 Jun 2020 14:21:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Output-number-closest-to-X/m-p/665025#M198768</guid>
      <dc:creator>GS2</dc:creator>
      <dc:date>2020-06-25T14:21:51Z</dc:date>
    </item>
    <item>
      <title>Re: Output number closest to X</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Output-number-closest-to-X/m-p/665042#M198775</link>
      <description>&lt;P&gt;You want to choose "c&lt;SPAN&gt;_v score that is closest to 6 month", yet for ID=2 you choose 7.06 rather than the much closer 5.5.&amp;nbsp; I don't understand the rule.&amp;nbsp; I presume you would therefore also want 6.9 over 5.5.&amp;nbsp; &amp;nbsp;In what situation would you choose a value 5.5?&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 25 Jun 2020 15:18:24 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Output-number-closest-to-X/m-p/665042#M198775</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2020-06-25T15:18:24Z</dc:date>
    </item>
    <item>
      <title>Re: Output number closest to X</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Output-number-closest-to-X/m-p/665059#M198783</link>
      <description>I want the the 6 month first, then 7 month and finally 5 month. So, in your example while 5.5 is technically closer it has not reached the 6 month threshold and therefore a 7.06 would be chosen. So it almost a hierarchy where I want the closest C_mos between 6-6.99, if not available then 7-7.99, if not available then 5-5.9. But within each group I would want the closest to 6.0 per ID. Does that make more sense? Thank you</description>
      <pubDate>Thu, 25 Jun 2020 16:15:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Output-number-closest-to-X/m-p/665059#M198783</guid>
      <dc:creator>GS2</dc:creator>
      <dc:date>2020-06-25T16:15:54Z</dc:date>
    </item>
    <item>
      <title>Re: Output number closest to X</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Output-number-closest-to-X/m-p/665229#M198868</link>
      <description>&lt;P&gt;Something like below could work.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
  infile datalines dsd;
  input ID C_MOS C_V expected;
datalines;
1,5.25,1,.
1,6.02,2,2
1,7.01,3,.
1,5.98,4,.
1,10,5,.
1,5,6,.
2,5.02,1,.
2,5.5,2,.
2,7.5,3,.
2,7.06,4,4
2,8,5,.
3,9.5,2,.
3,4.5,3,.
3,3.06,4,.
3,8,5,.
;

proc sql;
/*  create table want as*/
    select 
      o.*,
      i.c_v as derived
    from have o
    left join
    (
      select id,c_v
      from
      (
      select 
        *,
        case(floor(c_mos))
          when 6 then 10000-c_mos
          when 7 then 1000-c_mos
          when 5 then 100-c_mos
          else .
          end as calc
      from have
      )
      group by id
      having 
        max(calc) = calc 
        and not missing(calc)
    ) i
    on o.id=i.id and o.c_v=i.c_v
    ;
quit;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 26 Jun 2020 03:40:54 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Output-number-closest-to-X/m-p/665229#M198868</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2020-06-26T03:40:54Z</dc:date>
    </item>
    <item>
      <title>Re: Output number closest to X</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Output-number-closest-to-X/m-p/665232#M198870</link>
      <description>&lt;P&gt;Then you need to read each ID series twice.&amp;nbsp; The first time, you track the optimal value (call it _X67) in the range [6,8), and also track the optimal value in the range [5,6), call it _x5 (in case no _X67 is found).&amp;nbsp; &amp;nbsp; &amp;nbsp;Note x in the range [6,8) means 6&amp;lt;=x&amp;lt;8.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Take _x67 if it exists, otherwise take _x5 as the optimal _X value.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In the second reading of each ID, compare c_mos to _X, and set NEWVAR=C_V when C_MOS=_X.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data have;
input
ID	C_MOS	C_V	expected_var;
datalines;
1	5.25	1	.
1	6.02	2	2
1	7.01	3	.
1	5.98	4	.
1	10	5	.
1	5	6	.
2	5.02	1	.
2	5.5	2	.
2	7.5	3	.
2	7.06	4	4
2	8	5	.
run;

data want (drop=_:);
  do until (last.id);
    set have;
    by id;
    if (6&amp;lt;=c_mos&amp;lt;8) then _x67=min(_x67,c_mos) ; else
    if (5&amp;lt;=c_mos&amp;lt;6) then _x5=max(_x5,c_mos);
  end;
  _x=coalesce(_x67,_x5);
  do until (last.id);
    set have;
    by id;
    newvar=ifn(c_mos=_x,c_v,.);
    output;
  end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;The "do until (last.id)" loops, with embedded "set have; by id", each reads a complete series for a single ID.&amp;nbsp; The first loop establishes _X5 and _X67.&amp;nbsp; The second loop uses those values to identify the desired record.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If there is a tie, then two records will get a value for NEWVAR.&amp;nbsp; And if there are no values in the range [5,8) then that ID will have only missing values for NEWVAR.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 26 Jun 2020 03:53:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Output-number-closest-to-X/m-p/665232#M198870</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2020-06-26T03:53:18Z</dc:date>
    </item>
  </channel>
</rss>

