title: Simple way to do a weighted hot deck imputation in Stata?
body: <p>I'd like to do a simple weighted hot deck imputation in Stata.  In SAS the equivalent command would be the following (and note that this is a newer SAS feature, beginning with SAS/STAT 14.1 in 2015 or so):</p>
  
  <pre><code>proc surveyimpute method=hotdeck(selection=weighted); 
  </code></pre>
  
  <p>For clarity then, the basic requirements are:</p>
  
  <ol>
  <li><p>Imputations most be row-based or simultaneous.  If row 1 donates <code>x</code> to row 3, then it must also donate <code>y</code>.</p></li>
  <li><p>Must account for weights.  A donor with weight=2 should be twice as likely to be selected as a donor with weight=1</p></li>
  </ol>
  
  <p>I'm assuming the missing data is rectangular.  In other words, if the set of potentially missing variables consists of <code>x</code> and <code>y</code> then either both are missing or neither is missing.  Here's some code to generate sample data.</p>
  
  <pre><code>global miss_vars "wealth income"
  global weight    "weight"
  
  set obs 6
  gen id = _n
  gen type = id &gt; 3
  gen income = 5000 * _n
  gen wealth = income * 4 + 500 * uniform()
  gen weight = 1
  replace weight = 4 if mod(id-1,3) == 0
  
  // set income &amp; wealth missing every 3 rows
  gen impute = mod(_n,3) == 0
  foreach v in $miss_vars {
      replace `v' = . if impute == 1
  }
  </code></pre>
  
  <p>Data looks like this:</p>
  
  <pre><code>            id       type     income     wealth     weight     impute
    1.         1          0       5000   20188.03          4          0
    2.         2          0      10000   40288.81          1          0
    3.         3          0          .          .          1          1
    4.         4          1      20000   80350.85          4          0
    5.         5          1      25000   100378.8          1          0
    6.         6          1          .          .          1          1
  </code></pre>
  
  <p>So in other words, we need to randomly (with weighting) select a donor <strong>of the same type</strong> observation for each row with missing values and use that donor to fill in both income and wealth values.  In practical use the generation of the type variable is of course it's own problem, but I'm keeping that very simple here to focus on the main issue.</p>
  
  <p>For example, row 3 might look like either of the following post hotdeck (because it fills both income and wealth from row 1, or from row 2 (but in contrast would never take income from row 1 and the wealth from row 2):</p>
  
  <pre><code>  3.         3          0       5000   20188.03          1          1
    3.         3          0      10000   40288.81          1          1
  </code></pre>
  
  <p>Also, since row 1 has weight=4 and row 2 has weight=1, row 1 should be the donor 80% of the time and row 2 should be the donor 20% of the time.</p>