Showing posts with label twoway rcap. Show all posts
Showing posts with label twoway rcap. Show all posts

Oct 26, 2019

Specification curve analysis

use "ZA4612_v1-0-1.dta", clear
do "ZA4612_patch_v1-0-1.do" // Some patch from data provider

keep v399-v404 v933 v827 v301 v298 

// Outcomes
mvdecode v399-v404, mv(9 = .a )

generate stress  = 5 - v399
generate depress = 5 - v400
generate calm    = v401 - 1
generate energy  = v402 - 1
generate pain    = 5 - v403
generate lonely  = 5 - v404

// Predictors
  // Topbot
mvdecode v933 v827, mv(96 = .a \ 99 = .b) 
generate topbot = v933
replace  topbot = v827 if missing(topbot)
  // Age
mvdecode v301, mv(999 = .a)
rename v301 age
  // Female
generate female = (v298 == 2)

drop v399-v404 v933 v827 v298 // Drop unnecessary variables

// Post definition
tempname foo
postfile `foo' str50 spec k1 k2 k3 b se using deleteme.dta, replace

// Loop
forvalues k1 = 1/6 {
  if `k1' == 1 local y "stress"
  if `k1' == 2 local y "depress"
  if `k1' == 3 local y "pain"
  if `k1' == 4 local y "calm"
  if `k1' == 5 local y "energy"
  if `k1' == 6 local y "lonely"
    forvalues k2 = 1/4 {
      if `k2' == 1 local agecontrol "age"
      if `k2' == 2 local agecontrol "c.age##c.age"
      if `k2' == 3 local agecontrol "c.age##c.age##c.age"    
      if `k2' == 4 local agecontrol "c.age##c.age##c.age##c.age"
        forvalues k3 = 1/3 {
          if `k3' == 1 local ifs " "
          if `k3' == 2 local ifs "if female == 1"
          if `k3' == 3 local ifs "if female == 0"
 
        local spec regress `y' topbot `agecontrol' female `ifs'

        qui `spec'
        local  b =  _b[topbot]
        local se = _se[topbot]

        post `foo' ("`spec'") (`k1') (`k2') (`k3') (`b') (`se')
        }
    }
}
postclose `foo'

// Plot specification curve
use deleteme, clear

// Generate ranked analytical choice variable
sort b
generate sk = _n
label var sk "Specification (sorted by coefficient size)"

// Calculate CI's
generate ub = b + 1.96 * se
generate lb = b - 1.96 * se

// Remind yourself what the variables mean
label var k1 "Outcome"
label var k2 "Age control"
label var k3 "Subsample"

// Stack indicators
generate k3c = k3
generate k2c = k2 + 1 + 3 // 3 because K3 has 3 categories, 1 for title
generate k1c = k1 + 1 + 3 + 4 + 1  // K2 has 4 categories

// Calculate some things for size of second axis
qui summarize b
global brange = r(max) - r(min)
global bmin = r(min)
global bmax = r(max)
global from_y = $bmin - (4.5 * $brange)

// Plot
twoway (scatter k1c k2c k3c sk, msymbol(o o o) msize(vsmall vsmall vsmall) ///
        yscale(range(1 22)) ///        
        ylabel( 1 "Full sample" 2 "Females only" 3 "Males only" 4 "{bf:Subsample}" ///
                5 "Age" 6 "Age squared" 7 "Age cubed" 8 "Age quartic" 9 "{bf:Age control}" ///
               10 "Stress"   11 "Depression" 12 "Pain" ///
               13 "Calmness" 14 "Energy"     15 "Loneliness" 16 "{bf:Outcome}", tstyle(notick) axis(1)))  ///
       (rcap b b sk, yaxis(2) yscale(range($from_y $bmax) axis(2)) ///
                     ylab(, format(%2.1g) axis(2)) ///
                     ytitle("{bf:Coefficient size}", axis(2) placement(north)) ///
                     yline(0, axis(2))) ///
       (rspike ub lb sk, yaxis(2)), ///
        xlabel(none)  ///
        legend(off) name(curve, replace) 
 

Reference

Simonsohn, Uri, Joseph P. Simmons, and Leif D. Nelson. 2015. Specification Curve. Descriptive and Inferential Statistics on All Reasonable Specifications. University of Pennsylvania. doi: 10.2139/ssrn.2694998
 

Mar 23, 2018

Random graphs (129): Offsetting markers

// Open Allbus 2016
use eastwest hs01 id02 using ZA5250_v2-0-0.dta, clear

// Region
recode eastwest (1 = 0 "West Germany") (2 = 1 "East Germany"), gen(east)
label var east "East Germany"

// Subjective social class
recode id02 (-50/-7 = .) ///
            (     1 = 0 "Lower class") ///
            (     2 = 1 "Working class") ///
            (     3 = 2 "Middle class") ///
            (   4 5 = 3 `" "Upper" "(middle)" "class" "'), gen(class)
