***SAS code for Asymmetric Fixed Effects Models for Panel Data ***Paul D. Allison ***31 December 2018 ***Note: proc glm and proc logistic, used below, cannot produce robust standard errors; ***Data sets can be downloaded at https://statisticalhorizons.com/resources/data-sets ***Section 2; data nlsydiff; set my.nlsy; antidiff=anti2-anti1; selfdiff=self2-self1; povdiff=pov2-pov1; selfpos=selfdiff*(selfdiff>0); selfneg=-selfdiff*(selfdiff<0); povpos=povdiff*(povdiff>0); povneg=-povdiff*(povdiff<0); run; ***Table 1; proc freq data=nlsydiff; table povdiff; run; ***Table 2; proc reg data=nlsydiff; model antidiff=selfdiff povdiff; run; ***Section 3; ***Table 3; proc reg data=nlsydiff; model antidiff=selfpos selfneg povpos povneg; test selfpos=-selfneg; test povpos=-povneg; run; ***Section 4; data wagediff; set my.wagerate; id=_n_; array lwagea (*) lwage1-lwage5; array mara (*) mar1-mar5; array urba (*) urb1-urb5; array edua (*) edu1-edu5; do t=1 to 5; lwage=lwagea(t); mar=mara(t); urb=urba(t); edu=edua(t); if t>1 then do; wagediff=lwagea(t)-lwagea(t-1); mardiff=mara(t)-mara(t-1); urbdiff=urba(t)-urba(t-1); edudiff=edua(t)-edua(t-1); marpos=mardiff*(mardiff>0); marneg=-mardiff*(mardiff<0); urbpos=urbdiff*(urbdiff>0); urbneg=-urbdiff*(urbdiff<0); t3=(t=3); t4=(t=4); t5=(t=5); end; output; end; run; ***Table 4; proc glm data=wagediff; absorb id; class t; model lwage=mar edu urb t /solution ; run; ***Table 5, left panel; proc reg data=wagediff; model wagediff=mardiff edudiff urbdiff t3 t4 t5 / hcc ; run; ***Table 5, right panel; proc glm data=wagediff; absorb id; model wagediff=mardiff edudiff urbdiff t3 t4 t5 ; run; ***Table 6, left panel; proc mixed data=wagediff empirical; class t; model wagediff=mardiff edudiff urbdiff t / solution; repeated t / subject=id type=unr; run; ***Table 6, right panel; proc mixed data=wagediff empirical; class t; model wagediff=mardiff edudiff urbdiff t / solution; repeated t / subject=id type=toep(2); run; ***Fully constrained GLS; proc mixed data=wagediff empirical; class t; model wagediff=mardiff edudiff urbdiff t / solution; repeated t / subject=id type=toep(2); parms (-.5) (.2)/ ratios hold=1; /* The PARMS statement constrains the ratio of the covariance to the residual variance to be -.5 */ run; ***Section 5; ***Table 7; proc freq data=wagediff; table mardiff urbdiff; run; ***Table 8; proc mixed data=wagediff empirical; class t; model wagediff=marpos marneg edudiff urbpos urbneg t / solution cl; repeated t / subject=id type=toep(2); parms (-.5) (.2)/ ratios hold=1; contrast 'martest' marpos 1 marneg 1; contrast 'urbtest' urbpos 1 urbneg 1; run; ***Section 6; data wagecum; set my.wagerate; id=_n_; array mar (*) mar1-mar5; array urb (*) urb1-urb5; array edu (*) edu1-edu5; array lwage(*) lwage1-lwage5; array mardiff (*) mardiff1-mardiff5; array urbdiff (*) urbdiff1-urbdiff5; array marpos (*) marpos1-marpos5; array marneg (*) marneg1-marneg5; array urbpos (*) urbpos1-urbpos5; array urbneg (*) urbneg1-urbneg5; t=1; marposcum=0; marnegcum=0; urbposcum=0; urbnegcum=0; mart=mar1; urbt=urb1; edut=edu1; lwaget=lwage1; output; do t=2 to 5; mart=mar(t); urbt=urb(t); edut=edu(t); lwaget=lwage(t); mardiff(t)=mar(t)-mar(t-1); urbdiff(t)=urb(t)-urb(t-1); marpos(t)=mardiff(t)*(mardiff(t)>=0); marneg(t)=-mardiff(t)*(mardiff(t)<0); urbpos(t)=urbdiff(t)*(urbdiff(t)>=0); urbneg(t)=-urbdiff(t)*(urbdiff(t)<0); marposcum=marpos(t)+marposcum; marnegcum=marneg(t)+marnegcum; urbposcum=urbpos(t)+urbposcum; urbnegcum=urbneg(t)+urbnegcum; output; end; run; proc glm data=wagecum; absorb id; class t; model lwaget=marposcum marnegcum urbposcum urbnegcum edut t / solution; contrast 'mar test' marposcum 1 marnegcum 1; contrast 'urb test' urbposcum 1 urbnegcum 1; run; ***Section 7; ***Table 9; proc logistic data=my.teenyrs5 desc; class year / param=ref; model pov = mother spouse inschool hours year; strata id ; run; ***Table 10; data teencum; set my.teenpov; array mothera (*) mother1-mother5; array spouse (*) spouse1-spouse5; array inschool (*) inschool1-inschool5; array hours (*) hours1-hours5; array spousediff (*) spousediff1-spousediff5; array hoursdiff (*) hoursdiff1-hoursdiff5; array inschooldiff (*) inschooldiff1-inschooldiff5; array pova (*) pov1-pov5; array spousepos (*) spousepos1-spousepos5; array spouseneg (*) spouseneg1-spouseneg5; array inschoolpos (*) inschoolpos1-inschoolpos5; array inschoolneg (*) inschoolneg1-inschoolneg5; array hourspos (*) hourspos1-hourspos5; array hoursneg (*) hoursneg1-hoursneg5; t=1; spouseposcum=0; spousenegcum=0; inschoolposcum=0; inschoolnegcum=0; hoursposcum=0; hoursnegcum=0; pov=pov1; mother=mother1; output; do t=2 to 5; pov=pova(t); mother=mothera(t); spousediff(t)=spouse(t)-spouse(t-1); inschooldiff(t)=inschool(t)-inschool(t-1); hoursdiff(t)=hours(t)-hours(t-1); spousepos(t)=spousediff(t)*(spousediff(t)>0); spouseneg(t)=-spousediff(t)*(spousediff(t)<0); inschoolpos(t)=inschooldiff(t)*(inschooldiff(t)>0); inschoolneg(t)=-inschooldiff(t)*(inschooldiff(t)<0); hourspos(t)=hoursdiff(t)*(hoursdiff(t)>0); hoursneg(t)=-hoursdiff(t)*(hoursdiff(t)<0); spouseposcum=spousepos(t)+spouseposcum; spousenegcum=spouseneg(t)+spousenegcum; inschoolposcum=inschoolpos(t)+inschoolposcum; inschoolnegcum=inschoolneg(t)+inschoolnegcum; hoursposcum=hourspos(t)+hoursposcum; hoursnegcum=hoursneg(t)+hoursnegcum; output; end; run; proc logistic data=teencum desc; class t / param=ref; model pov = mother spouseposcum spousenegcum inschoolposcum inschoolnegcum hoursposcum hoursnegcum t; strata id ; test spouseposcum=-spousenegcum; test hoursposcum=-hoursnegcum; test inschoolposcum=-inschoolnegcum; run;