Wednesday, August 27, 2008

Concatenate a set of Numbers

-
Some time a programmer has to concatenate a set of Numbers. For example an inclusion criteria listing may demand the display of “Number of inclusion criteria’s (1-7) present in the dataset” as column. In the dataset given below, “NO equals the subjects who has not satisfied inclusion criteria". To display this, the following code will concatenate the (inclusion criteria) numbers to bring the inclusion criteria not satisfied per subject as 1, 2, 3, 4, 5, and 6.

SUBJECT AGE IN1 IN2 IN3 -IN4 IN5 -IN6 IN7
00001111 --43- YES YES YES .----YES YES YES
00001222 --20- NO NO -NO -NO NO -NO -.
-
(inclusion criteria not satisfied is stored as a Numeric value 2 with format NO)

data incl1;
length no $ 50;
set incl;
retain no;
array a[7] in1 - in7;
no = '';
*no is the variable to HOLD THE VALUE;
do i=1 to 7;
*loop is RUN TILL i=8;
if a[i]=2 then do;
*if loop satisfies the condition "NO";
if no eq '' then no=trim(left(put(i,best.)));
*then ASSIGN 1 to no;
else if no ne '' then no=trim(left(no))II', 'IItrim(left(put(i,best.)));
*now CONCATENATE no:1 with 2;
end;
end;
run;


Output for this subject 00001222 will be:
-
1, 2, 3, 4, 5, 6
-

Tuesday, August 26, 2008

Simple way of % Display!

-
***** DISPLAY OF PERCENTAGE IN PROC REPORT ******;

data new;
input cnt deno;
datalines;
53 54
9 -10
12 12
2 ---9
1 ---5

;
run;

data new1;
set new;
-
if cnt ne . and deno ne . then per = (cnt*100)/deno;
*cnt:COUNT, deno:DENOMINATOR, per:PERCENTAGE;
-
if (per ne 0 and per ne .) and per ne 100 then
cper = right(put(cnt,3.))IIright(put('('trim(left(put(per,4.1)))'%)',8.));
else if per eq 100 then
cper = right(put(cnt,3.))IIright(put('('trim(left(put(per,4.)))'%)',8.));
-
run;
proc print; run;

-
Together it takes a TOTAL of 11 spaces for displaying: xx (xx.x%)

3. -=> is for COUNT xxx
4.1
=> is for PERCENTAGE xx.x / 4. => is for % (if 100)
xxx
+3
=> is for SPECIAL CHARACTERS
(%)
+1
=> is for a space in b/w COUNT & PERCENTAGE
-

Thursday, August 21, 2008

Display 'No Observations'

-
Code for Displaying 'No Observations':
-
***** FINAL IS THE DATASET WITH 0 OBSERVATION *****;
-
proc sql noprint;
select count (*) into : n from final;
run;
-
*if observation is not equal to 0 set final, else if the observation is equal to 0 then display no observation in the first column (usubjid);
-
data disp;
length usubjid $20;
if &n^ = 0 then set final;
else usubjid = 'No Observations';
run;
-

Thursday, August 14, 2008

Wanna underline a header?

-
proc report data= ds split='^' nowd headline headskip spacing=1 missing;
by descending treat;
-
column (rest1 rest2 ("_First Value_" (fval1 fval2)) ("_Second Value_" (sval1 sval2 sval3)) rest3 rest4);
-
define rest1 / order-- width = 22 left-- "rest of the values (1)" spacing = 0;
define rest2 / order-- width = 22 left-- "rest of the values (2)";
define fval1 / display width = 22 center "first:-value (1)";
define fval2 / display width = 22 center "first:-value (2)";
define sval1 / display width = 22 center "second value (1)";
define sval2 / display width = 22 center "second value (2)";
define sval3 / display width = 22 center "second value (3)";
define rest3 / display width = 22 center "rest of the values (3)";
define rest4 / display width = 22 center "rest of the values (4)";
-
break after rest1 / skip;
footnote1 "&under";
footnote2 "Required footnote for display.";
-
run;

