BookmarkSubscribeRSS Feed
deleted_user
Not applicable
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;
7 REPLIES 7
Doc_Duke
Rhodochrosite | Level 12
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
deleted_user
Not applicable
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
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
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
Peter_C
Rhodochrosite | Level 12
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
ChrisNZ
Tourmaline | Level 20
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.
deleted_user
Not applicable
it worked
ballardw
Super User
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.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 7 replies
  • 978 views
  • 0 likes
  • 6 in conversation