/********************************************************************* Heather J. Hoffman Purpose: The pseudo-likelihood main program used to generate the likelihood function accounting for left-censored and missing observations. *********************************************************************/ /*-------------------------------------------------------------------Note: In order to run this program, the macros defined in the SAS file "PART 1 - MACRO DEFNS" must be compiled and stored in the location specified below. --------------------------------------------------------------------*/ libname mymacs "C:\sasmacros"; libname soln "C:\DEQ Rslts"; options mstored=yes sasmstore=mymacs; /*-------------------------------------------------------------------Global Macro Variables: Values must be supplied by the user PATHNAME = location of Excel workbook not enclosed in quotes SHEETNAME = sheet name within Excel workbook LIBNAME = name of SAS library where SAS data set is stored DATASET = name of SAS data set being created NSUBJ = number of subjects in dataset NUMVARS = number of variables in dataset VARLIST = actual names of variables to be analyzed (each name should be enclosed in quotes, and names should be separated by a single space) Example: 'x1' 'x2' 'x3' --------------------------------------------------------------------*/ %let pathname=C:\VDEQ Data.xls; %let sheetname=CONCENTRATION; %let libname=work; %let dataset=here; %let nsubj=184; %let numvars=5; %let varlist='Cu' 'Pb' 'Zn' 'Ca' 'Mg'; *If necessary, input dataset from Excel with user-supplied info; proc import out= &libname..&dataset datafile= "&pathname" dbms=EXCEL2000 REPLACE; range="&sheetname.$"; getnames=YES; RUN; *Call macro creates renames creates %UserInput; that: new SAS dataset MYDATA, variables VAR1-VARp, and censor indicator variables CEN1-CENp; /*-------------------------------------------------------------------DATA STEP: MYDATA PURPOSE: To take log-transformations of lognormal variable values to normalize them. --------------------------------------------------------------------*/ data mydata; set mydata; %LogTrans; run; /*-------------------------------------------------------------------DATA STEP: MOREMYDATA PURPOSE: To create dummy variables for left-censoring, to be used in the LIFEREG procedure. --------------------------------------------------------------------*/ data moremydata; set mydata (keep=%Vars(&numvars) %PrintpTimes(cen)); %Dummy(&numvars); run; *Call LIFEREG for each variable to get starting values; %NumVar(&numvars); /*-------------------------------------------------------------------DATA STEP: IMPMYDATA PURPOSE: To create data set with one-half LOD imputed for nondetects. Remember we subtract log(2) since this is the log-transformed data. --------------------------------------------------------------------*/ data impmydata; set mydata; %Impute(&numvars); run; *Save correlations in CORR dataset to be used as starting values; proc corr data=impmydata outp=corr; var %Vars(&numvars); run; *Prepare data set containing starting values; %GetInits; /*-------------------------------------------------------------------MAIN PROGRAM: Part 1 VARIABLE DIRECTORY: Y = (NR x NC) data matrix NR = number of rows/observations in y NC = number of columns/variables in y NCEN = (NR x 1) vector of # of cen vars for each obsn NOBS = (NR x 1) vector of # of obs vars for each obsn NOC = (NR x 1) vector of # of nonmiss vars for each obsn VARS = (NR x NC) sorted variable index matrix (sorted as C) LIKE = value of log-likelihood function MU = (NC x 1) estimated mean vector SIG = (NC x NC) estimated (co)variance matrix RHO = (NC x NC) estimated correlation matrix X = (1 x NC) row vector of parameter starting values CON = (2 x NC) matrix of parameter constraints L = final log-likelihood value based on parameter values selected by optimization procedure --------------------------------------------------------------------*/ proc iml; use mydata; read all var {%PrintpTimes(var)} into fully; read all var {%PrintpTimes(cen)} into fullc; nr=nrow(fully); nc=2; /*** Define function to be used in Newton-Raphson procedure ***/ start FullLike(x) global(nr, nc, y, vars, nobs, ncen, noc); like=0; count=1; p=2; newp=2*p-1; mu=J(p,1,0); sig=J(p,p,1); rho=J(p,p,1); do i=1 to newp by 2; mu[count,1]=x[i]; inci=i+1; sig[count,count]=x[inci]; count=count+1; end; count=2*p+1; decp=p-1; do i=1 to decp; inci=i+1; do j=inci to p; rho[i,j]=x[count]; sig[i,j]=rho[i,j]*sqrt(sig[i,i]*sig[j,j]); sig[j,i]=sig[i,j]; rho[j,i]=rho[i,j]; count=count+1; end; end; %MainProg; return(like); finish FullLike; /*** End function to be used in Newton-Raphson optimization ***/ use try; read all var _num_ into startvals; startvals=round(startvals, 0.001); use pearson; read all var _num_ into rhostartvals; numinits=&numvars*(&numvars+3)/2; startvec=J(numinits,1,0); count=1; do i=1 to 2*&numvars-1 by 2; startvec[i,1]=startvals[count,1]; startvec[i+1,1]=startvals[count,2]##2; count=count+1; end; count=2*&numvars+1; decreasep=&numvars-1; do i=1 to decreasep; increasei=i+1; do j=increasei to &numvars; startvec[count,1]=rhostartvals[i,j]; count=count+1; end; end; print startvec; con={. 1e-10 . 1e-10 -1, . . . . 1}; bivit=1; bivmeans=J(&numvars,&numvars,0); bivvars=J(&numvars,&numvars,0); bivcorr=J(&numvars*(&numvars-1)/2,1,0); do frst=1 to &numvars-1; do sec=frst+1 to &numvars; x=startvec[2*frst-1:2*frst,1]` ||startvec[2*sec-1:2*sec,1]` ||startvec[2*&numvars+bivit,1]; y=fully[,frst]||fully[,sec]; c=fullc[,frst]||fullc[,sec]; %BubbleSort; nobs=obs; ncen=cen; noc=nobs+ncen; call nlpnra(rc, xres, "FullLike", x, , con); print rc, x, xres; L=FullLike(xres); print bivit L; bivmeans[frst,sec]=xres[1,1]; bivmeans[sec,frst]=xres[1,3]; bivvars[frst,sec]=xres[1,2]; bivvars[sec,frst]=xres[1,4]; bivcorr[bivit,1]=xres[1,5]; bivit=bivit+1; end; end; print bivmeans bivvars; avgmeans=bivmeans[,+]/(&numvars-1); avgvars=bivvars[,+]/(&numvars-1); print avgmeans avgvars bivcorr; theres=J(2*&numvars,1,0); count=1; do i=1 to 2*&numvars-1 by 2; theres[i,1]=avgmeans[count,1]; theres[i+1,1]=avgvars[count,1]; count=count+1; end; theres=theres//bivcorr; theres=theres`; print theres; create xfinres from theres; append from theres; quit; /* data soln.xfinres; set xfinres; run; */