Thursday, April 5, 2007

Correspondence between genmod and logistic

I have been exploring this for my work. I found some guidance here. I am including some details here.
data drug;
input drug$ x r n;
cards;
A .1 1 10
A .23 2 12
A .67 1 9
B .2 3 13
B .3 4 15
B .45 5 16
B .78 5 13
C .04 0 10
C .15 0 11
C .56 1 12
C .7 2 12
D .34 5 10
D .6 5 9
D .7 8 10
E .2 12 20
E .34 15 20
E .56 13 15
E .8 17 20
;

proc genmod data=drug;
class drug;
model r/n=x drug / dist=binomial link=logit;
estimate 'A vs E' drug 1 0 0 0 -1/exp;
run;

proc logistic data=drug;
class drug/param=ref;
model r/n=x drug;
run;


/* generates dummy variables coded as follows
drug A 1 0 0 0
B 0 1 0 0
C 0 0 1 0
D 0 0 0 1
E 0 0 0 0 */


proc logistic data=drug;
class drug;
model r/n=x drug;
run;


/* generates dummy variables coded as follows

Class Value Design Variables

drug A 1 0 0 0
B 0 1 0 0
C 0 0 1 0
D 0 0 0 1
E -1 -1 -1 -1
*/



However, the results (Odds ratio) are going to be the same. Accessible help on writing contrast statements is here.

Monday, April 2, 2007

Proc tabulate/proc report

I have been trying to learn these new tools.

Here is a pdf with clear instructions and uses of both.

Some available options are ACROSS, ANALYSIS, CENTER, COLOR, COMPUTED, CSS, CV, DESCENDING, DISPLAY, EXCLUSIVE, F, FLOW, FORMAT, GROUP, ID, ITEMHELP, LEFT, MAX, MEAN, MEDIAN, MIN, MISSING, N, NMISS, NOPRINT, NOZERO, ORDER, P1, P10, P25, P5, P50, P75, P90, P95, P99, PAGE, PCTN, PCTSUM, PRELOADFMT, PRT, Q1, Q3, QRANGE, RANGE, RIGHT, SPACING, STD, STDERR, STYLE, SUM, SUMWGT, T, USS, VAR, WEIGHT, WGT, WIDTH.

Sunday, April 1, 2007

Macro to output only relevant results to ods

/** following macro runs logistic regression and outputs the results from only the relevant variables to the html file. In this case, I am running regression with various variables but keeping age in all the models. Age is not the variable of interest. */

%macro jncht(dataname,var1);
title "Age and sex adjusted &var1";
ods select OddsRatio ParameterEstimates;
proc logistic data=&dataname ;
model jncht=&var1 ahage ahsex ;
ods output OddsRatios=orrr;
ods output ParameterEstimates=Param;
run;

data param;
set param;
drop DF Estimate StdErr;
run;

proc sort;
by variable;

data orrr;
set orrr;
variable=effect;
drop effect;
proc sort;
by variable;
run;

data new;
merge param orrr;
by variable;
run;
%let cuts=%SUBSTR(&var1,1,4);

ods html select all;
title " age and sex adjusted &var1";
proc print data=new;
var variable OddsRatioEst LowerCL UpperCL ProbChiSq;
where variable like "%NRBQUOTE(%)&cuts%NRBQUOTE(%)";
run;
ods html exclude all;
proc datasets;
delete param orrr new;
%mend ;

Invocation of this macro.
/*include the following statement in the beginning of the program*/
ods html file ="%sysfunc
(reverse(%sysfunc(substr(%sysfunc(reverse(%sysfunc(reverse(%scan(%sysfunc(reverse(%sysfunc(getoption(sysin)))),1,/))))),5)))).html"
STYLE=MINIMAL;

data...;
.
.
.;
%jncht(trott1,&wstci_)

/*Where &wstci_ is a macro variable and equals 'wstci1 wstci2 wstci3'. */

