Spell Data SC5

Hallo,

für meine Abschlussarbeit möchte ich mir den Übergang von Studium zu Beruf anschauen. Insbesondere welche Einflussfaktoren eine Kongruenz oder Nicht-Kongruenz zwischen Studienfach und Beruf befürworten. ich habe bisher die Daten CohortProfile, Basics, pTargetCAWI, pTargetCATI gemerged und möchte nun spEMP noch hinzufügen, insbesondere die Variable ts23201_g1 Professional title (KldB 1988).
Mein bisheriger Code lautet:

use „$data/SC5_CohortProfile_D_19-0-0.dta“, clear

  • Set labels to English
    label language en
    ssc install distinct

distinct ID_t // Person Identification

sort ID_t wave

  • Merge the Basics data (m:1 because each wave in CohortProfile is linked to one Basics entry)
    merge m:1 ID_t using „$data/SC5_Basics_D_19-0-0.dta“, ///
    keepusing(t700001 tx29063 tx29064 tx29065 tx29066 tx29067 tx29068 tx29069 tx29073 tx29090 ) ///
    keep(1 3) nogen

  • Merge pTargetCAWI
    merge 1:1 ID_t wave using „$data/SC5_pTargetCAWI_D_19-0-0.dta“, ///
    keepusing(tg76001_g4 tg76001_g2) ///
    keep(1 3) nogen

merge 1:1 ID_t wave using „$data/SC5_pTargetCATI_D_19-0-0.dta“, ///
keepusing(tg02001_ha tg02001 tg02001_g1 tg04001_g3 tg04001_g4R tg04001_g5R tg04001_g6 tg04001_g2R tg04002 t531262) ///
keep(1 3) nogen

Vielen Dank für die Hilfe.
Laura

Hallo nochmal,

ich habe nun versucht meine Referenzgruppe zu bilden:
Studierende, die in einem Mint-Studienfach studieren, dort abschließen und nach ihrem Studium in eine Erwerbstätigkeit wechseln (Mint/Nicht-Mint).

Mein erster ansatz war:

** Reference group **

  • Step 1:
    use „$data/SC5_spVocTrain_D_19-0-0.dta“, clear
    keep if subspell == 0
    distinct ID_t // Person Identification: 43785 17909

  • Generate time variables
    gen startdate = ym(ts1511y, ts1511m)
    gen enddate = ym(ts1512y, ts1512m)
    format startdate enddate %tm

  • Keep only spells with valid enddates
    keep if !missing(enddate)

