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
------------------------------------------------------------------------------
l e(b) mat
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]
:
"Der Koeffizient für F200 ist " _b[F200]
dis "Der Standardfehler des Koeffizienten für F200 ist " _se[F200] dis
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:
_cons] + 20 *_b[F200]
dis _b[at(F200 = 20) margins,
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
diff su
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
r(table)'
mat C = l C mat
C[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:
rownumb(C,"F200"),1...]
mat C1 = C[l C1 mat
C1[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
l r(table)
mat "Der Koeffizient für S1 = weiblich ist " _b[2.S1] dis
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:
r(table)' // transponieren:
mat D = l D mat
eform
b se t pvalue ll ul df crit
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 0
3.4 Als Datensatz ablegen:
Auch hier können wir dann mit xsvmat
die Matrix in einen Datensatz umformatieren:
drop regres1
cap frame rownames(coef) frame(regres1)
xsvmat D, names(col)
frame change regres1
list, noobs clean
eform
coef b se t pvalue ll ul df crit
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
"`e(cmdline)'" dis
regress F518_SUF i.S1 F200
Diese Information können wir mit in den Ergebnis-frame
nehmen. global
s bleiben nehmen in der Session erhalten, auch wenn wir zwischen frame
s wechseln:
gen mo = "`e(cmdline)'"
list, noobs clean
eform mo
coef b se t pvalue ll ul df crit regress F518_SUF i.S1 F200
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 _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:
if smpl == 0 mdesc F518_SUF S1 F200
quietly{
use "./data/BIBBBAuA_2018_suf1.0_clean.dta", replace
reg F518_SUF i.S1 F200
gen smpl = e(sample)
}if smpl == 0 mdesc F518_SUF S1 F200
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.Migqui regress F518_SUF ${mod1}
gen smpl2 = e(sample)
local len2: word count ${mod1}
forvalues i = 1(1)`len2' {
word: word `i' of ${mod1}
loc "Modell Nr" `i' ": mit `word'"
dis `x' `word'
loc x qui reg F518_SUF `x' if smpl2 == 1
est store m`i'
}
est dir
m*, b se // ssc install esttab esttab
Modell 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ürmig01
undzpalter
mit einer Aussagekräftigen Nachricht ausgibt - Wie würde das als Schleife über die Koeffizienten aussehen?
- Extrahieren Sie die Regressionstabelle als
matrix
und legen sie diese alsframe
ab. - 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.S1
3.8 Anhang
3.8.1 statsby
statsby _b _se, by(Bula) noisily: ///
regress F518_SUF c.F200##c.F200 i.m1202 i.S1
3.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
// uv rücksetzen (zur sicherheit)
loc uv foreach v of local predictors {
local uv `uv' `v'
qui regress F518_SUF `uv'
r(table)' // reg-tabelle transponieren & speichern
mat D = rownumb(D,"2.S1"),1...] // Koeffizient für S1=2 behalten
mat D2 = D[
if (`r' == 1) mat R = D2 // im ersten Durchlauf R erstellen
if (`r' != 1) mat R = R\D2 // danach: D2 an R anfügen
r // Zähler + 1
loc ++
}l R mat
R[6,9]eform
b se t pvalue ll ul df crit
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 0
Wie 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
// uv rücksetzen (zur sicherheit)
loc uv foreach v of local predictors {
local uv `uv' `v'
qui regress F518_SUF `uv'
r(table)' // reg-tabelle transponieren & speichern
mat D = rownumb(D,"2.S1"),1...] // Koeffizient für S1=2 behalten
mat D2 = D[
`r'
mat M = mod
mat colname M =
if (`r' == 1) mat R = D2 , M // ,r -> zähler an Koeffizientzeile anfügen
if (`r' != 1) mat R = R\(D2 , M)
`r' = "`e(cmdline)'"
glo cmdr // Zähler + 1
loc ++
}l R mat
R[6,10]eform mod
b se t pvalue ll ul df crit
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 6
Diese matrix
R schicken wir jetzt in einen frame
:
drop rmods
cap frame rownames(coef) frame(rmods)
xsvmat R, names(col)
frame change rmods
list, noobs clean
eform mod
coef b se t pvalue ll ul df crit
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*"
l allglo
mac allglo: cmd6 cmd5 cmd4 cmd3 cmd2 cmd1
l cmd1
mac regress F518_SUF i.S1 cmd1:
Jetzt 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 {
`m' "${cmd`m'}", modify // value label verändern
lab def mod_lab
}mod mod_lab
lab val
list, noobs clean
eform mod
coef b se t pvalue ll ul df crit regress F518_SUF i.S1
2.S1 -1431.809 53.63 -26.69792 0 -1536.93 -1326.689 16633 1.960107 0 regress F518_SUF i.S1 c.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 c.F200 c.F200#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 i.m1202
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 zpalter
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 c.zpalter#c.zpalter 2.S1 -717.3357 54.06105 -13.26899 0 -823.3022 -611.3691 14551 1.960127 0
Daraus können wir beispielsweise einen Koeffizientenplot erstellen:
graph twoway ///
mod,horizontal lcolor("57 65 101") ) /// Konfidenzintervalle
(rcap ll ul scatter mod b, mcolor("177 147 74") ) , /// Punktschätzer
(white)) /// Hintergundfarbe (außerhalb des eigentlichen Plots)
graphregion(fcolor(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.