Extracting random integers from a given variable

2019-08-22 02:44发布

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条回答
We Are One
2楼-- · 2019-08-22 03:06

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 |
     +----------------------------+
查看更多
登录 后发表回答