Wildcards in different situations

This is a broad area to handle in one posting but here are few links that I found useful:

Matching with a wildcard using Perl regular expression A possible problem with this method is inability of this method to handle macro variables.

Matching with like and percent (%) It is used in the next post.

Using wildcards to read many files into one SAS data set

Saturday, March 31, 2007

Interactions in logistic regression using proc genmod

I have been trying to do logistic regression with interactions. Since this would have required a lot of dummy coding in proc logistic, I used proc genmod.

proc genmod;
class ahsex(ref=first) ah66a qtype &smok_ &alco_;
model jncht= wstrs wstrs*ahsex ahsex ah66a ahage &smok_ &alco_ WLTHINDF QTYPE/ error=bin link=logit type3;
run;

Another way to encode the interaction term and the main effects would be using "
wstrs|ahsex". This equals "wstrs wstrs*ahsex ahsex".
The ref option could be replaced with (ref="1") . Specifying more than one REF= variable option in the CLASS statement could be a problem.

In case you are wondering,
&smok_ refer to the macro variable I created earlier in the code as follows:
%let &sm0k= smok1 smok2 smok3 smokm;



Wednesday, March 21, 2007

Find the number of observations in the dataset

I work with huge daatsets - more than 100,000 observations followed up for 20 years. In the process of merging datasets read in through macros, I have lost track of the number of observations.

Following code gives the number of observations in the dataset - dataname:
%let dsid=%sysfunc(open(dataname));
%let num=%sysfunc(attrn(&dsid,nobs));
%let rc=%sysfunc(close(&dsid));
%put There are &num observations in dataset dataname.;


This is from the SAS samples.

Monday, March 19, 2007

Centering around mean or calculating standard deviation

data original;
set original;
var=1; /*creates a constant variable*/

/*creates means ,standard deviation and no of obs and puts them in dataset called starwars which has only one observation*/

proc means data=original;
var ahbmi ah98 ah99 ah9900 ;

OUTPUT OUT=starwars MEAN=avbmi av98 av99 STD=stbmi stah98 stah99 N=nbmi n98 n99 ;
run;


data starwars;

set starwars;
var=1; /*creates constant variable for merging with original dataset*/
drop _freq_ _type_;

data original ;
merge original starwars;
by var;

centerbmi=ahbmi-avbmi; /*centers bmi*/

bmisd=ahbmi/stbmi;/*creates variable to do regression with each unit increment of standard deviation*/



/**************Alternate way***************************/
data original;
set original;
proc means data=original;
var ahbmi ah98 ah99 ah9900 hipcr;
OUTPUT OUT=starwars MEAN=avbmi av98 av99 STD=stbmi stah98 stah99 N=nbmi n98 n99 ;
run;
/*creates means ,standard deviation and no of obs and puts them in dataset called starwars which has only one observation*/


data _null_;
set starwars;
call symput("bmibar",avbmi); /*creates macro var bmibar that has the value of avbmi*/
call symput("a98bar",av98);
call symput("a99bar",av99);
call symput("s98",stah98);
call symput("s99",stah99);
call symput("sbmi",stbmi);
run;

%put mean of bmi is &bmibar;
%put mean of ah98 is &a98bar;
%put mean of ah99 is &a99bar;

data original;
set original;
ceterbmi=avbmi-&bmibar;
/*centers bmi*/
bmisd=ahbmi/&sbmi;
/*creates variable to do regression with each unit increment of standard deviation */
run;

/**************Alternate way***************************/
/**************Standardized Coefficients***************************/

proc reg;
model dependent= independent1 independent2 independent3/stb;
run;

This gives standardized estimates i.e. when all variables in the
models (including dependent variable) are standardized to zero
mean and unit variance. Each coefficient indicates the number
of SD change in the dependent variable with a SD change in the
independent variable holding constant all other variables constant.
This is useful to compare the relative importance of independent
variables independent of the scales.