The above example: shows the use of "_" to underline the header(First Value & Second Value). These are the variables (fval1 fval2, sval1 sval2 sval3) which will get displayed under the header.
-

Saturday, August 2, 2008

Generating missing values in a Table

-
USUBJID VISITNUMBER
10011001 1
10011001 7
10011002 1
10011003 1

In the above example, the usubjid (10011002 and 10011003) has visitnumber 7 missing. The proc transpose statement helps in generating these missing values.

** PROC TRANSPOSE FOR GENERATING MISSING VALUES **;

proc transpose data = d1 out = d2 prefix = v;
by usubjid treatnc ;
id vis;
*vis is a character variable which contains visitnumber (1,7);
var vala valb valc vald vale valf valg valh vali valj;
run;

When transposed the data becomes:
USUBJID V1 V7
10011001 -0 --0
10011002 -0 --''
10011003 -0 --''

** RE(cursive) TRANSPOSE: TO BRING THE DATA BACK TO ITS SHAPE **;

proc transpose data = d2 out = d3;
by usubjid treatnc ;
id _name_;
*all values vala - valj becomes identifier again;
var v1 v7;
run;

The data would now look like:
USUBJID _name_ vala
10011001 -v1-------0
10011001 -v7-------0
10011002 -v1-------0
10011002 -v7-------''
10011003 -v1-------0
10011003 -v7-------''

proc sort data = d3;
by usubjid treatnc _name_;
run;

** BRING THE VARIABLES ONE AFTER THE OTHER FOR FREQ **;

proc transpose data = d3(rename = (_name_ = name)) out = d4;
by usubjid treatnc name;
var vala valb valc vald vale valf valg valh vali valj;
run;
-

Friday, August 1, 2008

Why two proc reports?????

-
When proc report had more columns that do not fit in one page, I tried using two different proc reports. However the disadvantage of using two different proc report is, the report one: gets generated first…
-
To solve this problem, define a variable with ID. This ID variable appears at the left of every page of a report. Hence the use of ID ensures that you can identify each row of the report when the report contains more columns that will not fit in one page.
-
In the example given below, the variables (param & grade) act as an id variable. In the first page, these variables (param & grade) appear with other variables (pv1 pv2 pv3 pv4 pv5 pv6). Same way in the next page, it appears with the rest of the variables (pv7 - total).
-
options nocenter;
proc report data=final headline headskip nowd missing spacing=1 split ='*';
columns (param grade pv1 pv2 pv3 pv4 pv5 pv6 pv7 pv8 pv9 pv10 pv11 total);
-
define param- / order id left width = 30 "Parameter" spacing = 0 flow;
define grade-- / order id left width = 7- "Grade";
define pv1-----/---------. left width = 10 "Visit 1*(N=&vis1)";
define pv2-----/---------. left width = 10 "Visit 2*(N=&vis2)";
define pv3-----/---------. left width = 10 "Visit 3*(N=&vis3)";
define pv4-----/---------. left width = 10 "Visit 4*(N=&vis4)";
define pv5-----/---------. left width = 10 "Visit 5*(N=&vis5)";
define pv6-----/---------. left width = 10 "Visit 6*(N=&vis6)";
define pv7-----/---------. left width = 10 "Visit 7*(N=&vis7)";
define pv8-----/---------. left width = 10 "Visit 8*(N=&vis8)";
define pv9-----/---------. left width = 10 "Visit 9*(N=&vis9)";
define pv10----/--------.. left width = 10 "Visit 10*(N=&vis10)";
define pv11----/--------.. left width = 10 "Visit 11*(N=&vis11)";
define total-----/-------... left width = 10 "Overall*(N=&total)";
-
break after param / skip;
footnote1 "&under";
run;
-