SC6: merge

Guten Tag,

ich nutze für meine Abschlussarbeit NEPS-Daten (SC 6). Für meine Analysen zum Thema Weiterbildungsrenditen habe ich folgende Datensätze:

  • SC6_Biography_D_8-0-0
  • SC6_pTarget_D_8-0-0
  • SC6_spEmp_D_8-0-0
  • SC6_Basics_D_8-0-0

verbunden.

 

Die Frage ist, hat das „mergen“ funktioniert, denn es ist für mich problematisch die zeitveränderlichen Panelvariablen und die Episodendaten zusammenzubringen.

 

Mein auf das Wesentliche verkürztes DO-File seht Ihr hier:

 

 

version 13
clear
set more off, perm
set scrollbufsize  50000

cd "F:\NEPS_DATA\1_Daten_D_8-0-0\Stata"


/************************
	load masterfile SC6_Biography_D_8-0-0
************************/

// load SC6_Biography_D_8-0-0 MASTERFILE
use "SC6_Biography_D_8-0-0.dta", clear

* prepare data from SC6_Biography_D_8-0-0
keep if sptype == 26  // nur wenn in arbeit
// recode missings
nepsmiss _all

// Veränderungen speichern
save "biography", replace


/************************
	load file SC6_pTarget_D_8-0-0
************************/

use "SC6_pTarget_D_8-0-0.dta", clear

* prepare data from SC6_pTarget_D_8-0-0
// nur relevante Variablen aufheben
keep ID_t wave splink t700001 t70000m t70000y tx20001 tx20002 tx20003        ///
     t405000_ha t731301_ha t731303_ha t731351_ha t731353_ha t271800 t271801  ///
	 t271802 t271804
// recode missings
nepsmiss _all

list ID_t splink wave t700001 in 1/100, sepby(ID_t)


// Veränderungen speichern
save "ptarget", replace


/************************
	merge der Datensätze ptarget --> biography
************************/

// load biography MASTERFILE
use "biography", clear

// merge via ID_t & splink (one-to-many merge!)
merge 1:m ID_t splink using "ptarget", keep (master matched)
drop  _merge

// merge speichern
save "bio_ptarg", replace


/************************
	load file SC6_spEmp_D_8-0-0
************************/

use "SC6_spEmp_D_8-0-0.dta", clear

* prepare SC6_spEmp_D_8-0-0.dta
// drop subspells - only keep main or harmonized episode
keep if subspell == 0
// nur relevante Variablen aufheben
keep ID_t wave splink ts23204_ha ts23510_g1 ts23243_v1 ts23219_g1 ts23229    ///
     ts23230 ts23231 ts23232 ts2311m ts2311y ts2312m ts2312y ts23310
// recode missings
nepsmiss _all

// Veränderung speichern
save "spemp", replace

/************************
	merge der Datensätze spemp --> bio_ptarg
************************/

// load bio_targ MASTERFILE
use "bio_ptarg", clear

// merge via ID_t & splink (many-to-one merge!)
merge m:1 ID_t splink using "spemp", keep (master matched)
drop _merge

// merge speichern
save "bio_targ_spemp", replace

/************************
	load file SC6_Basics_D_8-0-0
************************/

use "SC6_Basics_D_8-0-0.dta", clear

* prepare SC6_Basics_D_8-0-0
// nur relevante Variablen aufheben
keep ID_t t700001 t70000m t70000y tx20001 tx20002 tx20003 tx28102 tx29062    ///
     tx27000 tx29004 tx29949
// recode missings
nepsmiss _all

// Veränderungen speichern
save "basics", replace


/************************
	merge der Datensätze basics --> bio_targ_spemp
************************/

// load bio_targ_spemp MASTERFILE
use "bio_targ_spemp", clear

// merge via ID_t (many-to-one merge!)
merge m:1 ID_t using "basics", keep(master matched)
drop _merge

// merge speichern
save "bio_targ_spemp_basics", replace

use "bio_targ_spemp_basics"

