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.
- Es gibt viele Personen, die mehreren Erwerbstätigkeiten gleichzeitig nachgehen.
- 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