问题
My task is picking 3
years randomly within a time interval 500
times for simulation purpose.
More specifically,I want to select 3
random years from 2007
to 2016
(10
years), for example 2008
, 2012
and 2014
. So it's more or less equivalent to extracting random integers from a variable.
My solution is the following:
* The following (empty) dataset will be used to append the results of the Monte Carlo simulations
use "recession_parms.dta", clear
save "ind_simulations.dta", replace
forvalues i=1(1)500 {
use reg_sample.dta, clear
di "SIMULATION `i'"
scalar define lowest_year=2007
scalar define highest_year=2016
// randomly select "faked" year1: not inclue real treated years
gen year1_random=(lowest_year+int((highest_year-lowest_year+1)*runiform())) //To generate random integers over [a,b], use a+int((b-a+1)*runiform()) (see STATA help)
gen temp1 = inlist(year1_random,2008,2012,2014)
while temp1==1 {
replace year1_random =(lowest_year+int((highest_year-lowest_year+1)*runiform()))
cap drop temp1
gen temp1 = inlist(year1_random,2008,2012,2014)
}
// randomly select "faked" year2: (1)not inclue real treated years and (2)not equal to year1
gen year2_random=(lowest_year+int((highest_year-lowest_year+1)*runiform()))
gen temp2 = inlist(year2_random,2008,2012,2014)
while temp2==1|year1_random==year2_random {
replace year2_random = lowest_year+int((highest_year-lowest_year+1)*runiform()))
cap drop temp2
gen temp2 = inlist(year2_random,2008,2012,2014)
}
// randomly select ""faked" year3_random:(1)not inclue real treated years and (2)not equal to year1 or year2
gen year3_random=(lowest_year+int((highest_year-lowest_year+1)*runiform()))
gen temp3 = inlist(year2_random,2008,2012,2014)
while temp3==1|year1_random==year3_random|year2_random==year3_random {
replace year3_random =(lowest_year+int((highest_year-lowest_year+1)*runiform()))
cap drop temp3
gen temp3 = inlist(year3_random,2008,2012,2014)
}
drop temp*
* Generate the new treated year dummies
gen recession = (year==year1_random|year==year2_random |year==year3_random)
* Regression
di "SIMULATION `i'"
qui xtreg freq recession $city_control trend trend_sq ,fe cluster(city)
parmest,format(estimate min95 max95 %8.2f p %8.3f) saving("temp.dta", replace)
* Append the results of the simulation
use "temp.dta", clear
keep if parm=="recession"
append using "ind_simulations.dta"
save "ind_simulations.dta", replace
}
erase "temp.dta"
use "ind_simulations.dta", clear
drop if estimate==.
save "ind_simulations.dta", replace
Is there any elegant way to achieve my goal instead of writing several while
loops?
回答1:
The following works for me:
sysuse uslifeexp, clear
set seed 12345
tempname sim
postfile `sim' id year1 year2 year3 using results, replace
forvalues i = 1 / 500 {
generate random = runiform()
sort random
post `sim' (`i') (year[1]) (year[2]) (year[3])
drop random
}
postclose `sim'
Below you can see the first ten observations in the produced results
dataset:
use results, clear
list in 1/10
+----------------------------+
| id year1 year2 year3 |
|----------------------------|
1. | 1 1927 1920 1910 |
2. | 2 1946 1917 1925 |
3. | 3 1927 1926 1946 |
4. | 4 1916 1908 1963 |
5. | 5 1983 1913 1967 |
|----------------------------|
6. | 6 1926 1967 1974 |
7. | 7 1976 1947 1927 |
8. | 8 1908 1960 1982 |
9. | 9 1947 1989 1915 |
10. | 10 1950 1920 1975 |
+----------------------------+
来源:https://stackoverflow.com/questions/57328872/extracting-random-integers-from-a-given-variable