list ID_t splink wave t700001 in 1/100, sepby(ID_t)

     ,-----------------------------------------------------------------,
 87. , 8000352   260001   2009/2010 (1. NEPS-Haupterhebung)          . ,
 88. , 8000352   260002   2009/2010 (1. NEPS-Haupterhebung)          . ,
 89. , 8000352   260003   2009/2010 (1. NEPS-Haupterhebung)          . ,
 90. , 8000352   260004   2009/2010 (1. NEPS-Haupterhebung)          . ,
 91. , 8000352   260005   2013/2014 (5. NEPS-Haupterhebung)   männlich ,
 92. , 8000352   260006   2012/2013 (4. NEPS-Haupterhebung)          . ,
     ,-----------------------------------------------------------------,
 93. , 8000353   260001   2009/2010 (1. NEPS-Haupterhebung)          . ,
 94. , 8000353   260002   2009/2010 (1. NEPS-Haupterhebung)          . ,
 95. , 8000353   260003   2015/2016 (7. NEPS-Haupterhebung)   männlich ,
 96. , 8000353   260003   2015/2016 (7. NEPS-Haupterhebung)   männlich ,
     ,-----------------------------------------------------------------,
 97. , 8000354   260001   2009/2010 (1. NEPS-Haupterhebung)          . ,
 98. , 8000354   260002   2009/2010 (1. NEPS-Haupterhebung)          . ,
 99. , 8000354   260003   2009/2010 (1. NEPS-Haupterhebung)          . ,
100. , 8000354   260004   2009/2010 (1. NEPS-Haupterhebung)          . ,
     +-----------------------------------------------------------------+

Problem: Das Geschlecht ist nicht durchgehend vorhanden oder komplett verschwunden.





 

Vielen Dank im Voraus

 

Thomas Kind

Hallo Thomas,

und willkommen im NEPSforum! Leider ist es, durch den Jahreswechsel bedingt, zu ein wenig Verzögerung gekommen, bis wir uns im Detail deines Problems annehmen konnten, wir bitten, das zu entschuldigen.

Soweit ich das sehe, ist das Kernproblem deiner Datenaufbereitungssyntax, wie du sie uns hier zeigst, dass sie unterschiedliche Datenarten (nämlich Episoden- und Paneldaten) ein einen Topf wirft. Das sorgt zwangsweise dafür, dass an der ein- oder anderen Stelle lückenhafte Daten entstehen; ich denke, es ist sinnvoller, zunächst beide Datentypen getrennt zu halten, und erst für die Analyse zu verbinden. Dabei ist es notwendig, im Hinterkopf zu haben, welches Datenformat die geplante Analyse eigentlich benötigt – handelt es sich um eine Ereignisdatenanalyse, es müssen also Episodendaten vorliegen, oder eine "herkömmliche" Paneldatenanalyse, die (wiederholte) Querschnittsinformationen verlangt.

Ich gehe, weil du nichts detaillierteres dazu geschrieben hast, vom letzteren Fall aus. Der sinnvollste Weg dahin ist:

  1. Episodendaten vorbereiten
  2. Querschnitts- bzw. Paneldaten vorbereiten
  3. Zusammenspielen der beiden Informationstypen auf Basis des Interviewdatums

Es ist das letzte Detail an dieser Prozedur, das in deiner Syntax anders gelaufen ist. Du spielst pTarget und Biography über die Variable splink zusammen. Das ist mit ziemlicher Sicherheit nicht das, was du möchtest – die Variable splink in pTarget bezieht sich nicht auf die jeweils zum Interviewzeitpunkt andauernde Episode, sondern auf die Ewerbsepisode, zu der im Querschnittsfragebogen in den Wellen 4 und 8 gesonderte Fragen gestellt wurden. Für die übrigen Wellen ist die Variable nicht gefüllt, und deshalb produziert dein merge viele fehlende Werte.

Ich habe den meines Erachtens korrekten Weg zum Zusammenspieleln in der folgenden Syntax skizziert; dabei habe ich ein paar Feinheiten eingebaut, die vielleicht auch zukünftig hilfreich sein könnten:

  1. Die Syntax verwendet nepsuse aus dem Stata-Paket nepstools (das du bereits kennst, du verwendest ja auch nepsmiss aus dem gleichen Paket), um das Laden der Datensätze etwas komfortabler zu gestalten.
  2. Für temporäre Dateien verwendet die Syntax Statas eingebauten Mechanismus für temporäre Dateien, tempfile. So kümmert sich Stata selbst darum, die temporären Dateien wieder zu entfernen.
