0

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

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 中完成这个看似简单的任务?

4

5 回答 5

0

如果你所有的 ID 都以数字 1 开头,而你真的只想给它们编号,这样的事情应该可以工作:

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

请注意,您应该根据需要更改第一个排序。根据您的问题的性质, test == B 的项目的顺序是“有序的”是没有意义的,因此您应该确保初始排序将它们置于理想的顺序。

编辑:正如尼克考克斯所指出的,这个代码减少到一个衬里,如果这是所需的动作,这是最好的。为了简单起见,我把它写成 3 行,并注意以下事实:

  1. 必须考虑排序,无论您是独立执行还是在 bysort 命令中执行,以确保标签与程序员的目标一致

  2. 如果您想对旧 ID 进行抽查,那么能够直观地看到 id2 可能很有用,以确保代码正常工作。

一旦这两个都得到保证,我同意下面评论中尼克的代码更可取。

于 2015-09-16T15:35:38.913 回答
0

各种可能性之一(用于重复标识符 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) 

也将工作。

于 2015-09-05T14:57:55.840 回答
0

出于指导目的,@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 |
     +-----------+
于 2018-06-05T13:29:05.437 回答
0

好的,再想一想,我想我已经解决了我自己的问题。最简单的解决方案利用 Stata 的_n-function 而不诉诸循环:

replace id = _n - 3 if (id == .)

这似乎可以解决问题。

于 2015-09-05T14:55:39.283 回答
0

也许

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

这并不要求每个测试恰好有三个 id。

于 2015-09-05T15:26:48.883 回答