label var class "Subjective social class"

// Health
recode hs01 (-9 = .) (5 = 0 "Bad") (4 = 1 "Less good") (3 = 2 "Satisfactory") ///
            (2 = 3 "Good") (1 = 4 "Very good"), gen(health)
label var health "Self-rated health"

// Model
regress health i.class##i.east //[pw = wghtpew]

// Plot using marginsplot
margins class#east, saving(myfile, replace) 
 
marginsplot, legend(pos(4) ring(0)) name(marginsplot, replace) title("") ///
             ytitle("Predicted self-rated health") ylabel(, format(%6.1f))

// Plot using twoway with overlay
use myfile, clear

// Create offset
clonevar _mx = _m1
replace _mx = cond(_m2 == 2, _mx - 0.1, _mx + 0.1)

// Plot using marginsplot
 
twoway (rcap _ci_lb _ci_ub _m1 if _m2==0, sort) ///
       (rcap _ci_lb _ci_ub _mx if _m2==1, sort) ///
       (connected _margin _m1 if _m2==0, msymbol(oh)) ///
       (connected _margin _mx if _m2==1, msymbol(o)) ///
       , title("") ///
        ytitle("Predicted self-rated health") xla(, valuelabel) ///
  legend(pos(4) ring(0) col(1) order(3 "West Germany" 4 "East Germany")) ///
  name(twoway, replace) ylabel(, format(%6.1f))

May 25, 2017

Random graphs (96): Categorical variables

use S003A S002 X001 C041 C039 C038 C037 if inlist(S002, 4, 5) ///
    using WVS_Longitudinal_1981-2014_stata_v_2014_11_25.dta, clear

// Declare missing values
mvdecode C041 C039 C038 C037, mv(-5 -4 -3 -2 -1)

// Factor analysis
factor C041 C039 C038 C037, pcf
alpha C041 C039 C038 C037, item
local alph = round(`r(alpha)', .01)

// Prepare variables
scores nonworkethic = mean(C041 C039 C038 C037), nv(3) 
generate workethic = 5 - nonworkethic 
gen male = (X001 == 1) if X001 != -2
drop nonworkethic X001
// Create descriptive plot foreach var of varlist C041 C039 C038 C037 { recode `var' (1 = 4 "Strongly agree") /// (2 = 3 "Agree") /// (3 = 2 "Neither agree nor disagree") /// (4 = 1 "Disagree") /// (5 = 0 "Strongly disagree"), gen(`var'_rec) numlabel `var'_rec, add mask("# ") twoway histogram `var'_rec, discrete horizontal yla(0/4, valuelabel) percent /// title("`: variable label `var''") /// ytitle("") /// name(`var', replace) nodraw drop `var'_rec } graph combine C041 C039 C038 C037, col(2) row(2) altshrink title("Work ethic is measured as the average of four items:") /// caption("In a PCA, all items load on one dimension; explained variance = 49%, Cronbach's alpha = `alph'", span) note("{it:Source:} WVS 1999-2009, pooled", span) name(figure1, replace) drop C041 C039 C038 C037
// Calculate country differences preserve statsby mean_ = _b[_cons] /// loci = (_b[_cons] - 1.96 * _se[_cons]) /// hici = (_b[_cons] + 1.96 * _se[_cons]) /// , by(S003A) clear: /// regress workethic // Sort coefficients by size egen order_ = rank(mean_), unique labmask order_, value(S003A) decode // Plot twoway (rcap mean_ mean_ order_, horizontal) /// (rspike loci hici order_, horizontal) /// , legend(off) ylabel(1/63, valuelabels ang(h) labsize(*.8)) /// xlabel(0 (1) 4, grid format(%6.1f)) name(all, replace) /// xmtick(0 (.5) 4) /// ytitle("") xtitle("Work ethic across countries") /// title("{bf:A}", justification(left) bexpand span) /// xscale(alt) ysize(10) nodraw restore // Country differences--men only preserve statsby mean_ = _b[_cons] /// loci = (_b[_cons] - 1.96 * _se[_cons]) /// hici = (_b[_cons] + 1.96 * _se[_cons]) /// , by(S003A) clear: /// regress workethic if male == 1 // Sort coefficients by size egen order_ = rank(mean_), unique labmask order_, value(S003A) decode // Plot twoway (rcap mean_ mean_ order_, horizontal) /// (rspike loci hici order_, horizontal) /// , legend(off) ylabel(1/63, valuelabels ang(h) labsize(*.8)) /// xlabel(0 (1) 4, grid format(%6.1f)) name(men, replace) /// xmtick(0 (.5) 4) /// ytitle("") xtitle("Men's work ethic across countries") /// title("{bf:B}", justification(left) bexpand span) /// xscale(alt) ysize(10) nodraw restore // Calculate gender gap preserve statsby mean_ = _b[male] /// loci = (_b[male] - 1.96 * _se[male]) /// hici = (_b[male] + 1.96 * _se[male]) /// , by(S003A) clear: /// regress workethic male // Sort coefficients by size egen order_ = rank(mean_), unique labmask order_, value(S003A) decode // Plot twoway (rcap mean_ mean_ order_, horizontal) /// (rspike loci hici order_, horizontal) /// , legend(off) ylabel(1/63, valuelabels ang(h) labsize(*.8)) /// xlabel(-.25 (.25) .5, grid format(%6.2f)) name(gendergap, replace) /// xmtick(-.25 (.1) .5) /// text(63 .5 "Men" "higher", place(sw)) /// text( 1 -.25 "Women" "higher", place(ne)) /// ytitle("") xtitle("Gender gap in work ethic") /// title("{bf:C}", justification(left) bexpand span) /// xscale(alt) ysize(10) nodraw restore graph combine all men gendergap, note(" " "{it:Source:} WVS 1999-2009, pooled", span) col(3) ysize(12) xsize(18) altshrink /// title("Work ethic in cross-national comparison", span) name(figure2, replace)

