turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- SAS Procedures
- /
- shortening program....

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

05-19-2009 06:22 PM

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;

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;

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to deleted_user

05-20-2009 09:43 AM

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

http://support.sas.com/forums/message.jspa?messageID=20617#20617

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to deleted_user

05-20-2009 05:16 PM

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

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to deleted_user

05-20-2009 05:28 PM

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

Scott Barry

SBBWorks, Inc.

Using the Hash Object

http://support.sas.com/documentation/cdl/en/lrcon/61722/HTML/default/a002585310.htm

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to deleted_user

05-21-2009 10:47 AM

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

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

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Peter_C

05-27-2009 06:24 PM

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.

[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.

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to ChrisNZ

05-28-2009 02:38 AM

it worked

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

Posted in reply to deleted_user

05-27-2009 05:23 PM

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.

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.