tempfile all_spells
save `all_spells’

  • Step 2: Identify final spell per person and get their last study field
    use `all_spells’, clear
    bysort ID_t (enddate): keep if _n == _N

  • Rename study field for clarity
    gen last_studyfield = tg24170_g2
    keep ID_t last_studyfield
    tempfile lastfield
    save `lastfield’

// STEP 3: Reload all spells and merge last study field info
use all_spells', clear merge m:1 ID_t using lastfield’, keep(match master) nogen

// STEP 4: study field =STEM
gen stem_field = .
replace stem_field = 1 if inlist(last_studyfield, 4, 8, 9)
replace stem_field = 0 if inlist(last_studyfield, 1, 2, 3, 5, 6, 7, 10)
replace stem_field = . if inlist(last_studyfield, -98, -97, -96, -95, -92, -55, -29, -28, -22, -20, .)

  • Keep only individuals whose last study field is in STEM
    keep if stem_field == 1
  • nun habe ich Schwierigkeiten die Informationen zu Profession aus spEmp zu verbinden.

Hallo Laura!

Ich habe deinen Code etwas modifiziert, kommentiert und Lösungsmöglichkeiten angegeben.
Aber wie schon in den Release Notes beschrieben steht, sollte man Basics nicht für Analysen verwenden. Das Anspielen und Integrieren von Erwerbsepisoden in pTarget-Datensätze ist eine komplexe Sache.

  1. Es gibt viele Personen, die mehreren Erwerbstätigkeiten gleichzeitig nachgehen.
  2. Man muss ein Monatssplitting mit den Erwebsepisoden vollziehen. Dadurch entsteht für jeden Monat für die Dauer einer Episode eine eigene Zeile. Diese Zeile kann man dann mit dem Interviewdatum aus CohortProfile matchen, sodass das Ereignis der richtigen Welle in den Target-Datensätzen zugeordnet werden kann.

Die gleichzeitigen Erwergbstätigkeit führen dann zu Problemen, da dann mehr als eine Zeile der Episoden dasselbe Monatsdatum haben und ein 1:1-Merge mit den pTarget-Daten unmöglich wird, wenn man nicht zusätzliche Maßnahmen ergreift um diese Überlappungen/Duplikate aufzuheben.
Man kann zum Beispiel alle Personen mit Überlappungen ausschließen (a), alle Episoden nach dem m:1-Merge ins wide-Format überfuhren(b) oder vorab regelbasiert Episoden auswählen, die man anspielen will (c). Das alles sind technische Lösungen für dein Problem. Welche Lösung für dich in Frage kommt, muss du von inhaltlichen Kriterien abhängig machen.

Das alles braucht viel Zeit…

Viele Erfolg
Dietmar

*/

use "$data/SC5_CohortProfile_D_19-0-0.dta", clear

	// hier nur die Variablen behalten, die man benötigt, ggfs. anpassen
	keep  ID_t ID_i ID_tg wave tx8600y tx8600m tx8600d tx80521


    *Set labels to English
    label language en
    ssc install distinct

distinct ID_t // Person Identification

sort ID_t wave

    *Merge the Basics data (m:1 because each wave in CohortProfile is linked to one Basics entry)
    merge m:1 ID_t using "$data/SC5_Basics_D_19-0-0.dta", ///
    keepusing(t700001 tx29063 tx29064 tx29065 tx29066 tx29067 tx29068 tx29069 tx29073 tx29090 ) ///
    keep(1 3) nogen

    *Merge pTargetCAWI
    merge 1:1 ID_t wave using "$data/SC5_pTargetCAWI_D_19-0-0.dta", ///
    keepusing(tg76001_g4 tg76001_g2) ///
    keep(1 3) nogen

merge 1:1 ID_t wave using "$data/SC5_pTargetCATI_D_19-0-0.dta", ///
keepusing(tg02001_ha tg02001 tg02001_g1 tg04001_g3 tg04001_g4R tg04001_g5R tg04001_g6 tg04001_g2R tg04002 t531262) ///
keep(1 3) nogen

// Vorbereitungen für Monatssplitting um anhand des Interviewdatums und des Spelldatums beide Datensätze zum richtigen Zeitpunkt zu mergen
keep if tx80521 == 1
generate month = ym(tx8600y,tx8600m) // Interviewdatum als eine Variable
format %tm month
keep if !missing(month)
duplicates tag ID_t month, generate(dup)
browse if dup // ein Person hat im selben Monat an Welle 1 und 2 teilgenommen. Teilnahme an W2 vor W1.
bysort ID_t month (tx8600d): replace month = month + _n -1 if dup > 0 // Verändere das Intviewdatum so, dass ID_t+month unique sind
isid ID_t month // check ob ID_t+month unique ist
distinct ID_t //N == 17909 >> es sind noch alle da
drop dup
tempfile target // als temporären Datensatz speichern
save "`target'", replace

**************************************************
// Erwerbsepisoden vorbereiten:
  
use ID_t splink spms subspell disagint ts23201_g1 ts23256 ts23221 using "$data/SC5_spEmp_D_19-0-0.dta", clear
keep if subspell == 0
drop if disagint == 2 // annulliere Episoden löschen
drop if ts23256 == 2 //studentische Tätigkeiten droppen, weil der Zeitraum danach betrachtet werden soll
bysort ID_t(splink): egen anz_widerspr=total(disagint)
distinct ID_t
drop if anz_widerspr > 2 // Personen mit mehr als zwei Widersprüche droppen - da ist etwas schief gelaufen
 