Feb 20, 2017

Random graphs (94): Predicted probabilities and their differences

use 2010_ah.dta

// Prepare variables
recode ahm2010_varhours (1 = 0 "Inflexible") (2 3 4 5 = 1 "Flexible"), gen(flexible)
label variable flexible "Flexible working hours"
decode country, gen(cntry)
gen female = (sex == 2) if !missing(sex) 

// Set up loop for posting results
preserve
levelsof cntry, local(country)

tempname foo
tempname foo2
postfile `foo' str20 cntry sexdiffer lb ub using `foo2', replace

foreach x of local country {
      // Estimate model
  qui logit flexible i.female if cntry == "`x'"             
      // Predict probabilities, the r operator gives
      // differences from the reference (base) level
  qui capture margins r.female if cntry == "`x'", post
  local differ      = 100 * _b[r1vs0.female]
  local differ_loci = 100 * (_b[r1vs0.female] + (1.96 * _se[r1vs0.female]))
  local differ_hici = 100 * (_b[r1vs0.female] - (1.96 * _se[r1vs0.female]))
  post `foo' ("`x'") (`differ') (`differ_loci') (`differ_hici')
}
postclose `foo'

// Plot results
use `foo2', clear
   // Sort by size
egen order_ = rank(-sexdiffer), unique
labmask order_, value(cntry)

twoway (rcap sexdiffer sexdiffer order_, horizontal dsymbol(x)) ///
       (rspike ub lb order_, horizontal ) , ///
        xline(0) ylabel(1/30, val ang(h)) ///
        ytitle("") ///
        xtitle("Gender gap in flexible hours" "(Women minus men)") ///
        xscale(alt) ///
        legend(off) ///
        name(by_sex, replace) 
restore 

Dec 27, 2016

Generating a country–year variable

use "C:\ess 1-7\ESS1-7e01.dta", clear

// Generate country-year variable
egen cyear = group(cntry essround)

// Fit three-level model
mixed happy || cntry: || cyear:, variance
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 24, 2016

Random graphs (91): Regression coefficients

// ESS round 1
use ESS1e06_4.dta, clear

