1) データのサブセット化
メイン ファイルに 400,000 件の観測があり、参照ファイルに 300 件あるため、約 1.5 分かかります。メイン ファイルの 2 倍の観測値でこれをテストすることはできません。RAM が不足しているため、コンピューターがクロールするからです。
戦略には、参照緯度と経度を保持するために必要な数の変数を作成することが含まれます (OP の場合は 271*4 = 1084。Stata IC 以上でこれを処理できます。 を参照してくださいhelp limits
)。これには、いくつかの再形成と追加が必要です。次に、条件を満たすビッグデータ ファイルの観測を確認します。
clear all
set more off
*----- create example databases -----
tempfile bigdata reference
input ///
lon lat
-76.22 44.27
-66.0 40.85 // meets conditions
-77.10 34.8 // meets conditions
-66.00 42.0
end
expand 100000
save "`bigdata'"
*list
clear all
input ///
str4 id minlon maxlon minlat maxlat
"0765" -78.44 -75.22 34.324 35.011
"6161" -66.11 -65.93 40.32 41.88
end
drop id
expand 150
gen id = _n
save "`reference'"
*list
*----- reshape original reference file -----
use "`reference'", clear
tempfile reference2
destring id, replace
levelsof id, local(lev)
gen i = 1
reshape wide minlon maxlon minlat maxlat, i(i) j(id)
gen lat = .
gen lon = .
save "`reference2'"
*----- create working database -----
use "`bigdata'"
timer on 1
quietly {
forvalues num = 1/300 {
gen minlon`num' = .
gen maxlon`num' = .
gen minlat`num' = .
gen maxlat`num' = .
}
}
timer off 1
timer on 2
append using "`reference2'"
drop i
timer off 2
*----- flag observations for which conditions are met -----
timer on 3
gen byte flag = 0
foreach le of local lev {
quietly replace flag = 1 if inrange(lon, minlon`le'[_N], maxlon`le'[_N]) & inrange(lat, minlat`le'[_N], maxlat`le'[_N])
}
timer off 3
*keep if flag
*keep lon lat
*list
timer list
関数はinrange()
、OP の厳密な不等式 (関数テスト <=、>=) を満たすために、最小値と最大値を事前に調整する必要があることを意味します。
おそらく、 を使用したいくつかの拡張expand
、相関関係の使用、およびby
(データが長い形式である) ことで、速度が向上する可能性があります。今の私には完全には明らかではありません。プレーンな Stata モードでもっと良い方法があると確信しています。マタはさらに良いかもしれません。
(joinby
もテストされましたが、やはり RAM が問題でした。)
編集
完全なデータベースではなくチャンクで計算を行うと、RAM の問題が大幅に改善されます。120 万回の観測を含むメイン ファイルと 300 回の観測を含む参照ファイルを使用すると、次のコードはすべての作業を約 1.5 分で実行します。
set more off
*----- create example big data -----
clear all
set obs 1200000
set seed 13056
gen lat = runiform()*100
gen lon = runiform()*100
local sizebd `=_N' // to be used in computations
tempfile bigdata
save "`bigdata'"
*----- create example reference data -----
clear all
set obs 300
set seed 97532
gen minlat = runiform()*100
gen maxlat = minlat + runiform()*5
gen minlon = runiform()*100
gen maxlon = minlon + runiform()*5
gen id = _n
tempfile reference
save "`reference'"
*----- reshape original reference file -----
use "`reference'", clear
destring id, replace
levelsof id, local(lev)
gen i = 1
reshape wide minlon maxlon minlat maxlat, i(i) j(id)
drop i
tempfile reference2
save "`reference2'"
*----- create file to save results -----
tempfile results
clear all
set obs 0
gen lon = .
gen lat = .
save "`results'"
*----- start computations -----
clear all
* local that controls # of observations in intermediate files
local step = 5000 // can't be larger than sizedb
timer clear
timer on 99
forvalues en = `step'(`step')`sizebd' {
* load observations and join with references
timer on 1
local start = `en' - (`step' - 1)
use in `start'/`en' using "`bigdata'", clear
timer off 1
timer on 2
append using "`reference2'"
timer off 2
* flag observations that meet conditions
timer on 3
gen byte flag = 0
foreach le of local lev {
quietly replace flag = 1 if inrange(lon, minlon`le'[_N], maxlon`le'[_N]) & inrange(lat, minlat`le'[_N], maxlat`le'[_N])
}
timer off 3
* append to result database
timer on 4
quietly {
keep if flag
keep lon lat
append using "`results'"
save "`results'", replace
}
timer off 4
}
timer off 99
timer list
display "total time is " `r(t99)'/60 " minutes"
use "`results'"
browse
2) 不平等
不等式が正しいかどうかを尋ねます。それらは実際には合法であり、Stata は文句を言わないことを意味しますが、結果はおそらく予期しないものです。
次の結果は驚くべきものに思えるかもしれません。
. display (66.11 < 100 < 67.93)
1
式が true (つまり 1) と評価されるのはどうしてですか? Stata はまずどちらが真かを評価66.11 < 100
し、次にどちらが真かを判断1 < 67.93
します。
意図した式は次のとおりです (そして、Stata は希望どおりに動作します)。
. display (66.11 < 100) & (100 < 67.93)
0
関数に依存することもできますinrange()
。
次の例は、前の説明と一致しています。
. display (66.11 < 100 < 0)
0
Stata は66.11 < 100
どちらが真 (つまり 1) であるかを確認し1 < 0
、偽 (つまり 0) である をフォローアップします。