<?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: Replacing missing character values with closest non-missing values within the same DMRN in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Replacing-missing-character-values-with-closest-non-missing/m-p/924189#M363775</link>
    <description>&lt;P&gt;In the absence of sample data in the form of a working DATA step, this should work.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data vneed / view=vneed;
  set have (rename=(alcohol_user=_alc_user));
  by dmrn;
  where _alc_user^=' ';
  dx_date=ifn(first.dmrn=1,'01jan1900'd,mean(dx_date,lag(dx_date)),'01jan1900'd);
run;

data want (drop=_:);
  set have (in=inh)  vneed (in=inv keep=dmrn dx_date);
  by dmrn dx_date;
  if inv then set vneed (keep=_alc_user);
  if inh;
  if alcohol_user=' ' then alcohol_user=_alc_user;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;How does this work?&amp;nbsp; &amp;nbsp;Data set view VNEED has &lt;EM&gt;&lt;STRONG&gt;only non-missing&lt;/STRONG&gt;&lt;/EM&gt; alcohol_user data (renamed to _alc_user).&amp;nbsp; But its &lt;EM&gt;&lt;STRONG&gt;dx_dates are changed&lt;/STRONG&gt;&lt;/EM&gt;.&amp;nbsp; &amp;nbsp;dx_date is &lt;EM&gt;&lt;STRONG&gt;reset to halfway between&lt;/STRONG&gt;&lt;/EM&gt; the current valid obs and the prior valid obs ("valid" means non-missing _alc_user for the same DMRN).&amp;nbsp; &amp;nbsp;And in the case of the first non-missing _ALC_USER for a given DMRN, the DX_DATE is set back to 01jan1900.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As a result, when VNEED is interleaved with HAVE (the SET HAVE ... VNEED; BY DMRN DX_DATE statements), one can use the IF INV condition to read in (and retain) the non-missing _ALC_USER variable, until the next IF INV is satisfied.&amp;nbsp; And since the DX_DATEs in vneed are at halfway points between observed DX_DATEs, missing ALCOHOL_USER will always get the &lt;EM&gt;&lt;STRONG&gt;closest DX_DATE&lt;/STRONG&gt;&lt;/EM&gt; with non-missing values.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Important note:&amp;nbsp; the first SET statement in DATA WANT, must NOT read in _ALC_USER.&amp;nbsp; Therefore _ALC_USER is not automatically replaced, until the IF INV condition is satisfied.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Edited note: This assume data are sorted by DMRN/DX_DATE.&lt;/P&gt;</description>
    <pubDate>Sat, 13 Apr 2024 16:38:25 GMT</pubDate>
    <dc:creator>mkeintz</dc:creator>
    <dc:date>2024-04-13T16:38:25Z</dc:date>
    <item>
      <title>Replacing missing character values with closest non-missing values within the same DMRN</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-missing-character-values-with-closest-non-missing/m-p/920218#M362762</link>
      <description>&lt;P&gt;I tried to replace missing character values (alcohol_user) with the&amp;nbsp; closest non-missing values (either before or after) within the same DMRN.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This is how my data set looks like:&lt;/P&gt;&lt;P&gt;DMRN&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DX_DATE&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ALCOHOL_USER&lt;/P&gt;&lt;P&gt;16&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 28FEB2017&amp;nbsp;&lt;/P&gt;&lt;P&gt;16&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 13JUN2017&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;No&lt;/P&gt;&lt;P&gt;16&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 26SEP2017&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;No&lt;/P&gt;&lt;P&gt;24&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;12MAY2014&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; No&lt;/P&gt;&lt;P&gt;24&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;28MAR2016&lt;/P&gt;&lt;P&gt;24&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;25AUG2017&lt;/P&gt;&lt;P&gt;25&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;02SEP2021&lt;/P&gt;&lt;P&gt;25&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;29NOV2021&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Yes&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The outcome that I would like it to be:&lt;/P&gt;&lt;P&gt;DMRN&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DX_DATE&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ALCOHOL_USER&lt;/P&gt;&lt;P&gt;16&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 28FEB2017&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; No&lt;/P&gt;&lt;P&gt;16&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 13JUN2017&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;No&lt;/P&gt;&lt;P&gt;16&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 26SEP2017&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;No&lt;/P&gt;&lt;P&gt;24&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;12MAY2014&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; No&lt;/P&gt;&lt;P&gt;24&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;28MAR2016&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;No&lt;/P&gt;&lt;P&gt;24&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;25AUG2017&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; No&lt;/P&gt;&lt;P&gt;25&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;02SEP2021&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Yes&lt;/P&gt;&lt;P&gt;25&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;29NOV2021&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Yes&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried this code but it didn't work out. Any help would be very appreciated. Thank you!&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Screenshot 2024-03-13 001420.png" style="width: 403px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/94614iF661167DAB7D8F4F/image-size/large?v=v2&amp;amp;px=999" role="button" title="Screenshot 2024-03-13 001420.png" alt="Screenshot 2024-03-13 001420.png" /&gt;&lt;/span&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 13 Mar 2024 23:16:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-missing-character-values-with-closest-non-missing/m-p/920218#M362762</guid>
      <dc:creator>tan-wongv</dc:creator>
      <dc:date>2024-03-13T23:16:43Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing missing character values with closest non-missing values within the same DMRN</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-missing-character-values-with-closest-non-missing/m-p/924189#M363775</link>
      <description>&lt;P&gt;In the absence of sample data in the form of a working DATA step, this should work.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data vneed / view=vneed;
  set have (rename=(alcohol_user=_alc_user));
  by dmrn;
  where _alc_user^=' ';
  dx_date=ifn(first.dmrn=1,'01jan1900'd,mean(dx_date,lag(dx_date)),'01jan1900'd);
