// Open General Social Survey data
use wtssall year health1 parsol ///
if inlist(year, 2002, 2004, 2006, 2010, 2014, 2018) ///
using "data/GSS7218_R2.DTA", clear
// Listwise deletion
keep if !missing(health1, parsol)
// Fix health variable
recode health1 (4 5 = 1 "Poor health") ///
(3 2 1 = 0 "Good health"), gen(poorhealth)
label var poorhealth "Poor health"
// Collapse data set
collapse poorhealth [pw = wtssall], by(year parsol)
replace poorhealth = poorhealth * 100
// Create figure
foreach x of numlist 2002 2006 2010 2014 2018 {
local 2002 gs11
local 2006 gs11
local 2010 gs11
local 2014 gs11
local 2018 gs11
local `x' red
twoway (line poorhealth parsol if year == 2002, lcolor(`2002') lstyle(solid)) ///
(line poorhealth parsol if year == 2006, lcolor(`2006') lstyle(solid)) ///
(line poorhealth parsol if year == 2010, lcolor(`2010') lstyle(solid)) ///
(line poorhealth parsol if year == 2014, lcolor(`2014') lstyle(solid)) ///
(line poorhealth parsol if year == 2018, lcolor(`2018') lstyle(solid)) ///
, title({bf:`x'}, justification(left) bexpand span) ///
ytitle("% poor health") ///
xtitle("Living standard compared to parents'") ///
xlabel(1 `""Much" "better""' ///
2 `""Somewhat" "better""' ///
3 `""About" "the same""' ///
4 `""Somewhat" "worse""' ///
5 `""Much" "worse""' ///
, val) ///
name(year`x', replace) legend(off) nodraw
}
graph combine year2002 ///
year2006 year2010 ///
year2014 year2018, ///
col(2) ysize(8) altshrink ///
note("{it: Note:} Weighted with WTSSALL", size(vsmall)) ///
name(figure, replace)
Showing posts with label collapse. Show all posts
Showing posts with label collapse. Show all posts
Apr 24, 2020
Random graphs (145): Uncluttered line graphs
Labels:
collapse,
General Social Survey,
Random graphs,
twoway line
Oct 11, 2017
Random graphs (114): Line plot and choropleth
use ESS1-7e01, clear
// Country name variable
kountry cntry, from(iso2c) marker
rename NAMES_STD country
// Create No contract variable
gen nocontract = (wrkctra == 3) if !missing(wrkctra)
// Calculate per year and country
preserve
statsby cont = _b[_cons] contse = _se[_cons], by(country essround) clear: regress nocontract
replace cont = cont * 100 // Convert proportion into precentage
generate lb = cont - (contse * 100)
generate ub = cont + (contse * 100)
label define essround 1 "2002" 2 "2004" 3 "2006" 4 "2008" 5 "2010" 6 "2012" 7 "2014", modify
sort essround country
twoway (rarea lb ub essround) ///
(connected cont essround), ///+
by(country, legend(off) note(" " "{it:Source:} ESS 2002-2014", span) ///
title("{bf:A}", justification(left) bexpand span)) ///
xtitle("") xlabel(1/7, val ang(45)) ytitle("% no contract") ///
xsize(6) ysize(6) ///
name(figurea, replace)
restore
// Calculate average % no contracts per country
collapse nocontract, by(cntry)
replace nocontract = nocontract * 100
format nocontract %6.1f
saveold cont, replace
// Read in map data
// Source: shapefile from http://www.naturalearthdata.com/downloads/10m-cultural-vectors/
shp2dta using "maps\ne_10m_admin_0_countries", database(database) coordinates(coordinates) genid(id) replace
// Restrict coordinates to Europe
// Source: https://en.wikipedia.org/wiki/Extreme_points_of_Europe
use coordinates, clear
replace _Y = . if _Y < 36
replace _Y = . if _Y > 71 & !missing(_Y)
replace _X = . if _X < -28
replace _X = . if _X > 33 & !missing(_X)
saveold europecoordinates, replace
// Create data set with Europe internal borders
clonevar id = _ID
merge m:1 id using database, nogenerate
keep if CONTINENT == "Europe"
saveold europe, replace
// Merge map data with set with data to be plotted
use ISO_A2 NAME id using database, clear
rename ISO_A2 cntry
replace cntry = "FR" if NAME == "France" // Somehow not correct in map
replace cntry = "NO" if NAME == "Norway" // Somehow not correct in map
drop if cntry == "-99"
merge 1:1 cntry using cont, keep(matched) nogenerate
spmap nocontract using europecoordinates, id(id) xsize(6) ysize(6) ///
polygon(data(europe)) legstyle(2) clnumber(9) ///
legend(position (9) ring(0)) fcolor(Oranges) ///
legorder(hilo) ocolor(none ..) ///
title("{bf:B}", justification(left) bexpand span) ///
legtitle("{bf:% no contract, 2002-2014 averages}") legjunction({c 150}) ///
note(" " "{it:Source:} ESS 2002-2014", span) name(figureb, replace)
graph combine figurea figureb, row(1) xsize(12)
Jul 29, 2017
OLS regression: overfitting and dichotomization
Babyak (2004) demonstrates a couple of aspects of OLS regression, making use of the following simulations:
// Figure 1
set seed 1
// Create file to store simulation results
tempname foo
postfile `foo' b using clt, replace
// Simulate analyses
forvalues i = 1/10000 {
drop _all
qui set obs 100
generate x = rnormal()
generate e = rnormal()
generate y = .4 * x + e
qui regress y x
local b = _b[x]
post `foo' (`b')
}
postclose `foo'
// Open results from simulations and plot
use clt, clear
histogram b, freq ytitle("Frequency of b value") xtitle("Values of b") name(figure1, replace)
// Figure 2
set seed 1
// Create file to store simulation results
tempname foo
postfile `foo' r2_50 r2_100 r2_150 r2_200 using overfitting, replace
// Simulate analyses
forvalues i = 1/10000 {
drop _all
set obs 10000
generate y = rnormal()
foreach i of numlist 1/15 {
generate x`i' = rnormal()
}
foreach j of numlist 50 100 150 200 {
preserve
sample `j', count
qui reg y x*
local r2_`j' = e(r2)
restore
}
post `foo' (`r2_50') (`r2_100') (`r2_150') (`r2_200')
}
postclose `foo'
// Open results from simulations
use overfitting, clear
// Plot
twoway (kdensity r2_200) ///
(kdensity r2_150) ///
(kdensity r2_100) ///
(kdensity r2_50) ///
, ytitle("Percent of samples") ///
xtitle("R-square value from regression model") ///
xlabel(0 (.1) .6) ///
ylabel(0 (2) 20) ///
legend(order(1 "ca. 13 cases/predictor ({it:N} = 200)" ///
2 "10 cases/predictor ({it:N} = 150)" ///
3 "ca. 7 cases/predictor ({it:N} = 100)" ///
4 "ca. 3 cases/predictor ({it:N} = 50)") ///
pos(2) ring(0)) name(figure2, replace)
// Figure 2
set seed 1
// Create file to store simulation results
tempname foo
postfile `foo' r2_50 r2_100 r2_150 r2_200 using overfitting, replace
// Simulate analyses
forvalues i = 1/10000 {
drop _all
set obs 10000
generate y = rnormal()
foreach i of numlist 1/15 {
generate x`i' = rnormal()
}
foreach j of numlist 50 100 150 200 {
preserve
sample `j', count
qui reg y x*
local r2_`j' = e(r2)
restore
}
post `foo' (`r2_50') (`r2_100') (`r2_150') (`r2_200')
}
postclose `foo'
// Open results from simulations
use overfitting, clear
// Plot
twoway (kdensity r2_200) ///
(kdensity r2_150) ///
(kdensity r2_100) ///
(kdensity r2_50) ///
, ytitle("Percent of samples") ///
xtitle("R-square value from regression model") ///
xlabel(0 (.1) .6) ///
ylabel(0 (2) 20) ///
legend(order(1 "ca. 13 cases/predictor ({it:N} = 200)" ///
2 "10 cases/predictor ({it:N} = 150)" ///
3 "ca. 7 cases/predictor ({it:N} = 100)" ///
4 "ca. 3 cases/predictor ({it:N} = 50)") ///
pos(2) ring(0)) name(figure2, replace)
// Figure 4 (actually Table 1)
clear
set seed 1
// Create file to store simulation results
tempname foo
postfile `foo' n correlation typei using dichotomization, replace
// Simulate analyses
forvalues i = 1/10000 {
drop _all
foreach j of numlist 50 100 200 {
foreach k of numlist 0 .3 .5 .7 {
qui drawnorm x1 x2, ///
n(`j') ///
corr(1, `k', 1) cstorage(lower) ///
clear
generate e = rnormal()
generate y = .5*x1 + 0*x2 + e
qui sum x1, detail
generate x1s = (x1 > r(p50))
qui sum x2, detail
generate x2s = (x2 > r(p50))
qui reg y x1s x2s
local typei = _b[x2s]/_se[x2s]
local sig = (abs(`typei') > 1.96)
*di _b[x2s] _skip(5) _se[x2s] _skip(5) `typei' _skip(5) `sig'
post `foo' (`j') (`k') (`sig')
}
}
}
postclose `foo'
// Open results from simulations
use dichotomization, clear
collapse typei, by(n correlation)
graph hbar typei, over(n, relabel(1 "{it:N} = 50" 2 "{it:N} = 100" 3 "{it:N} = 200")) ///
over(correlation, relabel(1 "{it:Corr(x{sub:1}, x{sub:2})} = 0" ///
2 "{it:Corr(x{sub:1}, x{sub:2})} = .3" ///
3 "{it:Corr(x{sub:1}, x{sub:2})} = .5" ///
4 "{it:Corr(x{sub:1}, x{sub:2})} = .7")) ///
ytitle("Type I error rate") yscale(alt) ylabel(, format(%6.2f)) ///
name(figure4, replace)
Reference
Babyak, Michael A. 2004. "What You See May Not Be What You Get. A Brief, Nontechnical Introduction to Overfitting in Regression-Type Models." Psychosomatic Medicine 66(3):411-421. doi: 10.1097/01.psy.0000127692.23278.a9
Labels:
collapse,
drawnorm,
graph hbar,
Histogram,
Simulation,
Textbooks,
twoway kdensity
Jul 27, 2017
Random graphs (105): Scatterplot
// Open ISSP data
use C_ALPHAN SEX V51 WEIGHT using ZA4350_v2-0-0.dta, clear
// Fix country variable
replace C_ALPHAN = "BE" if C_ALPHAN == "BE-FLA"
replace C_ALPHAN = "DE" if C_ALPHAN == "DE-E"
replace C_ALPHAN = "DE" if C_ALPHAN == "DE-W"
replace C_ALPHAN = "UK" if C_ALPHAN == "GB-GBN"
// Recode job satisfaction
recode V51 (7 = 0 "Completely dissatisfied") ///
(6 = 1 "Very dissatisfied") ///
(5 = 2 "Fairly dissatisfied") ///
(4 = 3 "Neither satisfied nor dissatisfied") ///
(3 = 4 "Fairly satisfied") ///
(2 = 5 "Very satisfied") ///
(1 = 6 "Completely satisfied"), gen(jobsat)
label var jobsat "Job satisfaction"
// Recode sex
gen female = (SEX == 2) if !missing(SEX)
label define female 0 "Male" 1 "Female"
label val female female
label var female "Sex"
drop if missing(female)
// Get rid of old variables
drop SEX V51
// Collapse and reshape data
collapse jobsat [pw = WEIGHT], by(C_ALPHAN female)
reshape wide jobsat, i(C_ALPHAN) j(female)
label var jobsat0 "Job satisfaction: men"
label var jobsat1 "Job satisfaction: women"
// Plot
twoway (scatter jobsat0 jobsat1 if jobsat0 > jobsat1, mlabel(C_ALPHAN) mlabpos(9)) ///
(scatter jobsat0 jobsat1 if jobsat0 < jobsat1, mlabel(C_ALPHAN) mlabpos(6)) ///
(function y = x, range(3.5 5.1)) ///
, xlabel(3.5 (.5) 5.0, format(%6.2f)) ///
ylabel(3.5 (.5) 5.0, format(%6.2f)) ///
ytitle("Job satisfaction: men") ///
xtitle("Job satisfaction: women") ///
title("Cross-national variation in the gender gap in job satisfaction", span) ///
note(" " "{it:Source:} International Social Survey Program (ISSP) 2005, doi:10.4232/1.11648", span) ///
legend(off) name(figure1, replace)
Jul 10, 2017
Random graphs (102): Sparklines
use v151 year ost_west if ost_west == 1 using ZA4582_v1-0-0.dta, clear
// Year
label drop year
label var year ""
// Subjective social class
recode v151 (9 = .a "No response") ///
(8 = .b "Don't know") ///
(7 = .c "Refused") ///
(6 = .d "None of the strata") ///
(5 = 5 "Upper class") ///
(4 = 4 "Upper middle class") ///
(3 = 3 "Middle class") ///
(2 = 2 "Working class") ///
(1 = 1 "Lower class") ///
, gen(subjclass)
label var subjclass "Subjective social class"
qui tab subjclass, gen(subjx)
// Change value labels in bulk
foreach var of varlist subjx* {
local lab `: var label `var''
local lab `: di subinstr("`lab'", "subjclass==", " ", 1)'
label var `var' "`lab'"
}
// Collapse data set
// Copy variable labels before collapse
// Following:
// http://www.stata.com/support/faqs/data-management/keeping-same-variable-with-collapse/
foreach var of var subjx* {
local l`var' : variable label `var'
if `"`l`var''"' == "" {
local l`var' "`var'"
}
}
// Collapse
collapse subjx*, by(year)
// Restore value labels after collapse
foreach var of var subjx* {
label var `var' "`l`var''"
}
// Change to percentages
foreach var of var subjx* {
replace `var' = `var' * 100
}
// Sparklines
sparkline subjx* year, variablelabels xlabel(1980 (10) 2010) xmtick(1980 (2) 2014) ///
xtitle("") format(%6.1f) extremes ///
title("Subjective social class in Western Germany", span) ///
name(subjclass, replace)
May 28, 2016
Random graphs (87): Line plots
unzipfile ZA4582_v1-0-0.dta.zip
use ZA4582_v1-0-0.dta, clear
// Prepare some variables
recode v442 (0 = .a "Not asked") ///
(1 = 3 "Daily") ///
(2 = 2 "At least once per week") ///
(3 = 1 "At least once per month") ///
(4 5 = 0 "Less often/never") ///
(9 = .b "No answer"), generate(internet_inc1998)
recode v462 (0 = .a "Not asked") ///
(1 = 3 "Daily") ///
(2 = 2 "At least once per week") ///
(3 = 1 "At least once per month") ///
(4 5 = 0 "Less often/never") ///
(9 = .b "No answer"), generate(internet_inc2014)
recode v1910 (0 = .a "Not asked") ///
(1 = 3 "Daily") ///
(2 = 8 "Several times a week") ///
(3 = 2 "At least once per week") ///
(4 = 1 "At least once per month") ///
(5 = 0 "Less than once per week") ///
(9 = .b "No answer"), generate(internet_inc2006)
recode v1909 (0 = .a "Missing") ///
(1 = 1 "Yes") ///
(2 = 0 "No"), gen(internet_prev2006)
// Daily and weekly usage
clonevar internet_inc = internet_inc1998
replace internet_inc = internet_inc2014 if year == 2014
preserve
qui tab internet_inc, gen(usage)
rename usage4 dailyusage
rename usage3 weeklyusage
collapse dailyusage weeklyusage, by(year)
replace dailyusage = dailyusage * 100
replace weeklyusage = weeklyusage * 100
drop if missing(dailyusage)
twoway (scatter weeklyusage year, connect(L)) ///
(scatter dailyusage year, connect(L)) ///
, legend(order(1 "At least once per week" ///
2 "Daily") title("Internet usage", size(*.8)) ring(0) pos(11)) ///
xlabel(1998 2004 2014) xtitle("") ytitle(%) ylabel(0 (10) 60) ///
note(" " "{it:Source:} German General Social Survey (Allbus), doi: 10.4232/1.12439" ///
"{it:Note:} Based on recodings of v442 and v462.", span) name(internet1, replace)
restore
// Daily internet usage based on different response formats
replace internet_inc = internet_inc2006 if year == 2006 | year == 2008
preserve
qui tab internet_inc, gen(usage)
rename usage4 dailyusage
collapse dailyusage, by(year)
replace dailyusage = dailyusage * 100
drop if missing(dailyusage)
twoway (scatter dailyusage year, connect(L)) ///
, xlabel(1998 2004 2006 2008 2014) xtitle("") ytitle("% of respondents reporting" "{bf:daily} internet usage") ylabel(0 (10) 60) ///
note(" " "{it:Source:} German General Social Survey (Allbus), doi: 10.4232/1.12439" ///
"{it:Note:} Based on recodings of v442, v462, and v1910.", span) name(internet2, replace)
restore
// Yes/no question
preserve
collapse internet_prev, by(year)
drop if missing(internet_prev)
replace internet_prev = internet_prev * 100
twoway (scatter internet_prev year, connect(L)) ///
, xlabel(2006 2008 2010 2012 2014) xtitle("") ytitle("% of respondents using the internet") ylabel(0 (10) 80) ///
note(" " "{it:Source:} German General Social Survey (Allbus), doi: 10.4232/1.12439. {it:Note:} Based on v1909.", span) ///
name(internet3, replace)
restore
erase ZA4582_v1-0-0.dta
Labels:
Allbus,
collapse,
Random graphs,
twoway scatter
May 25, 2016
Random graphs (85): Area plot
unzipfile ZA4582_v1-0-0.dta.zip
use ZA4582_v1-0-0.dta, clear
recode v151 (9 = .a "No response") ///
(8 = .b "Don't know") ///
(7 = .c "Refused") ///
(6 = .d "None of the strata") ///
(5 = 5 "Upper class") ///
(4 = 4 "Upper middle class") ///
(3 = 3 "Middle class") ///
(2 = 2 "Working class") ///
(1 = 1 "Lower class") ///
, gen(subjclass)
qui tab subjclass, gen(subjective)
// Western Germany only
generate east = (ost_west == 2)
drop if east
// Collapse data by year
collapse subjective*, by(year)
generate lower = subjective1 * 100
generate working = lower + (subjective2 * 100)
generate middle = working + (subjective3 * 100)
generate uppermiddle = middle + (subjective4 * 100)
generate upper = uppermiddle + (subjective5 * 100)
twoway (area upper year) ///
(area uppermiddle year) ///
(area middle year) ///
(area working year) ///
(area lower year) ///
, xlabel(1980 (5) 2010 2014) xmtick(1980 (1) 2014) ///
ylabel(0 (10) 100) ymtick(0 (5) 100) ///
xtitle("") ytitle(%) ///
legend(order(1 "Upper class" ///
2 "Upper middle class" ///
3 "Middle class" ///
4 "Working class" ///
5 "Lower class") ///
title("Subjective social class", size(*.8)) pos(2)) ///
note(" " "{it:Source:} German General Social Survey (Allbus), doi: 10.4232/1.12439. {it:Note:} Western Germany only.", span)
Labels:
Allbus,
collapse,
Random graphs,
twoway area
May 24, 2016
Random graphs (84): Line plot
unzipfile ZA4582_v1-0-0.dta.zip
use ZA4582_v1-0-0.dta, clear
recode v126 (0 = .a "Not asked") ///
(8 = .b "Don't know") ///
(9 = .c "No answer") ///
(1 = 3 "Completely agree") ///
(2 = 2 "Mostly agree") ///
(3 = 1 "Mostly disagree") ///
(4 = 0 "Completely disagree") ///
, gen(goodlife)
recode goodlife (3 = 100) (2 1 0 = 0), gen(completelygood)
generate east = (ost_west == 2)
collapse completelygood, by(year east)
twoway (scatter completelygood year if east == 1, connect(L)) ///
(scatter completelygood year if east == 0, connect(L)) ///
, legend(order(2 "Western Germany" 1 "Eastern Germany") pos(7) ring(0)) ///
title(`" 'All in all, one can live very well in a country like Germany' "') ///
ytitle("% completely agree") xlabel(1985 (5) 2010 2014) ///
xmtick(1984 (1) 2014) xtitle("") ylabel(0 (10) 60)
erase ZA4582_v1-0-0.dta
Labels:
Allbus,
collapse,
Random graphs,
twoway scatter
May 4, 2016
Random graphs (80): Line plots using the -by- option
unzipfile output961465243413697143.zip, replace
use ESS1-6e01_1_F1.dta, clear
// Label waves
label define essround 1 "2002" 2 "2004" 3 "2006" 4 "2008" 5 "2010" 6 "2012"
label val essround essround
// Keep only countries that contribute six observations
egen pickone = tag(cntry essround)
tab cntry essround if pickone // Look at no. of waves per country
egen numrounds = total(pickone), by(cntry) // Calculate no. of waves per country
keep if numrounds == 6
// Identify migrants
generate migrant = 1 if (brncntr == 2) & !missing(brncntr)
replace migrant = 2 if (brncntr == 1 & (facntr == 2 | mocntr == 2)) & !missing(brncntr, facntr, mocntr)
replace migrant = 0 if (brncntr == 1 & facntr == 1 & mocntr == 1) & !missing(brncntr, facntr, mocntr)
label define migrant 0 "Native" 1 "First-generation migrant" 2 "Second-generation migrant"
label value migrant migrant
// Generate country identifier
kountry cntry, from(iso2c)
rename NAMES_STD country
replace country = "Slovenia" if country == "si"
// By country, year, and migrant status
collapse (mean) imbgeco imueclt imwbcnt [pweight = dweight], by(country essround migrant)
drop if migrant == .
sort country migrant essround
twoway (connected imbgeco essround if migrant == 0, ///
by(country, note(" " "{it:Source:} European Social Survey, rounds 1{c 150}6, weighted data", span size(*.8)))) ///
(connected imbgeco essround if migrant == 1) ///
(connected imbgeco essround if migrant == 2) ///
, xlabel(1/6, val ang(v)) ytitle("Immigration good for economy") ysize(8) xtitle("") name(imbgecocym, replace) ///
legend(order(1 "Natives" ///
2 "First-gen." ///
3 "Second-gen.") ring(0) row(1))
Labels:
collapse,
egen,
European Social Survey,
kountry,
Random graphs,
twoway connected,
unzipfile,
weight
Apr 26, 2016
Random graphs (75): Line plots
use essround cntry netuse dweight using ESS1-6e01_0_F1.dta, clear
// Drop parts of data and label wave identifier
drop if essround == 6 // Doesn't have internet use variable
drop if inlist(cntry, "IS", "LT") // drop countries with only one measurement
label define essround 1 "2002" 2 "2004" 3 "2006" 4 "2008" 5 "2010"
label val essround essround
// Generate variable of interest
generate dailyuser = (netuse == 7) if !missing(netuse)
// Generate values by country and round
collapse (mean) dailyuser [pweight = dweight], by(cntry essround)
replace dailyuser = dailyuser * 100
// Generate country identifier
kountry cntry, from(iso2c)
rename NAMES_STD country
// Plot
twoway (connected dailyuser essround, ///
by(country, note(" " "{it:Source:} European Social Survey, rounds 1{c 150}5, weighted data", span size(*.8)) ///
col(3))), xlabel(, val) ytitle("% daily internet users") ysize(8) xtitle("")
Labels:
collapse,
European Social Survey,
kountry,
Random graphs,
twoway connected,
weight
Apr 25, 2016
Random graphs (74): Arrow plot
use 7363_F1.dta, clear
// Prepare wave variable
label define wavex 1 "1991" 2 "1995" 3 "2000" 4 "2005" 5 "2010"
label val wave wavex
// Using the internet
fre y10_q_16
tab y10_q_16 wave
keep if wave > 3 // Drop waves where variable is missing
// Create variable of interest
generate nointernetuse = .
replace nointernetuse = (y10_q_16 == 7) if !missing(y10_q_16)
// Collapse data
collapse (mean) nointernetuse, by(countid wave)
replace nointernetuse = nointernetuse * 100
reshape wide nointernetuse, i(countid) j(wave)
// Sort variable labels
egen order_ = rank(-nointernetuse5), unique
labmask order_, val(countid) decode
label define order_ 8 "Macedonia", modify
twoway (pcarrow nointernetuse4 order_ nointernetuse5 order_, horizontal) ///
(scatter order_ nointernetuse5 if missing(nointernetuse4)) ///
, ylabel(1/34, val) legend(order(1 "Decrease 2005 to 2010" ///
2 "No data for 2005") pos(7) ring(0) size(*.8)) ///
ytitle("") ysize(8) xscale(alt) xtitle("% of labor force" ///
"never using internet/email" ///
"for professional reasons") ///
xlabel(10 (10) 80, grid) ///
note(" " "{it:Source:} European Working Conditions Survey 2005 and 2010", span)
Mar 11, 2016
Random graphs (64): Line plots
label define wavex 1 "1991" 2 "1995" 3 "2000" 4 "2005" 5 "2010"
label val wave wavex
// Working to tight deadlines
fre y10_q4_2
generate tight = .
replace tight = 1 if y10_q4_2 == 1 | y10_q4_2 == 2
replace tight = 0 if y10_q4_2 == 3 | y10_q4_2 == 4 | y10_q4_2 == 5 | y10_q4_2 == 6 | y10_q4_2 == 7
preserve
collapse (mean) tight, by(countid wave)
replace tight = tight * 100
twoway connected tight wave, ///
by(countid, note("") title("Working to tight deadlines")) ///
ytitle("% (Almost) all of the time") ///
xtitle("") xlabel(, val) name(deadlines, replace)
restore
// Time to get job done
fre y10_q_27
generate notenoughtime = .
replace notenoughtime = 1 if y10_q_27 == 1
replace notenoughtime = 0 if y10_q_27 == 2
preserve
collapse (mean) notenoughtime, by(countid wave)
replace notenoughtime = notenoughtime * 100
twoway connected notenoughtime wave, ///
by(countid, note("{it:Source:} European Working Conditions Survey 1991{c 150}2010", span) ///
title("Not enough time to get job done")) ///
ytitle("% Yes") xtitle("") xlabel(, val) name(notenoughtime, replace)
restore
graph combine deadlines notenoughtime, col(1) ysize(10)
Random graphs (63): Area plots
generate home = .
replace home = 1 if homewk == 1 | homewk == 2
replace home = 0 if homewk == 3
generate usually = .
replace usually = 1 if homewk == 1
replace usually = 0 if homewk == 2 | homewk == 3
generate sometimes = .
replace sometimes = 1 if homewk == 2
replace sometimes = 0 if homewk == 1 | homewk == 3
collapse (mean) home usually sometimes, by(country refyear)
replace home = home * 100
replace usually = usually * 100
replace sometimes = sometimes * 100
drop if country == 14 & refyear < 2006
replace sometimes = sometimes + usually
twoway (area sometimes refyear, by(country, note("{it:Source:} EU Labor Force Survey 1998{c 150}2013, HR 2004/5 removed", span))) ///
(area usually refyear, by(country)), ///
ytitle("% of labor force working from home") ///
xlabel(1998 2000 2005 2010 2013, ang(h) alternate) xtitle("") ///
legend(order(2 "% usually" 1 "% sometimes") row(1) pos(9)) ///
name(graph, replace)
Labels:
collapse,
EU Labor Force Survey,
Random graphs,
twoway area
Jan 8, 2015
Random graphs (42): Stacked bar graph
use "ESS3e03_5.dta", clear
// Drop two remote countries
drop if cntry == "UA"
drop if cntry == "RU"
// Prepare variables of interest
// Country variable
encode(cntry), gen(country)
label define country 12 "UK", modify
// Keep only respondents asked about women (split ballot)
keep if icsbfm == 1
/// Question about values
recode aftjbyc (1 2 = 1 "(Strongly) disapprove") ///
(3 = 2 "Neutral") ///
(4 5 = 3 "(Strongly) approve") ///
(7/9 = .a "Missing/NA") ///
, gen(value) label(value)
quietly tab value, gen(val)
ren val1 disapprove
ren val2 neutral
ren val3 approve
// Sex
generate female = (gndr == 2) if gndr != .a
drop if female == .
// Calculate average scores across all countries by gender
preserve
collapse (mean) disapprove neutral approve [pweight = dweight], by(female)
gen country = 50 // Assign some value to sample average
tempfile euaverage
save `euaverage', replace
restore
// Calculate average scores for each country by gender
collapse (mean) disapprove neutral approve [pweight = dweight], by(country female)
// Add average score
append using `euaverage'
label define country 50 "{bf:EU}", modify // Add bold label for sample averages
// Plot
graph bar approve neutral disapprove if female == 1 ///
, over(country, sort(approve) descending label(alternate)) stack percentages ///
title("Popular (dis)approval of a full-time" "working woman with a child under 3 years of age") ///
ytitle("% of women") yscale(range(0 100)) ylabel(0(20)100) legend(off) ///
name(women, replace)
graph bar approve neutral disapprove if female == 0 ///
, over(country, sort(approve) descending label(alternate)) stack percentages ///
ytitle("% of men") yscale(range(0 100)) ylabel(0(20)100) ///
legend(label(3 "(Strongly) disapprove") ///
label(2 "Neutral") ///
label(1 "(Strongly) approve") ///
order(1 2 3) pos(6) row(1)) ///
caption(" " ///
"{it: Source:} European Social Survey 2006/07, own calculations." ///
`"{it: Note:} "EU" refers to average for the 20 EU member states in this Figure."', ///
span size(small)) ///
name(men, replace)
graph combine women men, col(1) ysize(8)
Dec 17, 2014
Random graphs (39): Plotting on a log axis
Rather than looking at a variable in absolute terms, namely GDP per capita in the upper panel of the Figure, it is also sometimes helpful to look at it in terms of percentage increases, as in the lower panel. Equal distances on the x-axis refer to equal percentage increases in GDP per capita. Four equidistant points on the x-axis are labeled, each indicating a fourfold increase in GDP.
use wvs2005_v20090901a.dta, clear
// Country variable
// 1) Turn into string
decode v2, gen(ctry)
// 2) Abbreviate
kountry ctry, from(other) stuck marker
ren _ISO3N_ cntry
kountry cntry, from(iso3n) to(iso2c)
ren _ISO2C_ country
// Generate outcome: % in good health
generate goodhealth = 100 if v11 <= 2
replace goodhealth = 0 if v11 > 2
replace goodhealth = . if v11 == .
// Collapse data set
collapse (mean) goodhealth [pw = v259], by(country)
// Generate year variable
gen year = 2006
// Preserve collapsed data set
preserve
// Get GDP from World Bank data base
wbopendata, language(en - English) country() topics() indicator(NY.GDP.PCAP.PP.CD) clear long
// Fix obtained data set
ren ny_gdp_pcap_pp_cd gdp
ren iso2code country
keep if year == 2006
keep gdp country
drop if country == ""
// Save obtained GDP data
tempfile gdp
save `gdp'
// Restore
restore
// Merge GDP with collapsed data set
merge m:1 country using `gdp'
keep if _merge == 3
drop _merge
// Create labels with thousand separator
label define gdp 20000 "20,000" ///
40000 "40,000" ///
60000 "60,000"
label val gdp gdp
// Plot on unlogged axis
twoway (scatter goodhealth gdp, mlabel(country) mlabpos(0) msymbol(none)) ///
(lfit goodhealth gdp) ///
, legend(off) xtitle("GDP per capita, 2006, PPP in current international $") ///
ytitle("% in good health") ///
xlabel(0(20000)60000, valuelabels) ///
name(unlogged, replace)
// Generate logged variable
gen loggdp = log(gdp) * 1000 // Multiply by 1,000 because only integers can be labeled
// Generate numbers for labeling
// Round them to three decimal digits, then multiply by 1,000 to get integers
local log1 = round(log(1000), .001) * 1000
local log2 = round(log(1000 * 4), .001) * 1000
local log3 = round(log(1000 * 4 * 4), .001) * 1000
local log4 = round(log(1000 * 4 * 4 * 4), .001) *1000
*di `log1' _skip(2) `log2' _skip(2) `log3' _skip(2) `log4'
// Create labels for numbers to be labeled
label define loggdp `log1' "1,000" ///
`log2' "4,000" ///
`log3' "16,000" ///
`log4' "64,000"
label value loggdp loggdp
// Plot on log axis
twoway (scatter goodhealth loggdp, mlabel(country) mlabpos(0) msymbol(none)) ///
(lfit goodhealth loggdp) ///
, legend(off) xtitle("GDP per capita, 2006, PPP in current international $") ///
ytitle("% in good health") ///
xlabel(`log1' `log2' `log3' `log4', valuelabels) ///
name(logged, replace)
// Combine plots
graph combine unlogged logged, col(1) ysize(8)
Labels:
_skip(#),
collapse,
decode,
graph combine,
kountry,
log(),
mlabel,
preserve,
Random graphs,
round(),
tempfile,
twoway lfit,
twoway scatter,
wbopendata,
World Values Survey,
ysize
Jul 2, 2014
Random graphs (24): Small-multiples and overlayed line plots
clear
// SG.GEN.PARL.ZS - Proportion of seats held by women in national parliaments (%)
wbopendata, indicator(SG.GEN.PARL.ZS) clear long
// Keep European countries
keep if regioncode == "ECS" // "Europe & Central Asia (all income levels)"
// Keep EU-28
keep if inlist(iso2code, "AT", "BE", "BG", "CY", "CZ", "DE", "DK", "EE", "ES") | ///
inlist(iso2code, "FI", "FR", "GB", "GR", "HR", "HU", "IE", "IT", "LI") | ///
inlist(iso2code, "LT", "LU", "LV", "NL", "PL", "PT", "RO", "SE", "SI") | ///
inlist(iso2code, "SK") // EU-28
// Identify and rename salient variables
ren sg_gen_parl_zs women
label var women "% of national parliament seats held by women"
ren iso2code cntry
drop countrycode region regioncode
// Reshape to drop empty observations
reshape wide women, i(cntry) j(year)
dropmiss women1960-women2014, force
reshape long
// Calculate EU-28 mean
preserve
collapse (mean) women, by(year)
gen cntry = "{bf:EU-28}"
tempfile eu28
save `eu28', replace
restore
append using `eu28'
// Plot small-multiples figure
twoway scatter women year ///
, by(cntry ///
, note(" ") ///
caption("{it:Source:} World Development Indicators, date of extraction: 2015-05-25", span size(small))) ///
cmissing(no) ///
connect(l) ///
msymbol(o) ///
xtitle("") xlabel(1990 1997 2000 2005 2010 2014, ang(45)) ///
ylabel(0 (10) 50) ///
name(small_multiples, replace)
// Plot overlayed figure
encode cntry, gen(country) // No strings for -xtline-
xtset country year, yearly // Declare panel
xtline women if cntry != "{bf:EU-28}" ///
, overlay ///
xlabel(1990 1997 2000 2005 2010 2014) xtitle("Year") ///
plot1opts(lpattern(dash)) plot2opts(lpattern(dash)) ///
plot3opts(lpattern(dash)) plot4opts(lpattern(dash)) ///
plot5opts(lpattern(dash)) plot6opts(lpattern(dash)) ///
plot7opts(lpattern(dash)) plot8opts(lpattern(dash)) ///
plot9opts(lpattern(dash)) plot10opts(lpattern(dash)) ///
plot11opts(lpattern(dash)) plot12opts(lpattern(dash)) ///
plot13opts(lpattern(dash)) plot14opts(lpattern(dash)) ///
plot15opts(lpattern(dash)) plot16opts(lpattern(dash)) ///
plot17opts(lpattern(dash)) plot18opts(lpattern(dash)) ///
plot19opts(lpattern(dash)) plot20opts(lpattern(dash)) ///
plot21opts(lpattern(dash)) plot22opts(lpattern(dash)) ///
plot23opts(lpattern(dash)) plot24opts(lpattern(dash)) ///
plot25opts(lpattern(dash)) plot26opts(lpattern(dash)) ///
plot27opts(lpattern(dash)) plot28opts(lpattern(dash)) ///
name(overlay, replace) ///
addplot(line women year if cntry == "{bf:EU-28}", ///
lwidth(thick) lpattern(solid) sort(cntry year)) ///
legend(order(29 "EU-28 (unweighted average)") pos(6) ring(0)) ///
caption("{it:Source:} World Development Indicators, date of extraction: 2015-05-25", span size(small)) ///
ytitle("% of national parliament seats" "held by women, EU-28 countries")
Labels:
append,
collapse,
dropmiss,
Random graphs,
reshape,
tempfile,
twoway scatter,
wbopendata,
xtline,
xtset
Jun 6, 2014
Random graphs (25): Line plot
use country refyear coeff age wstator hwactual exist2j hwactua2 if refyear == 2011 using eulfs.dta, clear
// Handle missing values:
replace hwactual = 0 if age < 15
replace hwactual = 0 if inlist(wstator, 3, 4, 5)
replace hwactua2 = 0 if inlist(exist2j, 1, .)
replace hwactua2 = 0 if age < 15
// Sum up working hours from first and second job
gen hours = hwactual + hwactua2
// Drop unnecessary variables
drop refyear wstator exist2j
// Collapse to calculate means
collapse (mean) hours [pweight = coeff], by(country age)
// Label variables
label define age2 02 "0{c 150}4" 07 "5{c 150}9" ///
12 "10{c 150}14" 17 "15{c 150}19" ///
22 "20{c 150}24" 27 "25{c 150}29" ///
32 "30{c 150}34" 37 "35{c 150}39" ///
42 "40{c 150}44" 47 "45{c 150}49" ///
52 "50{c 150}54" 57 "55{c 150}59" ///
62 "60{c 150}64" 67 "65{c 150}69" ///
72 "70{c 150}74" 77 "75{c 150}79" ///
82 "80{c 150}84" 87 "85{c 150}89" ///
92 "90{c 150}94" 97 "95+", modify
label value age age2
label define country 1 "AT" 2 "BE" 3 "BG" 4 "CH" 5 "CY" ///
6 "CZ" 7 "DE" 8 "DK" 9 "EE" 10 "ES" ///
11 "FI" 12 "FR" 13 "GR" 14 "HU" 15 "IE" ///
16 "IS" 17 "IT" 18 "LT" 19 "LU" 20 "LV" ///
21 "MT" 22 "NL" 23 "NO" 24 "PL" 25 "PT" ///
26 "RO" 27 "SE" 28 "SI" 29 "SK" 30 "UK" ///
, modify
label value country country
// Plot
twoway (line hours age if country == 30) ///
(line hours age if country == 7) ///
(line hours age if country == 22) ///
(line hours age if country == 10) ///
, caption("{it:Source:} EU Labor Force Survey 2011, own calculations", span) ///
ytitle("Hours worked per week per capita") xtitle("Age group") ///
xlabel( 2 (5) 97, val ang(45)) ylabel(0 (5) 30) ///
legend(label(1 "United Kingdom") ///
label(2 "Germany") ///
label(3 "The Netherlands") ///
label(4 "Spain") ring(0) pos(1))
Labels:
collapse,
EU Labor Force Survey,
inlist(),
twoway line
Subscribe to:
Posts (Atom)





















