BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Steelers_In_DC
Barite | Level 11

I am attaching some code, I have a very large amount of if-then statements to flag different statuses.  I'm only copy and pasting so it should be easy enough, I'm just curious if there is something I can do to neaten up the code and make it more efficient.  There will be thousands of rows if I keep up like this.  I have 20 flags to label 3 tables and a very large amount of 'if's.  If you can look at the attachment and suggest a different way to write this I would appreciate it.

Thanks,

Mark

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

You can use multiple characters to map to one using proc format:

proc format;

invalue $ groups

    'Alfred', 'Alice', 'William' = 'Group1'

    'Barbara', 'Carol', 'Thomas' = 'Group2'

    'John', 'Joyce', 'Judy' = 'Group3'

    other='Group4';

run;

data class;

    set sashelp.class;

    group=input(name, $groups.);

run;

If you have the mappings in a dataset you can use CNTLIN to read them in as well, you don't have to type them all out.

You can specify character ranges as follows, but you'll want to make sure you fully understand how that works:

proc format;

invalue $ groups

    'A'-'A~' = 'Group1'

    'B' - 'B~' = 'Group2'

    'John', 'Joyce', 'Judy' = 'Group3'

    other='Group4';

run;

data class;

    set sashelp.class;

    group=input(name, $groups.);

run;

View solution in original post

12 REPLIES 12
Reeza
Super User

Proc Format.

Especially if you'll be reusing the groupings.

I'm a fan of the paper: Proc Format: Not just anther pretty face...you can easily find it online.

Steelers_In_DC
Barite | Level 11

Is there any way to do something like this:

proc format;

     value $ hcc19fmt ('

249.00','

249.01','

250.00','

250.01','

250.02','

250.03','

V58.67'

) = '19';

run;

I see ranges being used when it's a number that I'm listing for the format but not a list of characters.  Do I have to put ='19' after every row in the proc format?

Reeza
Super User

You can use multiple characters to map to one using proc format:

proc format;

invalue $ groups

    'Alfred', 'Alice', 'William' = 'Group1'

    'Barbara', 'Carol', 'Thomas' = 'Group2'

    'John', 'Joyce', 'Judy' = 'Group3'

    other='Group4';

run;

data class;

    set sashelp.class;

    group=input(name, $groups.);

run;

If you have the mappings in a dataset you can use CNTLIN to read them in as well, you don't have to type them all out.

You can specify character ranges as follows, but you'll want to make sure you fully understand how that works:

proc format;

invalue $ groups

    'A'-'A~' = 'Group1'

    'B' - 'B~' = 'Group2'

    'John', 'Joyce', 'Judy' = 'Group3'

    other='Group4';

run;

data class;

    set sashelp.class;

    group=input(name, $groups.);

run;

Steelers_In_DC
Barite | Level 11

That's awesome, great help.  One last question, here's what I have:

proc format;

     invalue $ testfmt

'249.00','249.01'='19';

run;

data test1;

set test;

HCC_CODE = input(dx_1_cd,$testfmt.);

run;

I only want HCC_CODE to generate IF the value equals the format.  I hope that makes sense.  In this example I only want HCC_CODE to populate if the value is going to be '19', and be blank otherwise.

Is that possible?

MumSquared
Calcite | Level 5

proc format;

     invalue $ testfmt

'249.00','249.01'='19'

other=''

;

run;

Marina
Calcite | Level 5

You can try the following:

data test1;

set test;

if indexw(input(dx_1_cd,$testfmt.),'19') ne 0 then

HCC_CODE = input(dx_1_cd,$testfmt.);

run;

Steelers_In_DC
Barite | Level 11

I have another problem,  I wanted to do this on 4 variables, that seems to present another issue, there is another table that I want to do this on 18 variables.  I'm not sure this will be the right path to take in this situation.

Your thoughts?

Reeza
Super User

Perfect path to take if you're applying it to multiple variables because you can just

new_var=input(old_var, $fmt_name.) on each one instead of recoding all of them.

Steelers_In_DC
Barite | Level 11

Is this what you mean?  I've attached what I have that seems to get the desired results but I'm thinking it's a remedial way to get to the desired result:

Steelers_In_DC
Barite | Level 11

The previous attachment had typos, this is correct.

Reeza
Super User

I think your first parts correct, I think the second part is a different question.

I'd suggest reposting that as a new question.

My guess is you could just use the whichc function instead or an array but you need to expand it.

Marina
Calcite | Level 5

Use array.

data test1;
length hcc_code $4.;
set test;

hcc_code="";


* you will need to list all 18 variables;

array dx_cd (18) dx_1_cd dx_2_cd ... dx_18_cd;

do i=1 to 18;

if hcc_code = "" then do;

if indexw(input(dx_cd(i),$testfmt.),'80') ne 0
then HCC_CODE = input(dx_cd(i),$testfmt.);
end;
end;
drop i;
run;

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 12 replies
  • 2139 views
  • 4 likes
  • 4 in conversation