2016-05-28 10 views
0

私のデータセットは、次の変数が含まれているとします比較観測

set obs 100 
generate var1 = rnormal() 
generate var2 = rnormal() 

input double(id var5 var6) 
1 1052 17.348 
2 1288 17.378 
3 1536 17.387 
4 2028 17.396 
5 1810 17.402 
6 2034 17.407 
end 

input double(id var5 var6) 
1 10000 0.4 
2 22000 0.55 
3 25000 0.5 
4 40000 1 
end 

私は、少なくとも一つの他のidと比較VAR5の増加値とvar6の減少値を持つIDの行を削除する必要があります。最初の例では、2028と17.396の4を削除する必要があります。 2番目の例では、数字3を25000と0.5で削除する必要があります。除去した後、3つの変数の観測結果は次のようになります。

1 1052 17.348 
2 1288 17.378 
3 1536 17.387 
5 1810 17.402 
6 2034 17.407 

1 10000 0.4 
2 22000 0.55 
4 40000 1 

var1var2はそのまま残るべきです。

どうすればいいですか?

+0

あなたの判断基準を定義しますか?この例では、ドロップされた観測値はvar5の最小値であり、負のvar6を持つ唯一のobsです。あなたが作ろうとしている他の観測(ids)との比較は何ですか?ドロップしたい他のいくつかのIDを使用して、あなたの例を拡張することを検討してください。 – lmo

+0

'var5の値が大きくなり、var6の値が他の少なくとも1つの値よりも小さくなっています。 'それは私には分かりません –

+0

' var5> min(var1、var2)&var6 ChrisP

答えて

0

完全に無関係の変数を持つデータセットがあると思われるため、これは非常に奇妙です。変数var1var2の初期観測データセットがあり、次に変数がvar5var6の6つの観測データを含む2次データセットがあります。あなたの目的は、変数var5var6に含まれる値に対してのみ、観測値を削除するように見えます。これは、Stataは任意の時点でメモリ内に単一のデータセットしか持たないため、スプレッドシートのように見えます。

ドロップする観測値を特定するタスクでは、各観測値をvar5var6の値と比較し、他のすべての観測値とそれらの変数の値を比較する必要があります。これは、crossコマンドを使用してすべてのペアの組み合わせを形成することによってStataで実行できます。

var5var6の値に基づいて観測を削除するタスクを実行するために、提示したとおりに編成されたデータで始まり、2つのデータセットを分離するソリューションです。データセットは完全に無関係であるように見えるので、不一致のmergeがデータの再結合に使用されます。

clear 
set obs 100 
generate var1 = rnormal() 
generate var2 = rnormal() 

input double(id var5 var6) 
1 1052 17.348 
2 1288 17.378 
3 1536 17.387 
4 2028 17.396 
5 1810 17.402 
6 2034 17.407 
end 
tempfile main 
save "`main'" 

* extract secondary dataset 
keep id var5 var6 
keep if !mi(id) 
tempfile data2 
save "`data2'" 

* form all pairwise combinations 
rename * =_0 
cross using "`data2'" 

* identify cases where there's an increase in var5 and decrease in var6 
gen todrop = var5_0 > var5 & var6_0 < var6 

* drop id if there's at least one case, reduce to original obs and vars 
bysort id_0 (todrop): keep if !todrop[_N] 
keep if id == id_0 
keep id var5 var6 
list 

* now merge back with original data, use unmatched merge since 
* secondary data is unrelated 
sort id 
tempfile newdata2 
save "`newdata2'" 
use "`main'", clear 
drop id var5 var6 
merge 1:1 _n using "`newdata2'", nogen 
+0

あなたの貢献に感謝します。あなたのコードは、私がしたいことを達成するために表示されます、私はクロスコマンドを認識していませんでした。私はさらにそれをテストし、私はさらに質問がある場合あなたに戻って取得します。レコードには、変数var1とvar2を持つデータセットが1つしかありません。変数var5とvar6は後で同じデータセットで生成されます。私はマージする必要がある一時的なデータセットを使わなくても同じ結果を得ることができるのだろうかと思います。 – user5751111

0

これは、データセットを分割しないでこれを行う方法の1つです。落とす観察を特定するタスクは、すべてのペアごとの比較を行うためにダブルループを必要とします。しかし、Stataには、わずかな変数の観測を削除するコマンドはありません。次の例では、私が保存してから値をクリアし、Stataの変数に戻し観測を保存するために観測をロードするためにマタに切り替える:また

clear 
set obs 100 
generate var1 = rnormal() 
generate var2 = rnormal() 

input double(id var5 var6) 
1 1052 17.348 
2 1288 17.378 
3 1536 17.387 
4 2028 17.396 
5 1810 17.402 
6 2034 17.407 
end 

* an observation index 
gen obsid = _n if !mi(id) 

* identify observations to drop 
gen todrop = 0 if !mi(id) 
sum obsid, meanonly 
local n = r(N) 
quietly forvalues i = 1/`n' { 
    forvalues j = 1/`n' { 
    replace id = . if var5[`i'] > var5[`j'] & var6[`i'] < var6[`j'] & _n == `i' 
    } 
} 

* take a trip to Mata to load the data to keep and store it back from there 
mata: 
// load data, ignore observations with missing values 
X = st_data(., ("id","var5","var6"), 0) 

// set all obs to missing 
st_store(., ("id","var5","var6") ,J(st_nobs(),3,.)) 

// store non-missing values back into the variables 
st_store((1,rows(X)), ("id","var5","var6") ,X) 
end 

drop obsid todrop 

、手動でいくつかの観測インデックスを実行して値を上に移動することができます体操:

clear 
set obs 100 
generate var1 = rnormal() 
generate var2 = rnormal() 

input double(id var5 var6) 
1 1052 17.348 
2 1288 17.378 
3 1536 17.387 
4 2028 17.396 
5 1810 17.402 
6 2034 17.407 
end 

* an observation index 
gen obsid = _n if !mi(id) 

* identify observations to drop 
gen todrop = 0 if !mi(id) 
sum obsid, meanonly 
local n = r(N) 
quietly forvalues i = 1/`n' { 
    forvalues j = 1/`n' { 
    replace id = . if var5[`i'] > var5[`j'] & var6[`i'] < var6[`j'] & _n == `i' 
    } 
} 

* move observations up 
local j 0 
quietly forvalues i = 1/`n' { 

    if !mi(id[`i']) { 
     local ++j 
     replace id = id[`i'] in `j' 
     replace var5 = var5[`i'] in `j' 
     replace var6 = var6[`i'] in `j' 
    } 
} 

local ++j 
replace id = . in `j'/l 
replace var5 = . in `j'/l 
replace var6 = . in `j'/l 

drop obsid todrop 
+0

ありがとう、ロバート、これは本当に最も役立ちます。私は最後の数行でなぜローカルjをlで分割するのか尋ねることはできますか?私は何ですか? – user5751111

+0

観測jから最後の観測までの範囲です。 'help in'を参照してください。 –