// Prepare variables
  // Country variable
  encode cntry, gen(country)

  // Trade union membership
  recode trummb (0 = 0 "Non-member") (1 = 1 "Trade union member") (. = .), generate(unionmember)
  label var unionmember "Trade union member"

  // Age
  generate age = agea if agea != 999
  label var age "Age"

  // Sex
  gen female = (gndr == 2) if gndr != 9
  label var female "Female sex"
  label define female 1 "Female" 0 "Male"
  label val female female

  // Happiness
  recode happy (77 88 99 = .)

  // Center age and sex
  center age female
  
// First set of models
  preserve   
  statsby mean_ = _b[unionmember] ///
          loci  = (_b[unionmember] - 1.96 * _se[unionmember]) ///
          hici  = (_b[unionmember] + 1.96 * _se[unionmember]) ///
        , by(country) clear: ///
          regress happy unionmember

  // Sort coefficients by size
  egen order_ = rank(mean_), unique
  labmask order_, value(country) decode

  // Plot
  twoway (rcap mean_ mean_ order_, horizontal) ///
         (rspike loci hici order_, horizontal) ///
        , legend(off) ylabel(1/20, valuelabels ang(h) labsize(*.8)) ///
          xlabel(-.5 (.5) 1.5, grid format(%6.1f)) name(unadjusted, replace)  ///
          xmtick(-.5 (.1) 1.5) ///
          ytitle("") xtitle("Happiness advantage of trade union membership" " ") ///
          xscale(alt) ysize(4)
restore  

// Second set of models
  preserve   
  statsby mean_ = _b[unionmember] ///
          loci  = (_b[unionmember] - 1.96 * _se[unionmember]) ///
          hici  = (_b[unionmember] + 1.96 * _se[unionmember]) ///
        , by(country) clear: ///
          regress happy unionmember c_female c_age

  // Sort coefficients by size
  egen order_ = rank(mean_), unique
  labmask order_, value(country) decode

  // Plot
  twoway (rcap mean_ mean_ order_, horizontal) ///
         (rspike loci hici order_, horizontal) ///
        , legend(off) ylabel(1/20, valuelabels ang(h) labsize(*.8)) ///
          xlabel(-.5 (.5) 1.5, grid format(%6.1f)) name(adjusted, replace)  ///
          xmtick(-.5 (.1) 1.5) ///
          ytitle("") xtitle("Happiness advantage of trade union membership" "(adjusted for age and sex)") ///
          xscale(alt) ysize(4)
  restore  
  
// Plot both underneath one another
graph combine unadjusted adjusted, row(2) ysize(8) xcommon name(combined, replace) ///
          note(" " ///
             "{it:Source:} ESS round 1, own calculations. {it:Note:} Error bars denote 95% confidence intervals." , span size(*.8))  

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"))

May 20, 2016

Merging the Demographic and Health Surveys in Stata

// Unzip files
clear
cd "C:\dhs"

local filelist : dir . files "*.zip"  // Create local with all filenames ending with ".zip"
di `filelist'

local first : word 1 of `filelist'      // Identify first file
di "`first'"

local total_ : word count `filelist' // Identify total number of files
di `total_'        

forvalues x = 1/`total_' {
    di `x'
    local y : word `x' of `filelist'
    unzipfile "`y'", replace
}

// Append all files
clear
cd "C:\dhs"
local directorylist : dir . dirs  "*ir*"  // Create local with all directory names that contain women's data

di `directorylist'

local firstdir : word 1 of `directorylist'      // Identify first directory
di "`firstdir'"

local total_ : word count `directorylist' // Identify total number of directories
di `total_'

local firstfile = strupper("`firstdir'")
local firstfile = subinstr("`firstfile'","DT","FL",.)
di "`firstfile'"

use caseid v000 v005 v007 v012 v106 v107 v155 v191 v201 v212 v525 v531 using "`firstdir'/`firstfile'", clear                    
capture decode v106, gen(v106s)
drop v106

save testfile, replace

