Help using Base SAS procedures

shortening program....

Reply
N/A
Posts: 0

shortening program....

Hi,

I wanted to make my program shorter this is the text that I have, I could I use a do loop and make it shorter. Thanks.
Essentially what I am trying to do is to read in five fields across cpt1 - cpt5 and if the following character variable is there in any of those five fields then it should be coded as one, else it should be zero.

Then I need to add up where all the variables that are coded equal one. where ags = 1 and ags1 = 1 and ags2 = 1 and ags3 = 1, because I want to add up all the number of times that variable equals 1. I only want frequencies and percentages.

Thank you!

If ( cpt1 = 'D9110' or cpt2 = 'D9110' or cpt3 = 'D9110' or cpt4 = 'D9110'
or cpt5 = 'D9110') then ags = 1; else ags = 0;

If ( cpt1 = 'D9230' or cpt2 = 'D9230' or cpt3 = 'D9230' or cpt4 = 'D9230'
or cpt5 = 'D9230') then ags1= 1; else ags1 = 0;

If ( cpt1 = 'D9310' or cpt2 = 'D9310' or cpt3 = 'D9310' or cpt4 = 'D9310'
or cpt5 = 'D9310') then ags2 = 1; else ags2 = 0;

If ( cpt1 = 'D9610' or cpt2 = 'D9610' or cpt3 = 'D9610' or cpt4 = 'D9610'
or cpt5 = 'D9610') then ags3 = 1; else ags3 = 0;
Trusted Advisor
Posts: 2,113

Re: shortening program....

This is a perfect application for ARRAYs. See your own question/posting from two weeks ago
http://support.sas.com/forums/message.jspa?messageID=20617#20617
N/A
Posts: 0

Re: shortening program....

Not sure whether I have understood your problem correctly. I Have tried the following code: This will calculate number of times those variables are "1" and Percentages acorss each observation and across overall observations.

data sample;
input cpt1 $ cpt2 $ cpt3 $ cpt4 $ cpt5$;
cards;
D9110 1100 122 2000 D9110
200 D9610 140 D9110 D9310
3000 D9110 D9230 300 D9110
D9610 3000 7777 7889 D9310
D9110 2333 3333 666 D9610
;
run;

data sample1;
set sample nobs=totobs;
array cpt{5} $20 cpt1-cpt5;
do i=1 to 5;
if cpt(i)='D9110' then do; ags=1; count+1; end; else ags=0;
if cpt(i)='D9230' then do; ags1=1; count+1; end; else ags1=0;
if cpt(i)='D9310' then do; ags2=1; count+1; end; else ags2=0;
if cpt(i)='D9610' then do; ags3=1; count+1; end; else ags3=0;
end;
percent=(count/(totobs*5)*100)||"%";
put _ALL_;
run;

~Sukanya E ~Sukanya E


Message was edited by: Sukanya
Super Contributor
Super Contributor
Posts: 3,174

Re: shortening program....

Also you may want to explore the use of a hash table to load up the list of values to check for, further reducing the SAS program while simplifying the maintenance of your look-up values list.

Scott Barry
SBBWorks, Inc.

Using the Hash Object
http://support.sas.com/documentation/cdl/en/lrcon/61722/HTML/default/a002585310.htm
Valued Guide
Posts: 2,174

Re: shortening program....

it would have been helpful if this were possible[pre] if 'D9110' in( cpt1,cpt2,cpt3,cpt4,cpt5 ) then ags= 1; else ags=0 ;[/pre]however, the in() function expects a list of constants and rejects variables.
Without using hash tables or arrays, one alternative gets IF to search a concatenation of the variables, like:[pre] ags = ^^( FIND( catx( '#', of cpt1-cpt5 ), 'D9110' )) ;
ags1= ^^( FIND( catx( '#', of cpt1-cpt5 ), 'D9230' )) ;
ags2= ^^( FIND( catx( '#', of cpt1-cpt5 ), 'D9310' )) ;
ags3= ^^( FIND( catx( '#', of cpt1-cpt5 ), 'D9610' )) ;[/pre]
This returns a 1/0 for ags if D9110 is in any of those columns CPT1-5, ags1 for D9230, ags2 for D9310, etc.

I've tested it and it worked

if you need a more generalised approach, please provide some more detail.

does this help?

PeterC
PROC Star
Posts: 1,555

Re: shortening program....

You can use Peter's test and the fact that sas can do character loops (in data steps at least, if not in macros):

[pre]
data sample;
input cpt1 $ cpt2 $ cpt3 $ cpt4 $ cpt5$;
do i='D9110','D9310','D9610';
ags + ^^( FIND( catx( '#', of cpt1-cpt5 ), i ) );
end;
put ags=;
cards;
D9110 1100 122 2000 D9110
200 D9610 140 D9110 D9310
3000 D9110 D9230 300 D9110
D9610 3000 7777 7889 D9310
D9110 2333 3333 666 D9610
run;
[/pre]

This way you have all in one place:
- a single list for all test values (in the loop)
- a single list for all test variables (in the concatenation list)
and you can massage the sums or derive ratios any way you want in the data step.
N/A
Posts: 0

Re: shortening program....

it worked
Super User
Posts: 10,466

Re: shortening program....

Taking advantage of SAS boolean behavior of returning 1 for true and 0 for false:

ags =( cpt1 = 'D9110' ) + ( cpt2 = 'D9110' ) + ( cpt3 = 'D9110' ) + ( cpt4 = 'D9110') + ( cpt5 = 'D9110');

By extension a total count could be generated by including all of the pairs of variable and value if desired. This is not intuitively obvious and should be documented when using this trick for those that haven't seen it. This sometimes runs a bit faster than lots of explicit if-then statements as well.
Ask a Question
Discussion stats
  • 7 replies
  • 161 views
  • 0 likes
  • 6 in conversation