// "simplified" loading of NEPS files with -nepsuse-: pre-save path, cohort, version and level
global NEPSuse_directory "/usr/local/share/NEPS_SUFs/\`cohort'_\`level'_\`dashedversion'/Stata14"
global NEPSuse_level "D"
global NEPSuse_cohort "SC6"
global NEPSuse_version "8.0.0"

// annouce temporary datasets to Stata
tempfile emp episodes

// prepare interesting variables from spEmp
nepsuse ID_t wave splink subspell ts23204_ha ts23510_g1 ts23243_v1 ts23219_g1 	///
	ts23229	ts23230 ts23231 ts23232 ts2311m ts2311y ts2312m ts2312y ts23310	///
	using "spEmp" , clear

keep if subspell==0
drop subspell
save `"`emp'"'

// load Biography, merge relevant variables from spEmp
nepsuse "Biography", clear

* only keep employment episodes
keep if sptype == 26

* merge with prepared spEmp data subset
merge 1:1 ID_t splink using `"`emp'"', nogenerate assert(match using) keep(match)

* nepsmiss
nepsmiss _all

* blow up data to monthly discrete episode
generate enddate=ym(endy,endm)
generate startdate=ym(starty,startm)
generate duration=enddate-startdate+1
expand duration
bysort ID_t splink : generate intdate=startdate+_n-1
format enddate startdate intdate %tm

// save episode data
save `"`episodes'"', replace

// prepare interesting variables from pTarget
nepsuse ID_t wave t700001 t70000m t70000y tx20001 tx20002 tx20003 t405000_ha 	///
	t731301_ha t731303_ha t731351_ha t731353_ha t271800 t271801		///
	t271802 t271804 intm inty						///
	using "pTarget", clear

* nepsmiss
nepsmiss _all

* generate interview date to merge episode data with
generate intdate=ym(inty,intm)
format %tm intdate

* there are two observations with invalid interview dates for wave 7 (december 2015); they are dropped here
drop if wave==7 & intm==12 & inty==2015

* merge with episode data: only information that is valid at the interview date
merge 1:m ID_t intdate using `"`episodes'"' , keep(master match) nogenerate

* inspect duplicates: all the tagged observations reported more than one employment episode at the interview date
* they have to be reduced for an analyses; it is, however, a decision influencing possible results
* which in way the reduction has to be performed (dropping duplicates, generating means, etc)
duplicates report ID_t wave
quietly : duplicates tag ID_t wave , generate(dups)
tabulate dups

Aber Achtung: Auch jetzt ist der Datensatz noch nicht fertig zum Analysieren; denn es gibt Personen, die (plausiblerweise oder auch nicht) mehrere zu einem Interviewzeitpunkt andauernde Erwerbsepisoden berichten. Für eine vernünftigte Analyse müssen diese Mehrfachnennungen noch bereinigt werden. Wie genau ist aber abhängig von der Fragestellung der Analyse.

Ich hoffe, das hilft ein wenig weiter. Rückfragen kannst du selbstverständlich gerne hier anbringen.

Beste Grüße
Bela

Hallo NEPS-Forum, Hallo Bela,

vielen Dank für deine sehr hilfreichen Anweisungen und detailierten Hinweise.


Deine Vermutung ist richtig, ich möchte eine Panelanalyse durchführen. Es soll untersucht werden wie Weiterbildung das Einkommen verändert.

Dabei ist ein neues Problem aufgetreten:

Ich möchte den zusammengefügte Datensatz aus FurtherEducation und spFurtherEdu2 an den schon bekannten Datensatz anbinden.

Die Zusammenführung von FurtherEducation und spFurtherEdu2 ist folgend wiedergegeben:

//lade FurtherEducation Datensatz
use "SC6_FurtherEducation_D_8-0-0", clear
keep ID_t wave splink course number tx2821m tx2821y tx2822m tx2822y tx28204

// merge spFurtherEdu2 zu FurtherEducation
merge m:1 ID_t course using "SC6_spFurtherEdu2_D_8-0-0", keep(master matched) nogenerate ///
keepusing(wave t272043)

list ID_t splink course wave tx2821y tx2822y tx28204 t272043 in 1/100

// recode missings
nepsmiss _all

// Selektion der course spells
keep if !missing(course)
* nur Arbeitsepisoden berücksichtigen
tab  splink
keep if splink >= 260000 & splink <= 260021 

list ID_t splink course wave tx2821y tx2822y tx28204 t272043 in 1/100

save "merge_further", replace

 