forvalues x = 2/`total_' {
    local y : word `x' of `directorylist'
 local filename = strupper("`y'")
    local filename = subinstr("`filename'", "DT", "FL", .)
 use "`y'/`filename'", clear
 
 // Source: https://stackoverflow.com/questions/17056016/stata-how-to-keep-a-list-of-variables-given-some-of-them-may-not-exist
 local masterlist "caseid v000 v005 v007 v012 v106 v107 v155 v191 v201 v212 v525 v531"
    local keeplist = ""

    foreach i of local masterlist  {
    capture confirm variable `i'
        if !_rc {
            local keeplist "`keeplist' `i'"
        }
     }
    keep `keeplist'
 capture decode v106, gen(v106s)
    capture drop v106
 
 tempfile new
 save `new', replace
 use testfile, clear
 append using `new', force
 save testfile, replace
}

// Prepare variables
use testfile, clear

//Country and wave identifiers
replace v000 = "VN3" if v000 == "VNT"
generate cntry = substr(v000,1,2)
generate wavex  = substr(v000,3,1)
replace wavex = "1" if wavex == ""
encode wavex, gen(wave)
drop wavex

  // Fix unusual country abbreviations
replace cntry = "BI" if cntry == "BU"
replace cntry = "IN" if cntry == "IA"
replace cntry = "KZ" if cntry == "KK"
replace cntry = "BI" if cntry == "BU"
replace cntry = "MD" if cntry == "MB"
replace cntry = "NA" if cntry == "NM"
replace cntry = "DO" if cntry == "DR"

kountry cntry, from(iso2c)
encode NAMES_STD, gen(country)
drop NAMES_STD

// Select last wave
keep if wave == 6

// Prepare variables
  // Age at first intercourse
generate age1stintercourse = .
replace  age1stintercourse = v531 if inrange(v531, 1, 63)
replace  age1stintercourse = .a   if v525 == 0
replace  age1stintercourse = .b   if v525 == 95
replace  age1stintercourse = .c   if v525 == 97
replace  age1stintercourse = .d   if v525 == 98
replace  age1stintercourse = .e   if v525 == 99
label define age1stintercourse .a "Not had intercourse" ///
                               .b "95?" ///
                               .c "inconsistent" ///
                               .d "don't know" ///
                               .e "99?" 
label val age1stintercourse age1stintercourse
label var age1stintercourse "Age at first intercourse"

  // Age at first birth
rename v212 afb
label var afb "Age at first birth"

// Calculate correlation
preserve
statsby mean_ = _b[age1stintercourse] ///
        loci  = (_b[age1stintercourse] - 1.96 * _se[age1stintercourse]) ///
        hici  = (_b[age1stintercourse] + 1.96 * _se[age1stintercourse]) ///
      , by(country) total clear: ///
        regress afb age1stintercourse

// Label total value
replace country = 1000 if country == .
label define country 1000 "{bf: Total}", modify

egen order_ = rank(mean_), unique
labmask order_, value(country) decode

// Plot
twoway (rcap mean_ mean_ order_, horizontal) ///
       (rspike loci hici order_, horizontal) ///
      , legend(off) ylabel(1/38, valuelabels ang(h) labsize(*.8)) ///
        xlabel(.7 (.1) 1.0, grid format(%6.1f)) name(ols, replace)  ///
        xmtick(.7 (.05) 1.0) ///
        ytitle("") xtitle("Association between" ///
                          "age at first intercourse" ///
                          "and age at first birth") xscale(alt) ysize(8) ///
        note(" " ///
             "{it:Source:} DHS VI, own calculations" , span size(*.8))
restore

Apr 30, 2016

Random graphs (79): Means with confidence intervals

use ZA5900_v3-0-0.dta, replace

renvars, lower // Switch variable names to lower case

// Fix country variable
generate cntry = c_alphan
replace  cntry = "GB" if cntry == "GB-GBN"
replace  cntry = "DE" if cntry == "DE-E"   | cntry == "DE-W"
replace  cntry = "BE" if cntry == "BE-BRU" | cntry == "BE-WAL" | cntry == "BE-FLA" 

// Generate country name variable
kountry cntry, from(iso2c)
encode NAMES_STD, gen(country)
drop NAMES_STD

// Happiness variable
recode v55 (1 = 6) (2 = 5) (3 = 4) (4 = 3) (5 = 2) (6 = 1) (7 = 0) (0 8 9 = .), gen(lsat)

label define lsat 0 "Completely unhappy" ///
                  1 "Very unhappy" ///
                  2 "Fairly unhappy" ///
                  3 "Neither happy nor unhappy" ///
                  4 "Fairly happy" ///
                  5 "Very happy" ///
                  6 "Completely happy"
label val lsat lsat
label var lsat "Happiness"

// Plot means by country
preserve
statsby mean_ = _b[_cons] ///
        loci  = (_b[_cons] - 1.96 * _se[_cons]) ///
        hici  = (_b[_cons] + 1.96 * _se[_cons]) ///
      , by(country) total clear: ///
        regress lsat

replace country = 1000 if country == .
label define country 1000 "{bf: Total}", modify

egen order_ = rank(mean_), unique
labmask order_, value(country) decode

twoway (rcap mean_ mean_ order_, horizontal) ///
       (rspike loci hici order_, horizontal) ///
      , legend(off) ylabel(1/41, valuelabels ang(h) labsize(*.8)) ///
        xlabel(3.5 (.5) 5.0, grid format(%6.1f)) name(lsat, replace)  ///
        xmtick(3.5 (.25) 5.0, grid) ///
        ytitle("") xtitle("Average happiness") xscale(alt) ysize(8) ///
        note(" " ///
             "{it:Note:} Happiness ranges from 0 ('Completely unhappy') to 6 ('Completely happy')" ///
             "{it:Source:} ISSP 2012, doi:10.4232/1.12339" , span size(*.8))
restore

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 28, 2016

Random graphs (67): Dot plots with confidence intervals

clear
input str20 cntry str30 outcome lb icc ub
"Finland"   "Attainment" .35 .36 .38
"Germany"   "Attainment" .43 .51 .60
"Norway"   "Attainment" .41 .41 .42
"Sweden"   "Attainment" .41 .41 .42
"United Kingdom" "Attainment" .34 .44 .54
"United States"  "Attainment" .49 .51 .53
"Finland"   "GPA"        .   .   .
"Germany"   "GPA"        .19 .23 .28
"Norway"   "GPA"        .48 .48 .48
"Sweden"   "GPA"        .52 .52 .52
"United Kingdom" "GPA"        .   .   .
"United States"  "GPA"        .37 .41 .46
"Finland"   "Cognitive skills"  .   .   .
"Germany"   "Cognitive skills"  .39 .46 .52
"Norway"   "Cognitive skills"  .   .   .
"Sweden"   "Cognitive skills"  .50 .50 .51
"United Kingdom" "Cognitive skills"  .   .   .
"United States"  "Cognitive skills"  .55 .57 .60
end

// Defining the label first allows to determine order of -encode- categories
label define country 1 "Finland" 2 "Germany" 3 "Norway" 4 "Sweden" ///
                     5 "United Kingdom" 6 "United States"
encode cntry, gen(country) label(country)

twoway (rcap icc icc country, by(outcome, note("") row(1) legend(off)) horizontal) ///
       (rspike ub lb country, by(outcome) horizontal) ///
      , ylabel(1/6, val)  ytitle("") xscale(alt) yscale(reverse) 

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

Mar 6, 2016

Shrinkage (partial pooling) in multilevel models

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

// Drastically reduce sample size
bysort cntry essround: keep if _n < 5

// Encode country variable
encode cntry, gen(country)

// Fit random intercept model
mixed happy || country: 
predict u0, reffects
predict u0se, reses

// Calculate posterior intercept
generate eb_happy = u0 + _b[_cons]

// Plot posterior intercept
preserve
egen pickone = tag(country)
keep if pickone
   
egen order_ = rank(-u0), unique
labmask order_, value(country) decode

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

twoway (rcap eb_happy eb_happy order_, dsymbol(x)) ///
       (rspike high low order_) , ///
        yline(`avg') xlabel(1/32, val ang(v)) ///
        xtitle("") ///
        ylabel(4/10) ///
        ytitle("Country-level residuals + intercept") ///
        legend(off) ///
        title("Random intercept model") ///
        name(emp_bayes, replace) nodraw
