3 Regressionsergebnisse weiterverarbeiten
3.1 e() und r() der Regressionsergebnisse
Die Koeffizienten und Standardfehler des letzten Modells werden in e() gespeichert:
reg F518_SUF F200 Source | SS df MS Number of obs = 14,659
-------------+---------------------------------- F(1, 14657) = 1370.76
Model | 1.3122e+10 1 1.3122e+10 Prob > F = 0.0000
Residual | 1.4031e+11 14,657 9572601.57 R-squared = 0.0855
-------------+---------------------------------- Adj R-squared = 0.0855
Total | 1.5343e+11 14,658 10467142.3 Root MSE = 3094
------------------------------------------------------------------------------
F518_SUF | Coef. Std. Err. t P>|t| [95% Conf. Interval]
-------------+----------------------------------------------------------------
F200 | 109.4473 2.956134 37.02 0.000 103.6529 115.2417
_cons | -344.1221 104.2802 -3.30 0.001 -548.5245 -139.7197
------------------------------------------------------------------------------
mat l e(b)e(b)[1,2]
F200 _cons
y1 109.44727 -344.12212
3.1.1 Koeffizienten mit _b / _se aufrufen
Allerdings gibt es noch eine Abkürzung mit _b[varname] bzw. _se[varname]:
dis "Der Koeffizient für F200 ist " _b[F200]
dis "Der Standardfehler des Koeffizienten für F200 ist " _se[F200]Der Koeffizient für F200 ist 109.44727
Der Standardfehler des Koeffizienten für F200 ist 2.9561335
Wir können so auch vorhergesagte Werte berechnen - entweder für spezifische Werte:
dis _b[_cons] + 20 *_b[F200]
margins, at(F200 = 20)1844.8234
Adjusted predictions Number of obs = 14,659
Model VCE : OLS
Expression : Linear prediction, predict()
------------------------------------------------------------------------------
| Delta-method
| Margin Std. Err. t P>|t| [95% Conf. Interval]
-------------+----------------------------------------------------------------
_cons | 1844.823 49.14441 37.54 0.000 1748.494 1941.153
------------------------------------------------------------------------------
…oder für alle Beobachtungen:
gen pred_manual = _b[_cons] + F200 *_b[F200]
predict pred_auto, xb
gen diff= pred_manual - pred_auto
su diff Variable | Obs Mean Std. Dev. Min Max
-------------+---------------------------------------------------------
diff | 17,376 0 0 0 0
3.1.2 Komplette Regressionstabelle
Die vollständige Regressionstabelle ist aber eine r-Class matrix:
reg F518_SUF F200
matlist r(table) r(table)[9,2]
F200 _cons
b 109.44727 -344.12212
se 2.9561335 104.28024
t 37.023793 -3.2999743
pvalue 6.36e-287 .00096924
ll 103.65288 -548.52452
ul 115.24167 -139.71973
df 14657 14657
crit 1.9601259 1.9601259
eform 0 0
3.2 Regressionstabellen als matrix speichern und anpassen
Mit ' können wir die Regressionstabelle transponieren:
reg F518_SUF F200
mat C = r(table)'
mat l CC[2,9]
b se t pvalue ll ul
F200 109.44727 2.9561335 37.023793 6.36e-287 103.65288 115.24167
_cons -344.12212 104.28024 -3.2999743 .00096924 -548.52452 -139.71973
df crit eform
F200 14657 1.9601259 0
_cons 14657 1.9601259 0
rownumb hilft, einen Koeffizienten zu suchen:
mat C1 = C[rownumb(C,"F200"),1...]
mat l C1C1[1,9]
b se t pvalue ll ul
F200 109.44727 2.9561335 37.023793 6.36e-287 103.65288 115.24167
df crit eform
F200 14657 1.9601259 0
3.3 kategoriale UV
Der Koeffizientenname ist etwas komplizierterer Name bei kat. UVs:
reg F518_SUF i.S1 F200
ereturn list
mat l r(table)
dis "Der Koeffizient für S1 = weiblich ist " _b[2.S1]r(table)[9,4]
1b. 2.
S1 S1 F200 _cons
b 0 -628.91281 95.08006 464.42184
se . 55.392637 3.2038116 125.90363
t . -11.353726 29.67717 3.688709
pvalue . 9.461e-30 5.23e-188 .00022621
ll . -737.48935 88.800186 217.63489
ul . -520.33627 101.35993 711.2088
df 14656 14656 14656 14656
crit 1.9601259 1.9601259 1.9601259 1.9601259
eform 0 0 0 0
Der Koeffizient für S1 = weiblich ist -628.91281
Dies müssen wir auch bei der Suche nach einem Koeffizienten berücksichtigen:
mat D = r(table)' // transponieren:
mat l D b se t pvalue ll ul df crit eform
1b.S1 0 . . . . . 14656 1.9601259 0
2.S1 -628.91281 55.392637 -11.353726 9.461e-30 -737.48935 -520.33627 14656 1.9601259 0
F200 95.08006 3.2038116 29.67717 5.23e-188 88.800186 101.35993 14656 1.9601259 0
_cons 464.42184 125.90363 3.688709 .00022621 217.63489 711.2088 14656 1.9601259 03.4 Als Datensatz ablegen:
Auch hier können wir dann mit xsvmat die Matrix in einen Datensatz umformatieren:
cap frame drop regres1
xsvmat D, names(col) rownames(coef) frame(regres1)
frame change regres1
list, noobs clean coef b se t pvalue ll ul df crit eform
1b.S1 0 . . . . . 14656 1.960126 0
2.S1 -628.9128 55.39264 -11.35373 9.46e-30 -737.4893 -520.3362 14656 1.960126 0
F200 95.08006 3.203812 29.67717 0 88.80019 101.3599 14656 1.960126 0
_cons 464.4218 125.9036 3.688709 .0002262 217.6349 711.2088 14656 1.960126 0 3.5 weitere Infos aus e()
In ereturn list oben sehen wir, dass e(cmdline) den reg-Befehl enthält:
reg F518_SUF i.S1 F200
dis "`e(cmdline)'"regress F518_SUF i.S1 F200
Diese Information können wir mit in den Ergebnis-frame nehmen. globals bleiben nehmen in der Session erhalten, auch wenn wir zwischen frames wechseln:
gen mo = "`e(cmdline)'"
list, noobs clean coef b se t pvalue ll ul df crit eform mo
1b.S1 0 . . . . . 14656 1.960126 0 regress F518_SUF i.S1 F200
2.S1 -628.9128 55.39264 -11.35373 9.46e-30 -737.4893 -520.3362 14656 1.960126 0 regress F518_SUF i.S1 F200
F200 95.08006 3.203812 29.67717 0 88.80019 101.3599 14656 1.960126 0 regress F518_SUF i.S1 F200
_cons 464.4218 125.9036 3.688709 .0002262 217.6349 711.2088 14656 1.960126 0 regress F518_SUF i.S1 F200 Diese Beschreibung ist natürlich alles andere als ideal. Im nächsten Kapitel werden wir einige Möglichkeiten kennenlernen, da etwas zu ändern.
3.5.1 e(sample)
e(sample) ist eine e()-Class Funktion, welche die in einem Modell berücksichtigten Fälle zu markieren:
quietly reg F518_SUF i.S1 F200
gen smpl = e(sample)
tab sampl smpl | Freq. Percent Cum.
------------+-----------------------------------
0 | 5,353 26.75 26.75
1 | 14,659 73.25 100.00
------------+-----------------------------------
Total | 20,012 100.00
So können wir bspw. sehen, wo die Missings liegen:
mdesc F518_SUF S1 F200 if smpl == 0quietly{
use "./data/BIBBBAuA_2018_suf1.0_clean.dta", replace
reg F518_SUF i.S1 F200
gen smpl = e(sample)
}
mdesc F518_SUF S1 F200 if smpl == 0 Variable | Missing Total Percent Missing
----------------+-----------------------------------------------
F518_SUF | 3,377 5,353 63.09
S1 | 0 5,353 0.00
F200 | 2,636 5,353 49.24
----------------+-----------------------------------------------
3.6 reg schrittweise aufbauen
glo mod1 i.S1 az i.m1202 zpalter i.Mig
qui regress F518_SUF ${mod1}
gen smpl2 = e(sample)
local len2: word count ${mod1}
forvalues i = 1(1)`len2' {
loc word: word `i' of ${mod1}
dis "Modell Nr" `i' ": mit `word'"
loc x `x' `word'
qui reg F518_SUF `x' if smpl2 == 1
est store m`i'
}
est dir
esttab m*, b se // ssc install esttabModell Nr1: mit i.S1
Modell Nr2: mit az
Modell Nr3: mit i.m1202
Modell Nr4: mit zpalter
Modell Nr5: mit i.Mig
----------------------------------------------------------------
name | command depvar npar title
-------------+--------------------------------------------------
m1 | regress F518_SUF 3 Linear regression
m2 | regress F518_SUF 4 Linear regression
m3 | regress F518_SUF 8 Linear regression
m4 | regress F518_SUF 9 Linear regression
m5 | regress F518_SUF 12 Linear regression
----------------------------------------------------------------
--------------------------------------------------------------------------------------------
(1) (2) (3) (4) (5)
F518_SUF F518_SUF F518_SUF F518_SUF F518_SUF
--------------------------------------------------------------------------------------------
1.S1 0 0 0 0 0
(.) (.) (.) (.) (.)
2.S1 -1434.1*** -683.3*** -725.7*** -755.7*** -756.4***
(53.94) (55.19) (53.65) (53.50) (53.51)
az 91.74*** 83.46*** 84.05*** 83.99***
(2.376) (2.323) (2.315) (2.316)
1.m1202 0 0 0
(.) (.) (.)
2.m1202 384.1*** 261.9* 250.9*
(114.5) (114.6) (115.2)
3.m1202 898.1*** 737.2*** 724.5***
(137.7) (137.9) (138.5)
4.m1202 2074.7*** 1933.3*** 1924.7***
(116.0) (116.2) (116.7)
zpalter 25.41*** 25.27***
(2.200) (2.210)
0.Mig 0
(.)
1.Mig 10.65
(93.55)
2.Mig -175.8
(146.9)
_cons 4236.3*** 359.5*** -376.7** -1447.4*** -1423.9***
(37.72) (106.7) (141.0) (168.3) (171.2)
--------------------------------------------------------------------------------------------
N 16518 16518 16518 16518 16518
--------------------------------------------------------------------------------------------
Standard errors in parentheses
* p<0.05, ** p<0.01, *** p<0.001
3.7 Übungen
3.7.1 Übung
Erstellen Sie folgendes Regressionsmodell:
reg az i.mig01 zpalter(In mig01 steht dann 0 für keinen Migrationshintergrund und 1 für Migrationshintergrund - siehe auch 01_init.do)
- Erstellen Sie jeweils einen
display-Befehl, der den Koeffizienten und Standardfehler fürmig01undzpaltermit einer Aussagekräftigen Nachricht ausgibt - Wie würde das als Schleife über die Koeffizienten aussehen?
- Extrahieren Sie die Regressionstabelle als
matrixund legen sie diese alsframeab. - Erstellen Sie zusätzlich eine Spalte mit dem Regressionsbefehl.
3.7.2 Übung
Bauen Sie folgendes Modell Schritt für Schritt auf und lassen Sie sich die Tabelle mit esttab ausgeben:
reg az i.S1 zpalter c.zpalter#c.zpalter i.gkpol i.F1604 i.F1604##i.S13.8 Anhang
3.8.1 statsby
statsby _b _se, by(Bula) noisily: ///
regress F518_SUF c.F200##c.F200 i.m1202 i.S13.8.2 reg-Ergebnisse für Modelle sammeln: Schleife
Wir können mit den matrix-Befehlen auch eine Schleife bauen, welche eine Reihe an Regressionsmodellen schätzt und bei jedem Durchlauf einen zusätzlichen Term hinzunimmt. Wir interessieren uns aber nur, dafür wie sich der Koeffizient für das Geschlecht (S1 == 2) entwickelt mit jedem neuen Modell. Mit den matrix-Befehlen können wir dieser herausfiltern.
local predictors i.S1 c.F200 c.F200#c.F200 i.m1202 zpalter c.zpalter#c.zpalter // UV-Liste
local r = 1 // Zähler
loc uv // uv rücksetzen (zur sicherheit)
foreach v of local predictors {
local uv `uv' `v'
qui regress F518_SUF `uv'
mat D = r(table)' // reg-tabelle transponieren & speichern
mat D2 = D[rownumb(D,"2.S1"),1...] // Koeffizient für S1=2 behalten
if (`r' == 1) mat R = D2 // im ersten Durchlauf R erstellen
if (`r' != 1) mat R = R\D2 // danach: D2 an R anfügen
loc ++r // Zähler + 1
}
mat l RR[6,9]
b se t pvalue ll ul df crit eform
2.S1 -1431.8093 53.630001 -26.697917 8.52e-154 -1536.9298 -1326.6888 16633 1.9601066 0
2.S1 -628.91281 55.392637 -11.353726 9.461e-30 -737.48935 -520.33627 14656 1.9601259 0
2.S1 -661.6656 55.679749 -11.883416 2.034e-32 -770.80492 -552.52628 14655 1.9601259 0
2.S1 -664.94219 53.793012 -12.361126 6.336e-35 -770.38328 -559.50111 14633 1.9601261 0
2.S1 -700.71303 54.028438 -12.969337 2.975e-38 -806.61563 -594.81043 14552 1.960127 0
2.S1 -717.33567 54.061055 -13.268991 5.977e-40 -823.30221 -611.36914 14551 1.960127 0Wie wissen wir jetzt, für was kontrolliert wurde?
Wir nutzen den Zähler, um ein global mit der Zählernummer zu erstellen und eine Zeile in die matrix einzufügen:
local predictors i.S1 c.F200 c.F200#c.F200 i.m1202 zpalter c.zpalter#c.zpalter
local r = 1 // Zähler
loc uv // uv rücksetzen (zur sicherheit)
foreach v of local predictors {
local uv `uv' `v'
qui regress F518_SUF `uv'
mat D = r(table)' // reg-tabelle transponieren & speichern
mat D2 = D[rownumb(D,"2.S1"),1...] // Koeffizient für S1=2 behalten
mat M = `r'
mat colname M = mod
if (`r' == 1) mat R = D2 , M // ,r -> zähler an Koeffizientzeile anfügen
if (`r' != 1) mat R = R\(D2 , M)
glo cmd`r' = "`e(cmdline)'"
loc ++r // Zähler + 1
}
mat l RR[6,10]
b se t pvalue ll ul df crit eform mod
2.S1 -1431.8093 53.630001 -26.697917 8.52e-154 -1536.9298 -1326.6888 16633 1.9601066 0 1
2.S1 -628.91281 55.392637 -11.353726 9.461e-30 -737.48935 -520.33627 14656 1.9601259 0 2
2.S1 -661.6656 55.679749 -11.883416 2.034e-32 -770.80492 -552.52628 14655 1.9601259 0 3
2.S1 -664.94219 53.793012 -12.361126 6.336e-35 -770.38328 -559.50111 14633 1.9601261 0 4
2.S1 -700.71303 54.028438 -12.969337 2.975e-38 -806.61563 -594.81043 14552 1.960127 0 5
2.S1 -717.33567 54.061055 -13.268991 5.977e-40 -823.30221 -611.36914 14551 1.960127 0 6Diese matrix R schicken wir jetzt in einen frame:
cap frame drop rmods
xsvmat R, names(col) rownames(coef) frame(rmods)
frame change rmods
list, noobs cleancoef b se t pvalue ll ul df crit eform mod
2.S1 -1431.809 53.63 -26.69792 0 -1536.93 -1326.689 16633 1.960107 0 1
2.S1 -628.9128 55.39264 -11.35373 9.46e-30 -737.4893 -520.3362 14656 1.960126 0 2
2.S1 -661.6656 55.67975 -11.88342 2.03e-32 -770.8049 -552.5263 14655 1.960126 0 3
2.S1 -664.9422 53.79301 -12.36113 6.34e-35 -770.3833 -559.5011 14633 1.960126 0 4
2.S1 -700.713 54.02844 -12.96934 2.97e-38 -806.6156 -594.8104 14552 1.960127 0 5
2.S1 -717.3357 54.06105 -13.26899 0 -823.3022 -611.3691 14551 1.960127 0 6 Jetzt wissen zwar schon mal, aus welchem Modell der Koeffizient jeweils kommt (basierend auf mod). Eigentlich würden das aber gerne labeln. Dazu können wir jetzt auf die globals zurückgreifen - mit all globals können wir nach ihnen suchen:
global allglo: all globals "cmd*"
mac l allglo
allglo: cmd6 cmd5 cmd4 cmd3 cmd2 cmd1mac l cmd1
cmd1: regress F518_SUF i.S1Jetzt können wir mit einer Schleife die Spalte mod labeln. Mit label define .... können Wertelabels erstellt werden - mit der Option ,modify können wir das auch schrittweise verändern. Außerdem können wir einen kleinen Trick nutzen, um innerhalb der Schleife auf das global mit einer bestimmten Zahl zuzugreifen:
levelsof mod, loc(mnrs)
foreach m of local mnrs {
lab def mod_lab `m' "${cmd`m'}", modify // value label verändern
}
lab val mod mod_lab
list, noobs clean coef b se t pvalue ll ul df crit eform mod
2.S1 -1431.809 53.63 -26.69792 0 -1536.93 -1326.689 16633 1.960107 0 regress F518_SUF i.S1
2.S1 -628.9128 55.39264 -11.35373 9.46e-30 -737.4893 -520.3362 14656 1.960126 0 regress F518_SUF i.S1 c.F200
2.S1 -661.6656 55.67975 -11.88342 2.03e-32 -770.8049 -552.5263 14655 1.960126 0 regress F518_SUF i.S1 c.F200 c.F200#c.F200
2.S1 -664.9422 53.79301 -12.36113 6.34e-35 -770.3833 -559.5011 14633 1.960126 0 regress F518_SUF i.S1 c.F200 c.F200#c.F200 i.m1202
2.S1 -700.713 54.02844 -12.96934 2.97e-38 -806.6156 -594.8104 14552 1.960127 0 regress F518_SUF i.S1 c.F200 c.F200#c.F200 i.m1202 zpalter
2.S1 -717.3357 54.06105 -13.26899 0 -823.3022 -611.3691 14551 1.960127 0 regress F518_SUF i.S1 c.F200 c.F200#c.F200 i.m1202 zpalter c.zpalter#c.zpalter Daraus können wir beispielsweise einen Koeffizientenplot erstellen:
graph twoway ///
(rcap ll ul mod,horizontal lcolor("57 65 101") ) /// Konfidenzintervalle
(scatter mod b, mcolor("177 147 74") ) , /// Punktschätzer
graphregion(fcolor(white)) /// Hintergundfarbe (außerhalb des eigentlichen Plots)
ylabel(, valuelabel angle(0) labsize(tiny)) ///
legend(off) ///
xtitle("Einkommen (W) vs. Einkommen (M)") /// Achsentitel
ytitle("") ///
title("Titel") ///
subtitle("Untertitel") ///
caption("{it:Quelle: Erwerbstätigenbefragung 2018}", size(8pt) position(5) ring(5) )
Diese labels sind natürlich alles andere als ideal. Im nächsten Kapitel werden wir einige Möglichkeiten kennenlernen, da etwas zu ändern.