用一系列整数替换数据子集

时间:2015-09-05 14:05:21

标签: subset sequence stata stata-macros

我有一个如下所示的数据集:

id    test
1     A
2     A
3     A
.     B
.     B
.     B

我想用与id对应的整数序列填充缺失值:

id    test
1     A
2     A
3     A
1     B
2     B
3     B

我最初考虑使用forvalues循环,如下所示:

forvalues i=1/3 {
    replace id = `i' if (id == .)
}

但是(出于显而易见的原因)只是在第一次迭代期间用1替换了所有缺失的值。

然后我考虑通过行索引将循环限制为数据的子集(如在R中),但Stata(?)似乎不存在此功能:

forvalues i=1/3 {
   replace id[3+`i'] = `i' if (id == .)
}

如何在Stata中完成这个看似简单的任务?

5 个答案:

答案 0 :(得分:1)

好的,考虑一下,我想我已经解决了自己的问题。最简单的解决方案是利用Stata的id - 函数而无需求助于循环:

_n

这似乎可以解决问题。

答案 1 :(得分:1)

各种可能性之一(用于重复标识符1,2,3,1,2,3 ......,这是我阅读问题的方式)是

replace id = 1 + mod(_n - 1, 3) if missing(id) 

或查看help egen seq()功能。

egen newid = seq(), to(3) 
replace id = newid if missing(id) 

在前三个观察中给出初始的1,2,3,然后

replace id = id[_n-3] if missing(id) 

也会奏效。

答案 2 :(得分:1)

或者

replace id = cond(test==test[_n-1],id[_n-1]+1,1) if missing(id)

不要求每次测试只有三个id。

答案 3 :(得分:1)

如果您的所有ID都以数字1开头,并且您真的只想对它们进行编号,那么这样的事情应该有效:

sort test id
by test: gen id2 = _n
replace id = id2 if missing(id)

请注意,您应该根据需要更改第一个排序。根据你的问题的性质,没有任何意义,测试== B的项目的顺序是“有序的”,所以你应该确保初始排序使它们按照理想的顺序。

编辑:正如Nick Cox所说,这段代码减少到一个衬里,如果这是所需的动作,这是更好的选择。为简单起见,我将其写成3行,并注意以下事实:

  1. 无论是单独执行还是使用bysort命令,都必须考虑排序,以确保标签与程序员的目标保持一致

  2. 如果您想要查看旧ID的新ID,可以直观地看到id2,以确保代码正常工作。

  3. 一旦确认了这两个,我同意下面评论中尼克的代码是可取的。

答案 4 :(得分:1)

出于指导目的,@ Nick的egen方法可以进一步推广:

clear

input id str1 test
1     A
2     A
3     A
.     B
.     B
.     C
.     C
.     C
.     C
.     D
.     E
.     E
.     E
end

levelsof test, local(test_levels)
local number_of_test_levels : word count `test_levels'

forvalues i = 1 / `number_of_test_levels' {
      count if missing(id) & test == "`=char(64 + `i')'"
      if `r(N)' != 0 {
          egen newid`i' = seq(), from(1) to(`r(N)')
          replace id = newid`i' if missing(id) & test == "`=char(64 + `i')'"
          drop newid`i'
      }
}

产生预期的输出:

sort test id  
list

     +-----------+
     | id   test |
     |-----------|
  1. |  1      A |
  2. |  2      A |
  3. |  3      A |
  4. |  1      B |
  5. |  2      B |
     |-----------|
  6. |  1      C |
  7. |  2      C |
  8. |  3      C |
  9. |  4      C |
 10. |  1      D |
     |-----------|
 11. |  1      E |
 12. |  2      E |
 13. |  3      E |
     +-----------+