restore

// Fit OLS models
regress happy
local avg =  _b[_cons]
regress happy i.country
predict avg_happy
predict se_happy, stdp

// Plot OLS estimates
preserve
egen pickone = tag(country)
keep if pickone
   
egen order_ = rank(-avg_happy), unique
labmask order_, value(country) decode

gen high = avg_happy + (1.96 * se_happy)
gen low  = avg_happy - (1.96 * se_happy)

twoway (rcap avg_happy avg_happy order_, dsymbol(x)) ///
       (rspike high low order_) , ///
        yline(`avg') xlabel(1/32, val ang(v)) ///
        xtitle("") ///
        ylabel(4/10) ///
        ytitle("Country-level means") ///
        legend(off) ///
        title("OLS regression model") ///
        name(plain, replace) nodraw
restore

graph combine emp_bayes plain, col(1) ysize(8) name(combo, replace)


// Plot EB and OLS means against one another to illustrate 
// shrinkage in multilevel modeling

preserve
egen pickone = tag(country)
keep if pickone
twoway (scatter eb_happy avg_happy) ///
       (function y = x, range(0 10)), ///
    legend(off) xtitle("OLS estimates") ytitle("Posterior intercept") ///
    title("Shrinkage")
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 

Jan 30, 2016

Random graphs (56): Intraclass Correlation Coefficients with confidence intervals


webuse productivity, clear

tempname foo
postfile `foo' str100 commandline_str str100 description_str icc icclb iccub N N_groups using "C:\Windows\Temp\test.dta", replace

qui mixed gsp || region: if year <= 1973
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]
local desc "ICC 1970 to 1973"

