Showing posts with label foreach. Show all posts
Showing posts with label foreach. Show all posts

Oct 26, 2019

Inverse probability of treatment weighting

// Allbus 2018
use xr19 sex age isced97 eastwest german pt09 pt10 wghtpew bik using "ZA5272_v1-0-0.dta", clear

// Outcome: Trust in media
recode pt09 pt10 (-9 = .)
alpha pt09 pt10 
scores trust = mean(pt09 pt10), nv(1)
label var trust "Trust in media"
drop pt09 pt10 

// Treatment: Internet use
gen internet = (xr19 == 1) if !inlist(xr19, -9, -8)
label define internet 1 "Internet user" 0 "Internet non-user"
label val internet internet
drop xr19

// Gender
gen female = (sex == 2)
label var female "Female sex"
drop sex

// Age
recode age (-32 = .)
label var age "Age"

// Education
recode isced97 (-32 = .)
label define isced97 1 "Basic" 2 "Lower secondary" 3 "Upper secondary" 4 "Post-secondary" 5 "Tertiary first" 6 "Tertiary second", modify
label var isced97 "Education"

// East
generate east = (eastwest == 2)
label var east "Eastern Germany"
drop eastwest

// German
recode german (1 = 0) (2 = 0) (3 = 1) (-50 = 1), gen(foreign)
label var foreign "Foreign citizen"
drop german

// Region
recode bik (-34 = .)
label define bik  1 "-1,999 inh." ///
                  2 "2,000-4,999 inh." ///
                  3 "5,000-19,999 inh." ///
                  4 "Zone 1-4, -50,000 inh." ///
                  5 "Zone 2-4, -100,000 inh." ///
                  6 "Zone 1, -100,000 inh." ///
                  7 "Zone 2-4, -500,000 inh." ///
                  8 "Zone 1, -500,000 inh." ///
                  9 "Zone 2-4, 499,999+ inh." ///
                 10 "Zone 1, 499,999+ inh.", modify
label var bik "Commuting zone"

// Keep only complete cases
keep if !missing(trust, internet, female, age, isced97, east, foreign, bik)

// See how imbalanced covariates are
  // Generate dummies for first table
foreach x of varlist isced97 bik {               // Plug in categorical variables here
  qui tab `x', gen(`x'x)                         // Create dummy variables
  foreach var of varlist `x'x* {
   local lab `: var label `var''
   *di "`lab'"                                   // Display label
   *di strpos("`lab'", "==") 
   local i = strpos("`lab'", "==") + 2
   local lab `: di substr("`lab'",  `i', .)'
   di "`lab'"
   label var `var' "  `lab'"                // Add space to label
  }
}
  // Calculate means
eststo clear
estpost tabstat trust female isced97x* age foreign east bikx*, by(internet) ///
                                                       statistics(mean sd) ///
                                                       columns(statistics) ///
                                                       casewise
   // Look at table
esttab, unstack cells(mean(fmt(2)) sd(fmt(2) par keep(trust age))) nonumber ///
        label collabels("Mean (SD)/Prop.") modelwidth(25) varwidth(25) ///
        refcat(isced97x1 "Education:" bikx1 "Communting zone:", nol) 
drop isced97x* bikx* // Drop variables created for table
eststo clear

// Alternative approach
  // Run desired model first