Meine Annahme war, diesen Datensatz ähnlich deiner Vorgabe an den obigen Datensatz anzubinden.

Als Basis sollte das Interviewdatum und das Startdatum der Weiterbildungskurses dienen:

use "merge_further", clear

// recode Startdatum der Kurse in Stata Datumsformat
generate startdatum = ym(tx2821y,tx2821m)

// recode Enddatum der Kurse in Stata Datumsformat
tab tx2822m, miss
tab tx2822y, miss
generate enddatum = ym(tx2822y,tx2822m)
keep if !missing(enddatum)
tab enddatum 

* "aufblasen"
generate duration1 = enddatum - startdatum + 1
expand   duration1

bysort ID_t splink: generate interviewdatum = startdatum + _n-1
list   ID_t interviewdatum startdatum in 1/50, sepby(ID_t)
format enddatum startdatum interviewdatum %tm

// save Datensatz
save "Weiterbildung", replace

 

Den merge-Versuch dieses Datensatzes an den Datensatz aus der ersten Forumsanfrage ist im Folgenden abgebildet

(Anmerkung die duplicates sind gelöscht):
keep if dups == 0

//lade den Datensatz masterfile (Datensatz aus der ersten Forumsanfrage mit gelöschten duplicates)
use "masterfile", clear

* generate Interviewdatum um mit Episodenkursdaten zu verbinden
generate interviewdatum = ym(inty,intm)
list     ID_t interviewdatum inty intm in 1/50
format   %tm interviewdatum
tab      interviewdatum wave


// * merge mit den Episodendaten
merge 1:m ID_t interviewdatum using "weiterbildung", keep(master match) nogenerate



 

Die Stata Fehlermeldung besagt: variables ID_t interviewdatum do not uniquely identify observations in the master data.


Was ist schief gelaufen?

Hallo Thomas,

(Anmerkung die duplicates sind gelöscht):
keep if dups == 0

Was ist schief gelaufen?

Kurz gesagt: ich glaube dir nicht, dass du "keep if dups==0" ausgeführt hast – oder zumindest vermute ich, dass du deine Datei "masterfile" danach nicht erneut abgespeichert hast.

Wenn ich nach dem Durchlauf meiner Syntax von oben im aktiven Datensatz folgendes die Dubletten zwangslösche und Stata gegenechecken lasse, ob ID_t und wave oder ID_t und intdate unique sind, dann klappt das:

keep if dups==0
isid ID_t wave
isid ID_t intdate

Im Anschluss kann ich diesen Datensatz problemlos speichern, deine Syntax verwenden, um die Weiterbildungsdaten vorzubereiten, und sie anspielen.

Im (inzwischen leider sehr langen) Syntaxbeispiel, das hier unten folgt, kannst du dir das ansehen -- ich habe lediglich die Reihung der einzelnen Datenvorbereitungs-Schritte ausgetauscht, damit ich weniger zwischenspeichern muss (erst alle Einzeldaten vorbereiten, dann zusammenspielen).

Hilft das etwas?

Grüße
Bela

// "simplified" loading of NEPS files with -nepsuse-: pre-save path, cohort, version and level
global NEPSuse_directory "/usr/local/share/NEPS_SUFs/\`cohort'_\`level'_\`dashedversion'/Stata14"
global NEPSuse_level "D"
global NEPSuse_cohort "SC6"
global NEPSuse_version "8.0.0"

// prepare interesting variables from spFurtherEdu2
tempfile spfurtheredu2
nepsuse ID_t wave course t272043 ///
	using "spFurtherEdu2" , clear
save `"`spfurtheredu2'"'

// prepare interesting variables from FurtherEducation
nepsuse ID_t wave splink course number tx2821m tx2821y tx2822m tx2822y tx28204 ///
	using "FurtherEducation", clear

// merge spFurtherEdu2 and FurtherEducation
merge m:1 ID_t course using "`spfurtheredu2'", keep(master matched) nogenerate ///
	keepusing(wave t272043)

list ID_t splink course wave tx2821y tx2822y tx28204 t272043 in 1/100

// recode missings
nepsmiss _all

// select courses with valid course number
keep if !missing(course)

// select employment episodes
keep if inrange(splink,260000,269999)

*list ID_t splink course wave tx2821y tx2822y tx28204 t272043 in 1/100