post `foo' (e(cmdline)) ("`desc'") (r(icc2)) (icclb) (iccub) (e(N)) (n_g)

qui mixed gsp || region: if year >= 1974 | year <= 1977
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]
local desc "ICC 1974 to 1977"

post `foo' (e(cmdline)) ("`desc'") (r(icc2)) (icclb) (iccub) (e(N)) (n_g)

qui mixed gsp || region: if year >= 1978 | year <= 1981
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]
local desc "ICC 1978 to 1981"

post `foo' (e(cmdline)) ("`desc'") (r(icc2)) (icclb) (iccub) (e(N)) (n_g)

qui mixed gsp || region: if year >= 1981 | year <= 1984
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]
local desc "ICC 1981 to 1984"

post `foo' (e(cmdline)) ("`desc'") (r(icc2)) (icclb) (iccub) (e(N)) (n_g)

qui mixed gsp || region: if year >= 1985 | year <= 1986
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]
local desc "ICC 1985 to 1986"

post `foo' (e(cmdline)) ("`desc'") (r(icc2)) (icclb) (iccub) (e(N)) (n_g)

postclose `foo'

use "C:\Windows\Temp\test.dta", clear
list

encode description_str, gen(description)
twoway (dot icc description, horizontal) ///
       (rcap icclb iccub description, horizontal)  ///
  , ylabel(1/5, val) ytitle("") legend(off) ///
    xlabel(0 (.1) 1) xtitle("ICC") name(figure, replace)
  
  
erase "C:\Windows\Temp\test.dta"

Sep 30, 2015

Random graphs (53): Visualizing multilevel models

use cntry happy mnactic agea gndr using ESS1e06_4.dta, clear

// Prepare variables
recode agea (999 = .), gen(age)
recode gndr (1 = 0 "Male") (2 = 1 "Female") (9 = .), gen(female)
recode mnactic (77 88 99 = .), gen(active)
label var female "Sex (ref. Male)"
label var age    "Age in decades"
label var happy  "Happiness"
label var active "Labor market status"
label val active mnactic

center happy age // Center outcome to make intercept smaller for plot
replace c_age = c_age / 10

// Listwise deletion
drop if missing(female, c_age, c_happy, active, cntry)
drop happy gndr agea mnactic // Unecessary variables can go

// Fit model
mixed c_happy c_age i.female i.active || cntry: c_age, ml cov(uns)

// Save random part
local var_age = round(exp(_b[lns1_1_1:_cons])^2, .0001)
local var_int = round(exp(_b[lns1_1_2:_cons])^2, .0001)
local covaria = round(tanh(_b[atr1_1_1_2:_cons]) * ///
                       exp(_b[lns1_1_1:_cons]) * ///
        exp(_b[lns1_1_2:_cons]), .0001)

// Plot fixed part
coefplot, xline(0) ///
xtitle(" " "Estimates and 95% CI's") ///
scheme(s1mono) ///
ciopts(recast(rcap)) ///
coeflabels(_cons = "{bf:Intercept}" ///
           c_age = "{bf:Age} in decades" ///
     8.active = "Housework") ///  // Shorten label
headings(c_age = " " ///
         1.female  = "{bf:Sex} ({it:ref.} Male)" ///
         2.active = `""{bf:Labor market status}" "({it:ref.} Paid work)""' ///
   _cons = " ") ///
mlabel format(%9.2f) mlabposition(12) mlabgap(*1.5) ///
xscale(alt) msymbol(x) ///
ysize(8) xsize(4) ///
title("Fixed part", span) ///
name(fixed_part, replace) nodraw

/* The default sizes of the available area are -ysize(4)- and -xsize(5.5)-,
   by the way. Letter size is -ysize(11)- and -xsize(8.5)-*/

// Plot random part   
  // Estimate residuals
capture drop u1* u0*
predict u1 u0, reffects 
predict u1se u0se, reses   

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

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

