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 のアイテムの順序が「順序付けられている」という意味はないので、最初の並べ替えでそれらが望ましい順序になるようにする必要があります。

編集: Nick Cox が指摘したように、このコードは 1 つのライナーに短縮されます。これは、これが目的のアクションである場合に適しています。簡単にするために3行で書きましたが、次の事実に注意してください。

  1. 並べ替えを個別に行うか、bysort コマンドで行うかに関係なく、ラベルがプログラマーの目標に沿っていることを確認するために、並べ替えを考慮する必要があります。

  2. 古い ID に対して新しい ID をスポット チェックしたい場合は、コードが機能していることを確認するためだけに、id2 を視覚的に確認できると便利です。

これらの両方が保証されたら、以下のコメントからのニックのコードが望ましいことに同意します。

于 2015-09-16T15:35:38.913 に答える
0

多分

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

テストごとに正確に 3 つの ID がある必要はありません。

于 2015-09-05T15:26:48.883 に答える
0

さまざまな可能性の1つ(識別子1、2、3、1、2、3、...を繰り返す場合、これが質問の読み方です)は

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

または関数をチェックアウトhelp egenseq()ます。

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

最初の 3 つの観測で最初の 1、2、3 が与えられた場合、

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

も機能します。

于 2015-09-05T14:57:55.840 に答える
0

わかりました、もう少し考えてみると、私は自分の問題を解決したと思います。_n最も簡単な解決策は、ループに頼らずにStata の -function を利用することです。

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

これはトリックを行うようです。

于 2015-09-05T14:55:39.283 に答える
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 に答える