// blow up data to monthly discrete episodes
generate startdate = ym(tx2821y,tx2821m)
generate enddate = ym(tx2822y,tx2822m)
keep if !missing(startdate)

generate duration1 = enddate - startdate + 1
expand   duration1

bysort ID_t splink: generate intdate = startdate + _n-1
list   ID_t intdate startdate in 1/50, sepby(ID_t)
format enddate startdate intdate %tm

// save Datensatz
tempfile furtheredu_combined
save "`furtheredu_combined'", replace

// prepare interesting variables from spEmp
tempfile emp
nepsuse ID_t wave splink subspell ts23204_ha ts23510_g1 ts23243_v1 ts23219_g1 	///
	ts23229	ts23230 ts23231 ts23232 ts2311m ts2311y ts2312m ts2312y ts23310	///
	using "spEmp" , clear

keep if subspell==0
drop subspell
save `"`emp'"'

// load Biography, merge relevant variables from spEmp
tempfile episodes
nepsuse "Biography", clear

* only keep employment episodes
keep if sptype == 26

* merge with prepared spEmp data subset
merge 1:1 ID_t splink using `"`emp'"', nogenerate assert(match using) keep(match)

* nepsmiss
nepsmiss _all

* blow up data to monthly discrete episodes
generate enddate=ym(endy,endm)
generate startdate=ym(starty,startm)
generate duration=enddate-startdate+1
expand duration
bysort ID_t splink : generate intdate=startdate+_n-1
format enddate startdate intdate %tm

// save episode data
save `"`episodes'"', replace

// prepare interesting variables from pTarget
nepsuse ID_t wave t700001 t70000m t70000y tx20001 tx20002 tx20003 t405000_ha 	///
	t731301_ha t731303_ha t731351_ha t731353_ha t271800 t271801		///
	t271802 t271804 intm inty						///
	using "pTarget", clear

* nepsmiss
nepsmiss _all

* generate interview date to merge episode data with
generate intdate=ym(inty,intm)
format %tm intdate

* there are two observations with invalid interview dates for wave 7 (december 2015); they are dropped here
drop if wave==7 & intm==12 & inty==2015

* merge with episode data: only information that is valid at the interview date
merge 1:m ID_t intdate using `"`episodes'"' , keep(master match) nogenerate

* inspect duplicates: all the tagged observations reported more than one employment episode at the interview date
* they have to be reduced for an analyses; it is, however, a decision influencing possible results
* which in way the reduction has to be performed (dropping duplicates, generating means, etc)
duplicates report ID_t wave
quietly : duplicates tag ID_t wave , generate(dups)
tabulate dups

// merge with prepared Further Education data
* eliminate duplicates (there would be smarter ways to do this instead if simply dropping them)
keep if dups==0
isid ID_t wave
isid ID_t intdate

// * merge mit den Episodendaten
merge 1:m ID_t intdate using "`furtheredu_combined'", keep(master match) nogenerate

 

Lieber Bela,

ich versuche gerade auch die Datensätze Biography, spEmp und pTarget zu mergen, komme aber nicht weiter… was ist denn mit intm und inty by pTarget gemeint?
Mein Ziel ist es am Ende Panel Daten zu haben um damit ein fixed effects model zu machen.

Liebe Grüße
Carina

Liebe Carina,

ohne dein genaues Problem näher beschrieben zu bekommen, kann ich hier leider nur raten.
Da sich mittlerweile aber ein paar der in den obigen Syntaxbeispielen verwendeten Variablennamen geändert haben, fangen wir doch einfach mal mit dem Ausschlusssprinzip an:
Sofern du versuchst, obige Syntax 1:1 lauffähig zu bekommen, müsstest du mindestens diejenigen Syntaxteile verändern, in denen erstmalig intm und inty aus pTarget verwendet wird. Ab Datenversion 12-1-0 existieren diese Variablen in pTarget nicht mehr, sondern sind als tx8600m und tx8600y in CohortProfile zu finden. Könnte das schonmal dein Problem lösen?
Wenn nein, bräuchte ich noch ein paar mehr Angaben, was du bisher erfolgreich / erfolglos gemacht hast, um dir weiterhelfen zu können (am besten mit ein paar Syntaxzeilen zur Ansicht :wink: - gerne auch nicht-öffentlich an fdz@lifbi.de ;-))

Viele Grüße,
Benno Schönberger