twoway (rcap u0 u0 order_, dsymbol(x)) ///
       (rspike high low order_) , ///
        yline(0) xlabel(1/22, val ang(v)) ///
        title("Intercept variance = `var_int'") ///
        xtitle("") ///
        ytitle("Random intercept residuals") ///
        legend(off) ///
        name(rand_int, replace) nodraw
restore 

  // Plot slope 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/22, val ang(v)) ///
        xtitle("") ///
        title("Slope variance = `var_age'") ///
        ytitle("Random slope residuals") ///
        ylabel(-1 (.5) 1) ///  // Make y-axis identical to other plot,
        legend(off) ///        // otherwise x-axis looks different, too
        name(rand_slope, replace) nodraw
restore 

  // Plot intercept-slope covariance
preserve

gen predRandomSlope= (_b[_cons] + u0) + ((_b[c_age] + u1) * c_age)
qui sum c_age
local hi1 =  1*r(sd)
local hi2 =  2*r(sd)
local hi3 =  3*r(sd)
local lo1 = -1*r(sd)
local lo2 = -2*r(sd)
      
sort cntry c_age
twoway (line predRandomSlope c_age, connect(ascending)), ///
        ytitle("Predicted Happiness") /// 
        xtitle("") ///
        title("Intercept{c 150}slope covariance = `covaria'") ///
        xlabel(`lo1' "-1 SD" 0 "Average age" `hi1' "+1 SD" `hi2' "+2 SD" `hi3' "+3 SD") ///
        ylabel(,format(%6.1f)) ///
        name(covariance, replace) nodraw
restore

// Combine Figures
graph combine rand_int rand_slope covariance, col(1) ysize(8) title("Random part") name(random_part, replace) nodraw
graph combine fixed_part random_part, col(2) ysize(8) xsize(8) altshrink title("Random coefficient model")

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))

Oct 15, 2014

Random graphs (33): Regression parameters

 
use V4 V56 SEX using "ZA5900_v2-0-0.dta", replace // ISSP 2012 data

renvars, lower // Switch variable names to lower case

kountry v4, from(iso3n) to(iso2c)  // Generate country abbreviation variable
replace _ISO2C_ = "RU" if v4 == 643
encode _ISO2C_, gen(country)

drop if cntry == "ZA" // v56 missing in ZA

// Prepare variables
recode sex (9 = .)
recode v56 (0 8 9 = .), gen(jobsat_rev)
generate jobsat = 7 - jobsat_rev
label define jobsat 6 "Completely satisfied" ///
                    3 "Neither satisfied nor dissatisfied" ///
                    0 "Completely dissatisfied"
label value jobsat jobsat

preserve

// Save parameters
statsby gendergap = _b[sex]  ///
        loci      = (_b[sex] - 1.96 * _se[sex]) ///
        hici      = (_b[sex] + 1.96 * _se[sex]) ///  
  , by(country) clear total: ///
  regress jobsat sex

replace country = 1000 if country == .  // Label parameter from total sample
label define country 1000 "{bf: Total}", modify // Label parameter from total sample

egen order_ = rank(-gendergap), unique
labmask order_, value(country) decode

twoway (dot gendergap order_, msize(vsmall)) ///
       (rcap loci hici order_) ///
     , legend(off) xlabel(1/37, valuelabels ang(v)) ///
       yline(0) note("{it:Source:} ISSP 2012 (Family and Changing Gender Roles IV), own calculations", span) ///
       ylabel(,format(%6.1f)) name(gendergap, replace) ///
       xtitle(" ") ytitle("Gender gap in job satisfaction")

restore

Oct 7, 2014

Random graphs (32): Dot plot with confidence intervals

// Read in data points
input str50 variable_str coeff se
"Discrimination in being hired" .18 .08
"Vocational index" 1.97 .53
end

// Switch to numeric
encode variable_str, gen(variable) 

// Create variable for -by-
recode variable (1 = 2 "Model 2") (2 = 1 "Model 1"), gen(model)

// Calculate 95 % CI's
gen loci = coeff - 1.96 * se
gen hici = coeff + 1.96 * se

twoway (dot coeff variable, by(model, legend(off) note("")) ///
                               horizontal dotextend(no)) ///
       (rcap hici loci variable, horizontal) ///
       , legend(off) ylabel(1/2, valuelabels) ///
         xline(0) ytitle("") ///
         ysize(4) yscale(range(0 3))