///Code generating CNPI and its components' values/// ////load dataset/// /* Requirements on the data & variable names. Data must have a panel structure with yearly observations on individuals on their yearly earnings from work, number of months spent in employment and the number of job terminations each year Variables required: pid - personal identifier (panel id) syear - calendar year employment & earnings data refer to employed_nmths - number of months in employment for each year perc_linc - yearly earnings from work expressed as a percentage of the low earnings threshold set by the researcher njobterm - number of job terminations for each year sex - any additional variable constant by pid The code generates CNPI for sequences of any length. The desired length can be altered at the code lines indicated by "set sequence length". The default is 5 years The code accounts for gaps in panel data, so there is no need to clean it beforehand */ /* clear use "..." */ ///generating dummy variable for years affected by low earnings from work/// gen liperc_low=0 replace liperc_low=1 if perc_linc<1 ///generating total n of years with low earnings and total n of month at work in a sequence/// macro drop _all /*accounting for gaps*/ tsset pid syear tsspell sex sum _spell local spell=r(max) *set sequence length: insert desired sequence length(s) in the following line, after local seqlength ... (default is 5) local seqlength 5 foreach sl in `seqlength' { local range=`sl' gen totalemplR`range'=. gen totallipercR`range'=. *providing maximum observation scope (max individual trajectory length) sum _seq local longest=r(max) local bound=`longest'-`range'+1 forvalues aa=1/`bound'{ local last=`aa'+`sl'-1 bysort pid _spell: egen totalemplR=total(employed_nmths) if _seq>=`aa' & _seq<=`last' replace totalemplR`range'=totalemplR if _seq==`last' bysort pid _spell: egen totallipercR=total(liperc_low) if _seq>=`aa' & _seq<=`last' replace totallipercR`range'= totallipercR if _seq==`last' drop totalemplR totallipercR } } drop _spell _end _seq ///generating non-employment component naci_nw/// macro drop _all /*account for gaps*/ tsset pid syear tsspell sex sum _spell local spell=r(max) *set sequence length: insert desired sequence length(s) in the following line, after local seqlength ... (default is 5) local seqlength 5 bysort pid _spell: egen EN=max(_seq) foreach sl in `seqlength' { local range=`sl' gen nwincidenceR`range'=. gen nw_recencyR`range'=. gen nw_incidence_licznikR`range'=. forvalues z=1(1)9{ gen naci_nw`z'R`range'=. } forvalues spl=1/`spell'{ *providing maximum observation scope (max individual trajectory length) sum _seq if _spell==`spl' local longest=r(max) local bound=`longest'-`range'+1 forvalues aa=1/`bound'{ local last=`aa'+`sl'-1 quietly levelsof pid if employed_nmths<12 & _seq>=`aa' & _seq<=`last' & EN>=`last' & _spell==`spl', local(pidneet) foreach l of local pidneet { display `l' levelsof syear if pid==`l' & employed_nmths<12 & _seq>=`aa' & _seq<=`last' & _spell==`spl', local(year) local max=r(r) local maxlessone=`max'-1 tokenize "`year'" local sumpid="" forvalues z=1/`maxlessone'{ local start `z' local next=`z'+1 local sum "" forvalues b=`next'/`max'{ local d``b''_``start''=((``b''-``start'')^-1) local sum "`sum' + `d``b''_``start'''" } local sumpid="`sumpid' `sum'" display `l' } replace nw_incidence_licznikR`range'=0`sumpid' if pid==`l' & _seq==`last' & _spell==`spl' } /*recencynw*/ gen lp`last'=. gen lpnw`last'=. local one=0 forvalues k=1/`sl'{ replace lp`last'=(1+ `one') if _seq==(`aa'+ `one') & _spell==`spl' local one=`one'+1 } replace lpnw`last'=lp`last'*(12-employed_nmths)/12 bysort pid: egen advnw_n=total(lpnw`last') gen advnw=advnw_n/(`range'*(`range'+1)/2) replace nw_recencyR`range'=advnw if _seq==`last' & _spell==`spl' drop advnw_n advnw drop lp`last' lpnw`last' } } gen denominator=sum(_n/(`range'-_n)) local den=denominator in `range' replace nwincidenceR`range'=nw_incidence_licznikR`range'/`den' replace nwincidenceR`range'=0 if totalemplR`range'==60 drop denominator /*generating component vals for different alpha*/ local i 1 foreach fa in .1 .2 .3 .4 .5 .6 .7 .8 .9 { replace naci_nw`i'R`range'=`fa'*nwincidenceR`range'+(1-`fa')*nw_recencyR`range' local i=`i'+1 } } drop _spell _end _seq EN ///generating low earnings component naci_liperc/// macro drop _all /*account for gaps*/ tsset pid syear tsspell sex sum _spell local spell=r(max) *set sequence length: insert desired sequence length(s) in the following line, after local seqlength ... (default is 5) local seqlength 5 bysort pid _spell: egen EN=max(_seq) foreach sl in `seqlength' { local range=`sl' gen lipercincidenceR`range'=. gen liperc_recencyR`range'=. gen nlipercincidenceR`range'=. gen liperc_incidence_licznikR`range'=. forvalues z=1(1)9{ gen naci_liperc`z'R`range'=. } forvalues spl=1/`spell'{ *providing maximum observation scope (max individual trajectory length) sum _seq if _spell==`spl' local longest=r(max) local bound=`longest'-`range'+1 forvalues aa=1/`bound'{ local last=`aa'+`sl'-1 quietly levelsof pid if perc_linc<1 & _seq>=`aa' & _seq<=`last' & EN>=`last' & _spell==`spl', local(pidlinc) foreach l of local pidlinc { display `l' levelsof syear if pid==`l' & perc_linc<1 & _seq>=`aa' & _seq<=`last' & _spell==`spl', local(year) local max=r(r) local maxlessone=`max'-1 tokenize "`year'" local sumpid="" forvalues z=1/`maxlessone'{ local start `z' local next=`z'+1 local sum "" forvalues b=`next'/`max'{ local d``b''_``start''=(``b''-``start'')^-1 local sum "`sum' + `d``b''_``start'''" } local sumpid="`sumpid' `sum'" display `l' } replace liperc_incidence_licznikR`range'=0`sumpid' if pid==`l' & _seq==`last' & _spell==`spl' } /*recency_earnings*/ gen lp`last'=. gen lplincratio`last'=. local one=0 forvalues k=1/`sl'{ replace lp`last'=(1+ `one') if _seq==(`aa'+ `one') & _spell==`spl' local one=`one'+1 } replace lplincratio`last'=lp`last'*(1-perc_linc) replace lplincratio`last'=0 if lplincratio`last'<0 bysort pid: egen advlinc_n=total(lplincratio`last') gen advlinc=advlinc_n/(`range'*(`range'+1)/2) replace liperc_recencyR`range'=advlinc if _seq==`last' & _spell==`spl' drop advlinc_n advlinc drop lp`last' lplincratio`last' } } gen denominator=sum(_n/(`range'-_n)) local den=denominator in `range' replace nlipercincidenceR`range'=liperc_incidence_licznikR`range'/`den' replace nlipercincidenceR`range'=0 if totallipercR`range'==0 drop denominator /*different alpha values*/ local i 1 foreach fa in .1 .2 .3 .4 .5 .6 .7 .8 .9 { replace naci_liperc`i'R`range'=`fa'*nlipercincidenceR`range'+(1-`fa')*liperc_recencyR`range' local i= `i'+1 } } drop _spell _end _seq EN ///generating job terminations component aejt/// /* The code generates aejt for any desired max_jt. It can be set at the code line indicated by "set maximum job terminations threshold (max_jt)". The default is 3 years */ macro drop _all /*account for gaps*/ tsset pid syear tsspell sex sum _spell local spell=r(max) *set sequence length: insert desired sequence length(s) in the following line, after local seqlength ... (default is 5) local seqlength 5 bysort pid _spell: egen EN=max(_seq) foreach sl in `seqlength' { local range=`sl' gen jtpersistR`range'=. *set maximum job terminations threshold (max_jt): insert desired threshold in the following line, after local jtnorm ... (default is 3) local jtnorm 3 foreach jtn in `jtnorm' { gen jt_recencyR`range'_`jtn'=. gen jt_recencyR`range'_`jtn'_licznik=. } gen jtpersist_licznikR`range'=. gen totaljtR`range'=. *gen jtincR`range'=. /*generating totaljt*/ sum _seq local longest=r(max) local bound=`longest'-`range'+1 forvalues aa=1/`bound'{ local last=`aa'+`sl'-1 bysort pid _spell: egen totaljtR=total(njobterm) if _seq>=`aa' & _seq<=`last' replace totaljtR`range'=totaljtR if _seq==`last' gen lp`last'=. local one=0 forvalues k=1/`sl'{ replace lp`last'=(1+ `one') if _seq==(`aa'+ `one') local one=`one'+1 } foreach jtn in `jtnorm' { gen lpjt`last'=. gen inc=njobterm/`jtn' replace inc=1 if inc>1 & inc!=. replace lpjt`last'=lp`last'*inc bysort pid _spell: egen licznik=total(lpjt`last') replace jt_recencyR`range'_`jtn'_licznik=licznik if _seq==`last' drop lpjt`last' inc licznik } drop lp`last' totaljtR } forvalues z=1(1)9{ *gen aejt`z'R`range'=. foreach jtn in `jtnorm' { gen aejt`jtn'`z'R`range'=. } } forvalues spl=1/`spell'{ *provide maximum observation scope (max individual trajectory length) sum _seq if _spell==`spl' local longest=r(max) local bound=`longest'-`range'+1 forvalues aa=1/`bound'{ local last=`aa'+`sl'-1 quietly levelsof pid if njobterm>0 & _seq>=`aa' & _seq<=`last' & EN>=`last' & _spell==`spl', local(pidneet) foreach l of local pidneet { display `l' levelsof syear if pid==`l' & njobterm>0 & _seq>=`aa' & _seq<=`last' & _spell==`spl', local(year) local max=r(r) local maxlessone=`max'-1 tokenize "`year'" local sumpid="" forvalues z=1/`maxlessone'{ local start `z' local next=`z'+1 local sum "" forvalues b=`next'/`max'{ local d``b''_``start''=((``b''-``start'')^-1) local sum "`sum' + `d``b''_``start'''" } local sumpid="`sumpid' `sum'" display `l' } replace jtpersist_licznikR`range'=0`sumpid' if pid==`l' & _seq==`last' & _spell==`spl' } } } gen denominator=sum(_n/(`range'-_n)) local den=denominator in `range' replace jtpersistR`range'=jtpersist_licznikR`range'/`den' replace jtpersistR`range'=0 if totaljtR`range'==0 drop denominator /*denominator recencynew*/ gen denominator_recency=sum(_n) local den=denominator_recency in `range' foreach jtn in `jtnorm' { replace jt_recencyR`range'_`jtn'=jt_recencyR`range'_`jtn'_licznik/`den' replace jt_recencyR`range'_`jtn'=0 if totaljtR`range'==0 } drop denominator_recency /*different alpha values*/ local i 1 foreach fa in .1 .2 .3 .4 .5 .6 .7 .8 .9 { *replace aejt`i'R`range'=`fa'*jtpersistR`range'+(1-`fa')*jt_recencyR`range'old foreach jtn in `jtnorm' { replace aejt`jtn'`i'R`range'=`fa'*jtpersistR`range'+(1-`fa')*jt_recencyR`range'_`jtn' } local i=`i'+1 } } drop _spell _end _seq EN ///generating CNPI/// /*The researcher specifies components' weights and the alpha parameter li_weight - low earnings weight nw_weight - non-employment weight jt_weight - job terminations weight alpha - weight attributed to the persistence dimension (in range 1-9, corresponding to 0.1-0.9) jtn - maximum job terminations threshold*/ *define sequence length local seqlength 5 *define specification-specific weights capture program drop _all program define default gen li_weight=0.33 gen nw_weight=0.33 gen jt_weight=0.33 gen alpha=5 gen jtn=3 end program define adjusted gen li_weight=0.25 gen nw_weight=0.25 gen jt_weight=0.5 gen alpha=5 gen jtn=3 end local specification default adjusted macro list foreach sl in `seqlength' { foreach spec in `specification' { `spec' gen cnpi_`spec'R`sl'=. local alpha=alpha in 1 local jtn=jtn in 1 replace cnpi_`spec'R`sl'=li_weight*naci_liperc`alpha'R`sl'+nw_weight*naci_nw`alpha'R`sl'+jt_weight*aejt`jtn'`alpha'R`sl' drop li_weight nw_weight jt_weight alpha jtn } }