distinct ID_t // 1 Person verloren
merge 1:1 ID_t splink using "$data/SC5_Biography_D_19-0-0.dta", keepusing(starty startm endy endm splast) keep(matched) nogenerate
distinct ID_t // N= 12854 >> 1 Person verloren


generate start = ym(starty, startm)
generate end = ym(endy, endm) 
drop starty startm endy endm anz_widerspr subspell ts23256
 
keep if !missing(start,end)
format %tm start end


// Check ob mehrere Episoden einer Person gleichzeitig vorliegen (z.B. zwei Erwerbstätigkeiten zur selben Zeit). Dann muss mit diesen Überlappungen umgegangen werden, wenn man Erwerbsepisoden in die Targetdatensätze mit Wellenlogik: ID_t+wave integriergen will.

// Variable erzeugen, die die Maximale Spellanzahl einer Personen enthält
bysort ID_t (splink): generate anz_spells = _N

generate overlap = 0
summarize anz_spells // die Statistik von summarize gibt den Maximalwert der Anzahl der Episoden über alle Personen als `r(max)' aus.

// Überlappungen identifizieren: eine Schleife von Zeile 1 bis zu höchstmöglichen Ereignis läuft innerhalb der jeweiligen Personen und checkt, ob sich Episoden überschneiden
forvalues num = 1/`r(max)' {
	bysort ID_t (start end splink): replace overlap = 1 if ((start <= end[_n-`num']) & ID_t == ID_t[_n-`num'])
	bysort ID_t (start end splink): replace overlap = 1 if ((end >= start[_n+`num']) & ID_t == ID_t[_n+`num'])

}
bysort ID_t  (start end splink): egen any_overlap = max(overlap)
br ID_t overlap start end splast spms ts23201_g1 if any_overlap // Personen mit Überlappungen ansehen
drop anz_spells

// es gibt Überlappungen der Spells bzw. Personen, die mehreren Erwebstätigkeiten zur selben Zeit nachgehen
/* Dadurch kann man auch nicht einfach spEmp 1:1 mit pTarget-Datensätzen mergen.
Was man dann anschließend macht, hängt ganz von inhaltlichen Fragen ab. Wenn man mit Löhnen oder Arbeitsstunden rechnet, kann man nicht einfach eine parallelen Erwerbsspell löschen - dann muss man erst den Lohn aufsummieren

 Abgesehen davon gibt es unter anderem folgende Optionen:
a) alle Personen mit gleichzeitigen Episoden ausschließen
b) den aus dem Merge resultierenden Datensatz ins wide-format bringen und für alle überzähligen Spells Variablen generieren, eine Aufbereitung der Variablen erfolgt dann im Wide-Format
c) Spells vor dem Merge aufbereiten: einzelne Spells, die sich überlappen, zusammenfügen, unplausible Spells löschen, etc. wie im wide-format-fall erholgt hier die Aufbereitung dann eben im long-format
*/



preserve
******** Option a) *********
distinct ID_t // N=12854
keep if any_overlap == 0 // alle PERSONEN löschen, die Überschneidungen haben
distinct ID_t // >> es gehen ca. 3500 Personen verlosen

/* Monatssplitting: für jeden Monat der Dauer des Ereignisses eine Zeile generieren und ein Datum generieren, dass von Start bis Ende des Ereignissen geht. Anhand der erzeugten Variable "month" kann man dann das Interviewdatum des CohortProfiles mit "month" des Spelldatensatzes mergen */

generate duration = end - start + 1
assert duration >= 1  //check: gibt es negative Dauern?
expand duration
bysort ID_t splink: generate month = start + _n - 1
format %tm month
assert month >= start & month <= end // check: liegt der Monat des Spell innerhalb von Anfang und Ende?
isid ID_t month // Check: sind ID_t+month variablen um Zeilen im Datensatz eindeutig zu identifizieren?
merge 1:1 ID_t month using "`target'", keep(matched) nogenerate
distinct ID_t // N= 8292 >> es gehen weitere 1000 Personen verloren
drop month
restore


preserve
******** Option b) *********
distinct ID_t // N=12854