qui teffects ipw (trust) (internet east##(c.age##c.age) female foreign ib3.isced97 i.bik, logit)
  // Table of covariates
tebalance summarize, baseline // Same table as created above
matrix before = r(table)
matrix list before
  // Table of covariates after weighting
tebalance summarize
matrix after = r(table)
matrix list after
  // Merge tables
matrix both = before, after
matrix list both

  // Look at table
esttab matrix(both, fmt(2)), ///
       label nomtitle ///
       coeflabel(1.east "Eastern Germany" ///
                 age "Age" ///
                 c.age#c.age "Age X age" ///
                 1.east#c.age "Eastern Germany X age" ///
                 1.east#c.age#c.age "Eastern Germany X age X age") ///
       refcat(1.isced97 "Education:" 2.bik "Commuting zone:", nol) ///
       varwidth(30) modelwidth(18) ///
       collabel("Control (mean)" "Treated (mean)" "Control (var.)" "Treated (var.)" "Std. diff." "Std. diff. weighted" "Var. ratio" "Var. ratio weighted")

// Omnibus test: tests hypothesis that treatment model balances the covariates
tebalance overid

// Check overlap
teffects overlap, xtitle(Propensity score Internet non-user) ///
                  ytitle(Density) ///
                  legend(order(1 "Internet non-user" 2 "Internet user") pos(2) ring(0)) 

// IPTW
eststo: teffects ipw (trust) (internet east##(c.age##c.age) female foreign ib3.isced97 i.bik, logit), ate
eststo: teffects ipw (trust) (internet east##(c.age##c.age) female foreign ib3.isced97 i.bik, logit), atet

// Doing things by hand:
// Calculate weight for IPTW, ATE
logit internet east##(c.age##c.age) female foreign ib3.isced97 i.bik
predict probab
generate wate = .
replace  wate = 1/probab       if internet == 1
replace  wate = 1/(1 - probab) if internet == 0

// Calculate weight for IPTW, ATT
generate watt = .
replace  watt = 1                   if internet == 1
replace  watt = probab/(1 - probab) if internet == 0

// IPTW by hand
eststo: regress trust i.internet [pw = wate]
eststo: regress trust i.internet [pw = watt]
esttab, b(2) se(2) keep(main:) drop(_cons) rename(r1vs0.internet 1.internet) ///
        nobaselevels mtitles("IPTW ATE" "IPTW ATT" "IPTW ATE" "IPTW ATT") ///
        mgroup("teffects" "regress", pattern(1 0 1 0))

// Doubly robust
eststo: teffects ipwra (trust          east##(c.age##c.age) female foreign ib3.isced97 i.bik) ///
                     (internet east##(c.age##c.age) female foreign ib3.isced97 i.bik, logit)
eststo: teffects ipwra (trust          east##(c.age##c.age) female foreign ib3.isced97 i.bik) ///
                     (internet east##(c.age##c.age) female foreign ib3.isced97 i.bik, logit), atet
esttab, b(2) se(2) keep(main:) drop(_cons) rename(r1vs0.internet 1.internet) ///
        nobaselevels mtitles("IPTW ATE" "IPTW ATT" "IPTW ATE" "IPTW ATT" "IPTW RA ATE" "IPTW RA ATT") ///
        mgroup("teffects ipw" "regress" "teffects ipwra", pattern(1 0 1 0 1 0))

// Doubly robust by hand
tempvar internet0a internet1a internet0b internet1b ate att

// ATE
regress trust east##(c.age##c.age) female foreign ib3.isced97 i.bik if !internet [pw = wate]
predict `internet0a'
regress trust east##(c.age##c.age) female foreign ib3.isced97 i.bik if internet [pw = wate]
predict `internet1a'
generate `ate' = (`internet1a' - `internet0a')
summarize `ate'

// ATT
regress trust east##(c.age##c.age) female foreign ib3.isced97 i.bik if !internet [pw = watt]
predict `internet0b'
regress trust east##(c.age##c.age) female foreign ib3.isced97 i.bik if internet [pw = watt]
predict `internet1b'
generate `att' = (`internet1b' - `internet0b')
summarize `att'

Aug 13, 2019

Make list of variable labels of all variables in data set

sysuse auto, clear

qui ds

local x = "`r(varlist)'"

foreach var of local x {
 di `"`: variable label `var''"'
}

Aug 14, 2018

Generate dummy variables with -tabulate- and relabel them in a loop

I'd like to generate a set of dummy variables based on one categorical variable, in this case a variable named 'country.'
qui tab country, gen(cntry)
This has created such a set of dummy variables, however, each of them is labeled 'country==USA' etc. How do I remove the old variable name and the equal signs from the variable labels of the new set of dummy variables? Like this:
foreach var of varlist cntry* {
        local lab `: var label `var''
 local lab `: di subinstr("`lab'", "country==", "", 1)'
 label var `var' "`lab'"
}

Nov 17, 2017

Random graphs (119): Line plots and dot plots

// Prepare ESS round 8
use cntry essround wrkctra dweight using "ESS8e01.dta", clear
recode wrkctra (6 = .a) (7 = .b) (8 = .c) (9 = .d)

// Add ESS rounds 1-7
append using "ESS1-7e01.dta", keep(cntry essround wrkctr wrkctra dweight)

  // Prepare variables
generate nocontract = (wrkctra == 3) if !missing(wrkctra)
kountry cntry, from(iso2c)
rename NAMES_STD country

  // Prepare files for post commands
tempname foo1
tempname foo2
postfile `foo1' str20 country essround ll nocontract ul using `foo2', replace

qui levelsof country, local(country)

 // Loop
foreach x of local country {
 foreach i of numlist 1/8 {
  capture logit nocontract [pw = dweight] if country == "`x'" & essround == `i'
  if _rc == 0 {
   qui margins [pw = dweight]
   matrix prevs = r(table)
   local prev = prevs[1,1] * 100
   local ll = prevs[5,1] * 100
   local ul = prevs[6,1] * 100
   *di "`x'" _skip(5) `i' _skip(5)  `ll' _skip(5) `prev' _skip(5) `ul'
   post `foo1' ("`x'") (`i') (`ll') (`prev') (`ul')
  }
 }
}
postclose `foo1'

// Plot estimates
use `foo2', clear

  // Fix value label
label define essround 1 "2002" 2 "2004" 3 "2006" 4 "2008" ///
                      5 "2010" 6 "2012" 7 "2014" 8 "2016", modify
label val essround essround

// First plot
sort country essround
twoway (rarea ll ul essround, lcolor(white)) ///
       (connected nocontract essround), ///
        by(country, ///
           note("") ///
           legend(off)) ///
        xlabel(1/8, val ang(90)) ///
        xtitle("") ytitle("% without job contract") ///
        name(figure2a, replace) ysize(9)

// Second plot
reshape wide ll ul nocontract, i(country) j(essround)    

scores average =  mean(nocontract*)
egen order_ = rank(average), unique
labmask order_, value(country)
    
twoway (dot nocontract1 order_, horizontal) ///
       (dot nocontract2 order_, horizontal) ///
       (dot nocontract3 order_, horizontal) ///
       (dot nocontract4 order_, horizontal) ///
       (dot nocontract5 order_, horizontal) ///
       (dot nocontract6 order_, horizontal) ///
       (dot nocontract7 order_, horizontal) ///
       (dot nocontract8 order_, horizontal) ///
       (rspike ul1 ll1 order_, horizontal) ///
       (rspike ul2 ll2 order_, horizontal) ///
       (rspike ul3 ll3 order_, horizontal) ///
       (rspike ul4 ll4 order_, horizontal) ///
       (rspike ul5 ll5 order_, horizontal) ///
       (rspike ul6 ll6 order_, horizontal) ///
       (rspike ul7 ll7 order_, horizontal) ///
       (rspike ul8 ll8 order_, horizontal), ///
        ylabel(1/32, val) ytitle("") xscale(alt) ///
        xtitle("% without job contract") ///
        legend(order(1 "2002" 2 "2004" 3 "2006" 4 "2008" ///
                     5 "2010" 6 "2012" 7 "2014" 8 "2016") ///
               pos(5) ring(0)) ///
        name(figure2b, replace) ysize(9)
   
graph combine figure2a figure2b, ///
      col(2) name(figure2, replace) ///
      note(" " "{it:Source:} European Social Survey 2002-16, weighted data. {it:Note:} Error bands/spikes denote 95% confidence intervals", span  size(*.7)) 


Aug 2, 2016

Random graphs (90): Regression coefficients

version 14
use 7348_F1.dta, clear

// Prepare variables:
// Country variable
rename Y11_Country ctry
decode ctry, gen(country)
kountryadd "Macedonia (FYROM)" to "Macedonia" add
kountry country, from(other) stuck
rename _ISO3N_ geo
kountry geo, from(iso3n) to(iso2c)
rename _ISO2C_ cntry
replace cntry = "XK" if country == "Kosovo"
drop geo 

label define Y11_Country 30 "Macedonia", modify

// Wave identifier
rename Wave wave

// Gender
generate female = (Y11_HH2a == 2)

// Work-family conflict
*factor Y11_Q12a Y11_Q12b Y11_Q12c, pcf
*tab Y11_Q12a wave, mis
*tab Y11_Q12b wave, mis
*tab Y11_Q12c wave, mis
*alpha Y11_Q12a Y11_Q12b Y11_Q12c, item
scores wfb = mean(Y11_Q12a Y11_Q12b Y11_Q12c)
generate wfc = 5 - wfb
drop wfb

eststo clear

levelsof wave, local(wave)

foreach x of local wave {
eststo: mixed wfc female || ctry: female if wave == `x', cov(uns)

preserve
// Get no. of countries
matrix groups = e(N_g)
local n_g = groups[1,1]

// Predict residuals
predict u1 u0, reffects
predict u1se u0se, reses

// Calculate posterior slope
generate eb_female = u1 + _b[female]

// Plot posterior slope
egen pickone = tag(country)  // Keep one case per countr
keep if pickone
   
egen order_ = rank(-u1), unique
labmask order_, value(ctry) decode

gen high = u1 + _b[female] + (1.96 * u0se)
gen low  = u1 + _b[female] - (1.96 * u0se)
local avg =  _b[female]

twoway (rcap eb_female eb_female order_, horizontal) ///
       (rspike high low order_, horizontal) , ///
        xline(`avg') ylabel(1/`n_g', val ang(h)) ///
        ytitle("") ///
  xscale(alt) ///
        xlabel(-.2 (.1) .4) ///
        xtitle("Female WFC disadvantage") ///
        legend(off) ///
        title(`: label (wave) `x'') ///
        name(emp_bayes_`x', replace) xsize(3) nodraw
restore
}

graph combine emp_bayes_1 emp_bayes_2 emp_bayes_3, col(3) xsize(6) name(variation, replace) altshrink ///
      note("{it:Source:} European Quality of Life Surveys, 2003-11. {it:Notes:} Horizontal line shows average coefficient, country-specific" ///
        "estimates indicate deviation from this average. Error bars are 95% CI's based on random-effects models.")

coefplot est1, bylabel(EQLS 2003) || /// est2, bylabel(EQLS 2007) || /// est3, bylabel(EQLS 2011) || /// , xlabel(0 (.05) .2) drop(_cons) xscale(alt) baselevel coeflabel(female = "Female") /// xtitle("Female WFC disadvantage") xline(0) byopts(row(1)) ciopts(recast(rcap))
coefplot est1 est2 est3, xlabel(0 (.05) .2) drop(_cons) xscale(alt) baselevel coeflabel(female = "Female") /// xtitle("Female WFC disadvantage") xline(0) byopts(row(1)) ciopts(recast(rcap)) /// legend(order(2 "EQLS 2003" 4 "EQLS 2007" 6 "EQLS 2011"))

Mar 30, 2016

Random graphs (69): ICC's with confidence intervals

use sharew1_rel2-6-0_gv_isced.dta, clear

// Reshape data into long format
reshape long iscedy_c, i(mergeid) j(child)
// Fix variable of interest
recode iscedy_c (-7 = .a "not yet coded (temporary)") ///
                (-2 = .b "refusal") ///
                (-1 = .c "don't know") ///
                (95 = .d "still in school") ///
                (97 = .e "other") ///
                ( . = .f "missing") ///
               , gen(years)
label var years "Years of education"
    
// Israel doesn't provide a ISCED-to-years conversion, thus it's dropped here
drop if country == 25

// Fix country variable
decode country, gen(cntry)

// Calculate ICC's per country
tempname foo
postfile `foo' str100 commandline_str str20 cntry icc icclb iccub N N_groups using "C:\Windows\Temp\test.dta", replace    
    
levelsof cntry, local(country)

foreach x of local country {
  *di "`x'"
  qui mixed years || mergeid: if cntry == "`x'", reml
  qui estat icc
  
  matrix groups = e(N_g)
  scalar n_g = groups[1,1]
  matrix cis =  r(ci2)
  scalar icclb = cis[1,1]
  scalar iccub = cis[1,2]
  
  post `foo' (e(cmdline)) ("`x'") (r(icc2)) (icclb) (iccub) (e(N)) (n_g)
  
  matrix stuff1 = (r(icc2), icclb, iccub, e(N), n_g)
  if "`x'" == "Austria" matrix table1 = stuff1
  else matrix table1 = (table1\stuff1)
}

postclose `foo'

matrix rownames table1 = `country'
matrix colnames table1 = "ICC" "CI lower" "CI upper" "Children" "Families"
esttab matrix(table1, fmt(2 2 2 0 0))
use "C:\Windows\Temp\test.dta", clear

egen order_ = rank(-icc), unique
labmask order_, value(cntry)

twoway (rcap   icc icc order_, horizontal) ///
       (rspike icclb iccub order_, horizontal) ///
      , ylabel(1/11, val) legend(off) ytitle("") xscale(alt) ///
        xtitle("Sibling correlations in educational attainment") ///
        note(" " "{it:Source:} SHARE wave 1, doi:10.6103/SHARE.w1.260", span)

erase "C:\Windows\Temp\test.dta"

Mar 14, 2016

Random graphs (65): Dot plots with confidence intervals

preserve
// Keep those countries for which three waves are available
keep if inlist(cntry, "AT", "AU", "BG", "CZ", "DEE", "DEW", "ES", "GB", "HU") | ///
        inlist(cntry, "IE", "IL", "JP", "NL", "NO", "PH", "PL", "RU", "SE")   | ///
  inlist(cntry, "SI", "US")

// Define temporary objects
tempname foo
tempname foox
postfile `foo' str3 cntry year perc perc_ll perc_ul using `foox', replace

levelsof cntry, local(levels1)
levelsof year, local(levels2)

// Calculate proportions by country and year
foreach year of local levels2 {
 foreach country of local levels1 {

    capture proportion separate if cntry == "`country'" & year == `year'
    *matrix list r(table)
    matrix fcoefs  = r(table)
    local fperc    = fcoefs[1,2] * 100
    local fperc_ll = fcoefs[5,2] * 100
    local fperc_ul = fcoefs[6,2] * 100

    di "`country'"  _skip(2) `year' _skip(2)  `fperc_ll' _skip(2) `fperc' _skip(2) `fperc_ul'

    if "`fperc'" != "" {    // Make sure that the loop doesn't break if empty
    post `foo' ("`country'") (`year') (`fperc') (`fperc_ll') (`fperc_ul')
    }
 }
}
postclose `foo'

// Use posted data set
use `foox', clear

// Generate country name variable using -kountry-
kountry cntry, from(iso2c)
rename NAMES_STD country
replace country = "Germany (West)" if country == "dew"
replace country = "Germany (East)" if country == "dee"

// Plot average change over time
twoway (scatter perc year, connect(direct) msymbol(o)) ///
       (rcap perc_ll perc_ul year) ///
      , by(country, ///
           note("{it:Source:} ISSP 'Family and Changing Gender Roles II{c 150}IV. {it:Note:} Error bars denote 95% confidence intervals.", span) ///
           legend(off)) ///
        xlabel(1994 2002 2012) xtitle("") ///
        ytitle("% of couples keeping incomes separate") ///
        ylabel(0 10 20 30 40 50, gstyle(minor)) yscale(r(0))
        // yscale(r(0)) adds missing gridline according to
        // http://www.stata.com/statalist/archive/2013-04/msg00904.html    
restore

Feb 26, 2016

Generating a country–year variable

unzipfile "output7717034280080927434.zip", replace
use cntry essround happy using ESS1-6e01_0_F1, clear


// Generate country-year variable
levelsof cntry, local(levels1)
levelsof essround, local(levels2)
gen cyear = ""

foreach country of local levels1 {
  foreach round of local levels2 {
     replace cyear = "`country'" + "`round'" if cntry == "`country'" & essround == `round'
  di "`country'" "`round'"
  }
}
label var cyear "Country-Year"

// Fit three-level model
mixed happy || cntry: || cyear:
estat icc

capture drop u1* u0*
predict u1 u0, reffects 
predict u1se u0se, reses   

  // Plot country-level variation
preserve
egen pickone = tag(cntry)
keep if pickone
   
egen order_ = rank(-u1), unique
labmask order_, value(cntry)

gen high = u1 + (1.96 * u1se)
gen low  = u1 - (1.96 * u1se)

twoway (rcap u1 u1 order_, dsymbol(x)) ///
       (rspike high low order_) , ///
        yline(0) xlabel(1/32, val ang(v)) ///
        xtitle("") ///
        ytitle("Country-level residuals") ///
        legend(off) ///
        name(cntry, replace) 
restore 

  // Plot country-year level variation
preserve
egen pickone = tag(cyear)
keep if pickone
   
egen order_ = rank(-u0), unique
labmask order_, value(cyear)

gen high = u0 + (1.96 * u0se)
gen low  = u0 - (1.96 * u0se)

twoway (rcap u0 u0 order_, dsymbol(x) horizontal) ///
       (rspike high low order_, horizontal) , ///
        xline(0) ylabel(none) ///
  xscale(alt) ///
        ytitle("") ///
        xtitle("Country{c 150}year-level residuals") ///
        legend(off) ///
        name(cyear, replace) ysize(8)
restore 

Oct 4, 2015

Firebaugh (1997): Analyzing Repeated Surveys in Stata (ch. 4)

Note how this is restricted to the linear decompositions!

Intracohort change versus overall change


use year race age cohort racmar using GSS7214_R4.DTA, clear

// Select sample
keep if inlist(year, 1974, 1984, 1994)
keep if race == 1   // Whites only
keep if age >= 20   
keep if !missing(age, racmar)

// Generate 10-year cohort variable
generate cohort10 = .
local lowerbracket = 1965
local upperbracket = 1974

foreach x of numlist 1/10 {
 replace cohort10 = `x' if cohort >= `lowerbracket' & cohort <= `upperbracket'
 label define cohort10 `x' "`lowerbracket' to `upperbracket'", modify
 local lowerbracket = `lowerbracket' - 10
 local upperbracket = `upperbracket' - 10
}

label value cohort10 cohort10
label var year "Year"

// Opposing interracial marriage
recode racmar (1 = 1 "Yes") (2 = 0 "No") (.d .i .n = .), gen(oppose)
label var oppose "Opposes interracial marriage"
generate oppose_perc = oppose * 100

// Create Table 4.1 without change
table cohort10 year, contents(mean oppose_perc n oppose_perc) format(%9.1f) center

// Different version of Table 4.1, including calculated changed
preserve
qui table cohort10 year, contents(mean oppose_perc n oppose_perc) format(%9.1f) center replace
rename table1 oppose_perc 
rename table2 oppose_n
reshape wide oppose_perc oppose_n, i(cohort10) j(year)
gen change1984 = oppose_perc1984 - oppose_perc1974 
gen change1994 = oppose_perc1994 - oppose_perc1984 
format change1984 change1994 %9.1f
list, noobs sep(0) abbreviate(20) subvar
restore

Empirical example for linear decomposition: Trend in antiblack prejudice

use year race cohort racdin racpush racseg racmar using GSS7214_R4.DTA, clear

// Create sample
keep if inlist(year, 1972, 1976, 1980, 1984)
keep if race == 1

// Create outcome
alpha racdin racpush racseg racmar, item
egen zracdin  = std(racdin)
egen zracpush = std(racpush)
egen zracseg  = std(racseg)
egen zracmar  = std(racmar)
scores y = total(zracdin zracpush zracseg zracmar), minvalid(3)
gen prejudice = 6 - y  // Difficult to figure out the exact outcome
drop y                 // But this seems to be close enough

// Calculate total change in prejudice
mean prejudice, over(year) coeflegend
local totalchange = _b[1984] - _b[1972]

// Calculate annual change within cohorts
reg prejudice year cohort
local b1 = _b[year]
local b2 = _b[cohort]

// Calculate contributions of intracohort change and cohort replacement
local intracohort = `b1' * (1984 -1972)
di `intracohort'

qui mean cohort, over(year) coeflegend
local cohortreplacement = `b2' * (_b[1984] - _b[1972])
di `cohortreplacement'

// Calculate estimated total change
local estim_change = `intracohort' + `cohortreplacement'
di `estim_change'

// Output results
matrix results = (`totalchange')\(`b1')\(`b2')\(`intracohort')\(`cohortreplacement')\(`estim_change')
esttab matrix(results, fmt(%9.2f)), coeflabel(r1 "Total change" ///
                                              r2 "Intracohort slope" ///
                                              r3 "Intercohort slope" ///
                                              r4 "Estimated contribution of intracohort change" ///
                                              r5 "Estimated contribution of cohort replacement" ///
                                              r6 "Estimated total change") ///
                                              mtitle("Result")  ///
                                              varwidth(45)

Empirical example of the same-sign rule: Gender role attitudes

use year cohort fework fepres fepol fehome if year >= 1972 & year <= 1988 using GSS7214_R4.DTA, clear

// Prepare variables
recode fework fepres (2 = 0)
recode fepol fehome  (2 = 1) (1 = 0)

// Create sample for Table 4.2
preserve
keep if inlist(year, 1972, 1974, 1988)
fre year
gen id = _n
reshape wide fework fepres fepol fehome, i(id) j(year)
replace fepol1972 = fepol1974
replace fehome1972 = fehome1974
reshape long
drop if year == 1974
recode year (1972 = 0 "1972") (1988 = 1 "1988"), gen(yr)

// Table 4.2
foreach y of varlist fework fepres fepol fehome {
 qui regress `y' yr
 local mean1972 = _b[_cons]
 local mean1988 = _b[_cons] + _b[yr]
 local differen = _b[yr]
 local t        = _b[yr] / _se[yr]
 *di "`y'" _skip(5) `mean1972' _skip(5) `mean1988' _skip(5) `differen' _skip(5) `t'
 matrix stuff1 = (`mean1972' , `mean1988' , `differen' , `t')
 if "`y'" == "fework" matrix table42 = stuff1
 else matrix table42 = (table42\stuff1)
}
 
matrix rownames table42 = "WORK" "PRES" "POLI" "HOME"
matrix colnames table42 = "Mean 1972" "Mean 1988" "Change" "t-value"
esttab matrix(table42, fmt(3 3 3 1))

restore

// Table 4.3
foreach y of varlist fework fepres fepol fehome { qui logit `y' year cohort local n = e(N) local intracohort = _b[year] local intracohort_t = _b[year] / _se[year] local intercohort = _b[cohort] local intercohort_t = _b[cohort] / _se[cohort] *di "`y'" _skip(5) `n' _skip(5) `mean1988' _skip(5) `differen' _skip(5) `t' matrix stuff = (`n', `intracohort', `intracohort_t', /// `intercohort', `intercohort_t') if "`y'" == "fework" matrix table43 = stuff else matrix table43 = (table43\stuff) } matrix rownames table43 = "WORK" "PRES" "POLI" "HOME" matrix colnames table43 = "N" "Within cohort" "t" "Cross-cohort" "t" esttab matrix(table43, fmt(0 %9.3f %9.1f %9.3f %9.1f)), modelwidth(14)

Reference

Firebaugh, Glenn. 1997. Analyzing Repeated Surveys. Sage. doi: 10.4135/9781412983396

Apr 20, 2015

Random graphs (45): Re-creating -graph dot- using -twoway dot-



This plot recreates this one, but adds confidence intervals.
preserve

// Calculate country-specific means to be plotted
tempname foo
tempname idealage
postfile `foo' quintile incocomp incocomp_lb incocomp_ub using `foo2', replace

levelsof(quintile), local(quintile)        
        
foreach x of local quintile {
 qui reg incocomp if quintile == `x', cluster(cntry)
 local incocomp   = _b[_cons]
 local incocomplb = _b[_cons] - (1.96 * _se[_cons])
 local incocompub = _b[_cons] + (1.96 * _se[_cons])
 post `foo' (`x') (`incocomp') (`incocomplb') (`incocompub')
}

postclose `foo'

// Plot country-specific means
use `foo2', clear
    
twoway (dot incocomp quintile) ///  -twoway scatter- doesn't have the lines
       (rcap incocomp_lb incocomp_ub quintile) ///
      , yscale(range(1.5 3.0)) ///
        ylabel(1.5 (.25) 3.0, format(%6.2f)) ///
 legend(off)
        title("Income quintiles")
        xlabel(1 `""1" "(poorest)""' /// Double-compound quotes allow for the line break
               2 3 4 5 `""5" "(richest)"') ///
        fxsize(40) /// Forces x-size to be 40 percent of its original size
        xtitle("") ///
        xscale(range(0.2 5.8)) /// Making this a bit bigger makes room for the labels
 name(byquintile_hor, replace) 

restore

// Calculate country-specific means to be plotted 2
preserve
tempname foo
tempname idealage
postfile `foo' str2 cntry incocomp incocomp_lb incocomp_ub using `foo2', replace


levelsof(cntry), local(cntry)        
        
foreach x of local cntry {
 qui reg incocomp if cntry == "`x'"
 local incocomp   = _b[_cons]
 local incocomplb = _b[_cons] - (1.96 * _se[_cons])
 local incocompub = _b[_cons] + (1.96 * _se[_cons])
 post `foo' ("`x'") (`incocomp') (`incocomplb') (`incocompub')
}

postclose `foo'

use `foo2', clear

// Create sorted-by-size variable
egen order_ = rank(-incocomp), unique
labmask order_, value(cntry)

// Plot country-specific means 2      
twoway (dot incocomp order_) ///
       (rcap incocomp_lb incocomp_ub order_) ///
      , yscale(off) /// Not necessary, as we're using the one from the other graph
        xlabel(1/23, val alt) ///
        title("Countries") ///
        xtitle("") ///
        legend(off) ///
        /* graphregion(margin(b=16)) */ /// Could help as -ycommon- isn't accounting for the different label sizes
        name(bycntry_hor, replace)

// Combine plots
graph combine byquintile_hor bycntry_hor, ///
      l1title("Mean income comparison orientation") ///
      ycommon row(1) ///
      imargin(zero) // Sets margin between both plots to 0

restore

Jan 9, 2015

Random graphs (43): Means with confidence intervals

use "ESS3e03_5.dta", clear

// Restrict to respondents 25-42 y
keep if agea >= 25 & agea <= 42 

// Generate variables of interest

// Split ballot identifier
*fre icsbfm

// Sex
generate female = (gndr == 2) if gndr != .a
drop if female == .

// Country
replace cntry = "UK" if cntry == "GB"

// iagpnt "In your opinion, what is the ideal age for a XXX 
//         to become a mother/father?"
recode iagpnt (  0 = .a "No ideal age") ///
              (777 = .b "Refusal") ///
              (888 = .c "Don't know") ///
              (999 = .d "No answer") ///
              (998 = .e "Split ballot") ///
              , gen(idealageparent)

clonevar idealagefather = idealageparent
replace  idealagefather = .e if icsbfm == 1

clonevar idealagemother = idealageparent
replace  idealagemother = .e if icsbfm == 2

// tochld "After what age would you say a woman/man is generally too old to
//        "consider having any more children?"
recode tochld (  0 = .a "Never too old") ///
              (777 = .b "Refusal") ///
              (888 = .c "Don't know") ///
              (999 = .d "No answer") ///
              (998 = .e "Split ballot") ///
              (997 = .f "Wrong age group") ///
              , gen(toooldforchild)

clonevar  toooldforchildf = toooldforchild
replace   toooldforchildf = .e if icsbfm == 1
label var toooldforchildf "Man too old for a(nother) child"

clonevar  toooldforchildm = toooldforchild
replace   toooldforchildm = .e if icsbfm == 2
label var toooldforchildm "Woman too old for a(nother) child"

// Set outliers and "never too old" to country-specific 99th percentile
levelsof(cntry), local(country)
foreach x of varlist toooldforchildf toooldforchildm {
  foreach y of local country {
   qui sum `x' if cntry == "`y'", detail
  *di `x' _skip(2) "`y'" _skip(2) r(p95) _skip(2) r(p99) 
   replace `x' = r(p99) if `x'   == .a ///
                         & cntry == "`y'"
   replace `x' = r(p99) if `x'    > r(p99) ///
                         & !missing(`x') ///
                         & cntry == "`y'"
 }
}

// Create temporary files and postfile
tempname foo
tempname idealage
postfile `foo' str2 cntry idealagem idealagemlb idealagemub ///
                          idealagef idealageflb idealagefub ///
                          toooldforchildfm toooldforchildflb toooldforchildfub  ///
                          toooldforchildmm toooldforchildmlb toooldforchildmub ///
                          using `idealage', replace

levelsof(cntry), local(country)
foreach x of local country {
 qui reg idealagemother if cntry == "`x'"
 local idealagem   = _b[_cons]
 local idealagemlb = _b[_cons] - (1.96 * _se[_cons])
 local idealagemub = _b[_cons] + (1.96 * _se[_cons])

 qui reg idealagefather if cntry == "`x'"
 local idealagef = _b[_cons]
 local idealageflb = _b[_cons] - (1.96 * _se[_cons])
 local idealagefub = _b[_cons] + (1.96 * _se[_cons])

 qui reg toooldforchildf if cntry == "`x'"
 local toooldforchildfm   = _b[_cons]
 local toooldforchildflb = _b[_cons] - (1.96 * _se[_cons])
 local toooldforchildfub = _b[_cons] + (1.96 * _se[_cons])

 qui reg toooldforchildm if cntry == "`x'"
 local toooldforchildmm = _b[_cons]
 local toooldforchildmlb = _b[_cons] - (1.96 * _se[_cons])
 local toooldforchildmub = _b[_cons] + (1.96 * _se[_cons])

post `foo' ("`x'") (`idealagem') (`idealagemlb') (`idealagemub') ///
                   (`idealagef') (`idealageflb') (`idealagefub') ///
                   (`toooldforchildfm') (`toooldforchildflb') (`toooldforchildfub') ///
                   (`toooldforchildmm') (`toooldforchildmlb') (`toooldforchildmub') 
}
postclose `foo'

use `idealage', clear

egen order_ = rank(-toooldforchildmm), unique
labmask order_, value(cntry)

twoway (scatter toooldforchildmm order_) ///
       (rcap toooldforchildmub toooldforchildmlb order_) ///
       (scatter toooldforchildfm order_) ///
       (rcap toooldforchildfub toooldforchildflb order_) ///       
       , legend(label(1 "... women") ///
                label(3 "... men") ///
                order(3 1) pos(1) ring(0)) ///
         xlabel(1/23, val alt) ///
         ylabel(40(5)60) ///
         xtitle(" ") ytitle("Age in years") ///
         title("Age when one is too old to have a(nother) child for ...") ///
         name(tooold, replace)
   
drop order_

egen order_ = rank(-idealagem), unique
labmask order_, value(cntry)

twoway (scatter idealagem order_) ///
       (rcap idealagemub idealagemlb order_) ///
       (scatter idealagef order_) ///       
       (rcap idealagefub idealageflb order_) ///
       , legend(label(1 "... mother") ///
                label(3 "... father") ///
                order(3 1) pos(1) ring(0)) ///
         xlabel(1/23, val alt) ///
         ylabel(20(5)40) ///
         xtitle(" ") ytitle("Age in years") ///
         title("Ideal age to become a ...") ///
         name(idealage, replace)

graph combine idealage tooold, ///
          col(1) ysize(8) /// 
          note("{it:Source:} European Social Survey Round 3, own calculations" ///
               "{it:Notes:} Respondents age 25{c 150}42 y only. Error bars denote 95 % CI's", span size(small))

Jul 16, 2014

Random graphs (28): Plotting categorical variables

foreach x of varlist V39 V40 V41 {

    // Recode each variable:
  recode `x' (1/5 = 2 "Valid answer") ///
             ( .c = 1 "Can't choose") ///
             ( .n = 0 "No answer") ///
    , gen(`x'_mis)
  label var `x'_mis "Recode of `x'"
  
    // Plot each variable:
  catplot `x'_mis, over(C_ALPHAN, label(ang(v)))
                   stack asyvars perc(C_ALPHAN) ///
                   legend(pos(1) row(1)) recast(bar) ///
     ytitle("Percentage") b1title("") ///
     title("Recode of `x'") ///
     name(`x'_mis, replace)
}

grc1leg V39_mis V40_mis V41_mis, col(1) name(combined, replace)
graph display combined, ysize(11) xsize(7)