run;

data want (drop=_:);
  set have (in=inh)  vneed (in=inv keep=dmrn dx_date);
  by dmrn dx_date;
  if inv then set vneed (keep=_alc_user);
  if inh;
  if alcohol_user=' ' then alcohol_user=_alc_user;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;How does this work?&amp;nbsp; &amp;nbsp;Data set view VNEED has &lt;EM&gt;&lt;STRONG&gt;only non-missing&lt;/STRONG&gt;&lt;/EM&gt; alcohol_user data (renamed to _alc_user).&amp;nbsp; But its &lt;EM&gt;&lt;STRONG&gt;dx_dates are changed&lt;/STRONG&gt;&lt;/EM&gt;.&amp;nbsp; &amp;nbsp;dx_date is &lt;EM&gt;&lt;STRONG&gt;reset to halfway between&lt;/STRONG&gt;&lt;/EM&gt; the current valid obs and the prior valid obs ("valid" means non-missing _alc_user for the same DMRN).&amp;nbsp; &amp;nbsp;And in the case of the first non-missing _ALC_USER for a given DMRN, the DX_DATE is set back to 01jan1900.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As a result, when VNEED is interleaved with HAVE (the SET HAVE ... VNEED; BY DMRN DX_DATE statements), one can use the IF INV condition to read in (and retain) the non-missing _ALC_USER variable, until the next IF INV is satisfied.&amp;nbsp; And since the DX_DATEs in vneed are at halfway points between observed DX_DATEs, missing ALCOHOL_USER will always get the &lt;EM&gt;&lt;STRONG&gt;closest DX_DATE&lt;/STRONG&gt;&lt;/EM&gt; with non-missing values.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Important note:&amp;nbsp; the first SET statement in DATA WANT, must NOT read in _ALC_USER.&amp;nbsp; Therefore _ALC_USER is not automatically replaced, until the IF INV condition is satisfied.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Edited note: This assume data are sorted by DMRN/DX_DATE.&lt;/P&gt;</description>
      <pubDate>Sat, 13 Apr 2024 16:38:25 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-missing-character-values-with-closest-non-missing/m-p/924189#M363775</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2024-04-13T16:38:25Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing missing character values with closest non-missing values within the same DMRN</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-missing-character-values-with-closest-non-missing/m-p/924214#M363790</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/31461"&gt;@mkeintz&lt;/a&gt;&amp;nbsp;Appears to be a "duplicate" question with an accepted solution &lt;A href="https://communities.sas.com/t5/New-SAS-User/Assign-the-same-value-to-identical-IDs-with-date-difference-less/m-p/922523#M41404" target="_self"&gt;here&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Sat, 13 Apr 2024 00:01:59 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-missing-character-values-with-closest-non-missing/m-p/924214#M363790</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2024-04-13T00:01:59Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing missing character values with closest non-missing values within the same DMRN</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-missing-character-values-with-closest-non-missing/m-p/924238#M363800</link>
      <description>&lt;P&gt;Load your data into a date-indexed array:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let start = %sysfunc(inputn(2000-01-01,yymmdd10.));