/* Monatssplitting: für jeden Monat der Dauer des Ereignisses eine Zeile generieren und ein Datum generieren, dass von Start bis Ende des Ereignissen geht. Anhand der erzeugten Variable "month" kann man dann das Interviewdatum des CohortProfiles mit "month" des Spelldatensatzes mergen */

generate duration = end - start + 1
assert duration >= 1
expand duration
bysort ID_t splink: generate month = start + _n - 1
format %tm month
assert month >= start & month <= end
duplicates report ID_t month 
merge m:1 ID_t month using "`target'", keep(matched) nogenerate
distinct ID_t // 11904 Personen bleiben übrig

drop month
distinct ID_t wave, joint // von 189548 Zeilen sind 17132 Zeilen Duplikate >> das bedeutet, dass Personen mehr als eine Erwebstätigkeit pro Welle hatten
duplicates report ID_t wave //>> bis zu sechs gleichzeitige Episoden wurden angegeben.
bysort ID_t wave (spms splink): generate nr = _n

// Um die Uniqueness von ID_t+wave zurueckzuerhalten, kann man nun die Daten ins wide-format reshapen
foreach var of varlist splink disagint ts23201_g1 ts23221 duration spms splast start end {
	rename `var' `var'_w
}

reshape wide *_w, i(ID_t wave) j(nr)

/* >> nun hat man so viele *_w-Variablen wie Überlappungen >> in diesem Beispiel z.B. ts23201_g1_w1 ... ts23201_g1_w6
und die splink-id in splink_w1 ist nicht zwingend dieselbe wie in splink_w2
es ist also ein subotimaler Vorgang
*/
restore



*preserve
******** Option c) *********
*vielleicht zuerst versuchen Spells auszuschließen wie z.B. ts23201_g1 nicht ermittelbar, oder abgeschlossene Ereignisse mit einer Dauer <= 3 Monate löschen. 
generate duration = end - start + 1

drop if duration <= 3 & splast == 2 & overlap == 1
assert duration >= 1