%let end = %sysfunc(inputn(2024-12-31,yymmdd10.));

data want;
array vals {&amp;amp;start.:&amp;amp;end.} $3 _temporary_;
do i = &amp;amp;start. to &amp;amp;end.;
  vals{i} = "";
end;
do until (last.dmrn);
  set have;
  by dmrn;
  vals{dx_date} = alcohol_user;
end;
do until (last.dmrn);
  set have;
  by dmrn;
  if alcohol_user = ""
  then do;
  dist = &amp;amp;end. - &amp;amp; start.;
  do i = &amp;amp;start. to &amp;amp;end.;
    if vals{i} ne "" and abs(i - dx_date) &amp;lt; dist
    then do;
      dist = abs(i - dx_date);
      alcohol_user = vals{i};
    end;
  end;
  output;
end;
drop dist i;
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Untested, posted from my tablet.&lt;/P&gt;</description>
      <pubDate>Sat, 13 Apr 2024 08:34:49 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-missing-character-values-with-closest-non-missing/m-p/924238#M363800</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2024-04-13T08:34:49Z</dc:date>
    </item>
    <item>
      <title>Re: Replacing missing character values with closest non-missing values within the same DMRN</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Replacing-missing-character-values-with-closest-non-missing/m-p/924250#M363802</link>
      <description>&lt;BLOCKQUOTE&gt;&lt;HR /&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/12447"&gt;@Patrick&lt;/a&gt;&amp;nbsp;wrote:&lt;BR /&gt;
&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/31461"&gt;@mkeintz&lt;/a&gt;&amp;nbsp;Appears to be a "duplicate" question with an accepted solution &lt;A href="https://communities.sas.com/t5/New-SAS-User/Assign-the-same-value-to-identical-IDs-with-date-difference-less/m-p/922523#M41404" target="_self"&gt;here&lt;/A&gt;&lt;/P&gt;
&lt;HR /&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;True.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The code I offered above takes advantage of the fact that the data are sorted, which AFAICT, SQL does not.&amp;nbsp; There is likely to be a significant performance benefit.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It uses the same technique as the "carry the future back" section in a presentation I gave at PharmaSUG 2019&amp;nbsp;(&lt;A href="https://www.lexjansen.com/pharmasug/2019/BP/PharmaSUG-2019-BP-302.pdf" target="_self"&gt;History Carried Forward, Future Carried Back: Mixing Time Series of Differing Frequencies&lt;/A&gt;), except it mixes a subset of a series with the whole series.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;One of the reasons I have come to promote this technique is that it is fairly simple to expand mixing of two series to three or more series, which I think can become rather messy in SQL.&amp;nbsp; Applying it to finding the "closest" value only explicitly occurred to me when contemplating this OP's post.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Plug:&amp;nbsp; I'll be presenting content from the PharmaSUG paper at next month's Boston Area SAS User's group.&amp;nbsp; And I hope to include an example of "finding the closest" as well.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sat, 13 Apr 2024 15:38:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Replacing-missing-character-values-with-closest-non-missing/m-p/924250#M363802</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2024-04-13T15:38:20Z</dc:date>
    </item>
  </channel>
</rss>