// nachdem man nun einige Überlappungen gelöscht hat, muss man die Prozedur nochmal durchführen...
drop overlap any_overlap
bysort ID_t (splink): generate anz_spells = _N
generate overlap = 0
sum anz_spells 
forvalues num = 1/`r(max)' {
	bysort ID_t (start end splink): replace overlap = 1 if ((start <= end[_n-`num']) & ID_t == ID_t[_n-`num'])
	bysort ID_t (start end splink): replace overlap = 1 if ((end >= start[_n+`num']) & ID_t == ID_t[_n+`num'])

}
bysort ID_t  (start end splink): egen any_overlap = max(overlap)
br ID_t overlap start end splast spms ts23201_g1 if any_overlap // bei Bedarf diese Duplikate betrachten
drop anz_spells

// Indikator bilden, der angibt, ob Missings in der Berufskodiuerung vorliegen
generate missings_beruf = (missing(ts23201_g1) | ts23201_g1 < 0)
nepsmiss ts23221
distinct ID_t spms ts23221 splast missings_beruf duration disagint, joint miss

/* wenn man möglichst nur die Duplikate behalten will, die Hauptereignisse sind, am längsten andauern und Vollzeit sind und keine Missings in ts23201_g1 haben, muss man den Datensatz so sortieren, damit der erste Spell der Sortierung behalten wird (oder der letzte, aber die Sortierung muss konsistenz sein:
spms: 1=Hauptereignis 2=Nebenereignis; ts23221: 1=Vollzeit 2=Teilzeit; splast: 1= ja 2=nein; missings_beruf: 0 nein 1: ja
duration (dauer des Ereignisses, muss mit (-1) multipliziert werden, dass der niedrigste Wert der höchsten Dauer entspricht )
*/
generate duration_neg = duration * (-1) // hier im Beispiel Spelldauer so sortieren, dass der längste Spell behalten werden soll, wenn es Überlappungen gibt 

// trotzdem gibt es noch immer Duplikate:
distinct ID_t spms ts23221 splast missings_beruf duration_neg disagint start end, joint miss
* >> zusätzlich splink zur Sortierung aufnehmen und dann abhängig von den Präferenzen sortieren und alle Überlappungen löschen, wenn diese nicht der Sortierung entsprechen
distinct ID_t
bysort ID_t (missings_beruf splast ts23221 spms duration_neg disagint start end splink): drop if _n != 1  & overlap == 1
distinct ID_t // ca. 6000 Episoden (überlappungen) und 0 Personen verloren

/* Monatssplitting: für jeden Monat der Dauer des Ereignisses eine Zeile generieren und ein Datum generieren, dass von Start bis Ende des Ereignissen geht. Anhand der erzeugten Variable "month" kann man dann das Interviewdatum des CohortProfiles mit "month" des Spelldatensatzes mergen. So landet das Ereignis in der richtigen Welle */

expand duration
bysort ID_t splink: generate month = start + _n - 1
format %tm month
assert month >= start & month <= end
isid ID_t month // keine Überlappungen/Duplikate
merge 1:1 ID_t month using "`target'", keep(matched) nogenerate
distinct ID_t // 11745 Personen bleiben übrig
1 Like

Hallo nochmal Laura!

Wenn du spVocTrain mit den restliche Daten mergen willst, muss du auch wie bei spEmp ein Monatssplitting durchführen und dann an den Datensatz wieder ID_t+month anspielen.

VG
Dietmar

1 Like

Hallo Dietmar,

vielen Dank für die Erklärungen und die Beispielcodes, die haben mir sehr geholfen. Ich konnte nun meinen Code soweit fertigstellen und es funktioniert auch alles. Dennoch sind ein paar Fragen noch aufgekommen.

  1. Ist die Art des mergen über month wichtig? insbesondere welchen Datensatz man merged und welcher der „Master“ - file darstellt.
  • Bei dem mergen des Study spell Datensatzes über month mit dem Datensatz „cp_month“ ( ID_t wave month von CohortProfile) hatte ich zunächst das Problem, dass ID_t und wave nach dem mergen nicht unique waren. Ich hatte es zunächst auf wie in dem Code den du zuvor angehangen hast probiert:

// Monatssplitting ohne Überschneidungen, da schon im Vorfeld nur ein Spell pro Person behalten wurde : Spelldatensatz aufblähen, sodass für jeden Monat der Spelldauer eine Zeile entsteht. Die Variable, die diesen Monat markiert, wird month genannt.
use „studium'", clear expand duration bysort ID_t splink: generate month = studium_start + _n - 1 isid ID_t month //nun kann anhand month die richtige wave-Variable mit den Spelldaten zusammengebracht werden, alle nicht gematchtenn Fälle werden fallen gelassen. merge 1:1 ID_t month using "cp_month’“, keep(matched) nogenerate
isid ID_t wave
save „`studium’“, replace

  • Daraufhin have ich mir nocheinmal die Videos auf der NEPS Seite angeschaut und es dann auf diese Weise probiert und ID_t und wave waren nun auch unique:

// Monthsplitting: Study spells

use „$posted/study.dta“, clear
expand duration
bysort ID_t splink: generate month = study_start + _n - 1
format month %tm
assert month >= study_start & month <= study_end
isid ID_t month
save „$posted/study_month“, replace

use „$posted/cp_month.dta“, clear
merge 1:m ID_t month using „$posted/study_month.dta“, generate(merge)
keep if merge == 3
isid ID_t wave
distinct ID_t // 4806 individuals
save „$posted/study_wave“, replace

  1. Im laufe der Eingrenzungen, insbesondere bei den spell Daten (um die überlappungen zu bereinigen), verliere ich sehr viele individuen. Für meine spätere Analsyse soll meine Referenzgruppe aus Studierenden bestehen, die MINT studieren. Deswegen habe ich bei VocTrain alle anderen Studierenden sofort entfernt, um so individuen mit überlappungen auf meine relevante gruppe zu begrenzen. Macht es eventuell bei „größeren“ Filterungen, diese in dem endfile durchzuführen? - Ich möchte möglichst wenig individuen aus meiner referenzgruppe verlieren.

  • Month splitting - variable month

use ID_t wave tx8600y tx8600m tx8600d using „$data/SC5_CohortProfile_D_19-0-0.dta“, clear
generate month = ym(tx8600y,tx8600m)
format month %tm
keep if !missing(month)
// eine Person hat in einem Monat in Welle 1 und Welle 2 teilgenommen. Tagedatum heranziehen und das spätere Interview auf einen Monate später setzen
duplicates report ID_t month
bysort ID_t month (tx8600d): replace month = month+1 if _n !=1
duplicates report ID_t month
isid ID_t month
isid ID_t wave
keep ID_t wave month
save „$posted/cp_month.dta“, replace

// Monthsplitting: Study spells

use „$posted/study.dta“, clear
expand duration
bysort ID_t splink: generate month = study_start + _n - 1
format month %tm
assert month >= study_start & month <= study_end
isid ID_t month
save „$posted/study_month“, replace

use „$posted/cp_month.dta“, clear
merge 1:m ID_t month using „$posted/study_month.dta“, generate(merge)
keep if merge == 3
isid ID_t wave
distinct ID_t // 4806 individuals
save „$posted/study_wave“, replace

// Monthsplitting: Occupational spells
use „$posted/occupation.dta“, clear
expand duration
bysort ID_t splink: generate month = occ_start + _n - 1
format month %tm
assert month >= occ_start & month <= occ_end
isid ID_t month
save „$posted/work_month“, replace

use „$posted/cp_month.dta“, clear
merge 1:m ID_t month using „$posted/work_month.dta“, generate(merge)
keep if merge == 3
isid ID_t wave
distinct ID_t // 4806 individuals
save „$posted/work_wave“, replace

// merge study and occ. spells
use „$posted/work_wave.dta“, clear
merge 1:1 ID_t wave using „$posted/study_wave“, keep(master match using) nogenerate
save „$posted/study_occupation“, replace
distinct ID_t // 4.904 individuals

use „$posted/master_file.dta“, clear
merge 1:1 ID_t wave using „$posted/study_occupation“, keep(master match)
distinct ID_t wave
drop _merge
save „$posted/master_final_version.dta“, replace

Hallo Laura!

Es ist egal, ob der gesplittete Episodendatensatz als Master- oder Usingdatensatz angespielt wird. Das Ergebnis ist dasselbe.

Auch hier ist es für das Ergebnis komplett egal, wo du die Fälle wegwirfst. Aber es ist besser sie am Anfang wegzuwerfen, weil du sie dann nicht mitschleppst und dier dadurch vielleicht manche Aufbereitungsschritte sparen kannst.

VG
Dietmar

Hallo,

alles klar, vielen Dank! Nur noch mal zum Verständnis. Am Ende muss ich die spell Datensätze spVocTrain und spEmp aber schon auf ID_t wave runterbrechen - also das diese unique sind - um sie richtig mit den paneldatensätzen zu mergen, oder?

LG, laura

Hallo Laura!

ja, ich denke, es wäre so einfacher.
LG
Dietmar

1 Like