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

Hello programmers,

 

I am trying to change the numbers in my variables to another set of numbers. I am using the if and then statement but it seems to be longer as i would be changing the values of about 50 variables. I am not an advanced sas user. Is there are way i can do this task faster with if --the statement or any other easier method? Any help will be appreciated.

My codes are something like this.

data one; set fooddata;
if xa= 0 then xa1= 0;
if xa= 1 then xa1= 0.033;
if xa=2 then xa1=0.067;
if xa=3 then xa1= 0.143;
if xa=4 then xa1=0.429;
if xa=5 then xa1=0.857;
if xa=6 then xa1= 1;
if xa=7 then xa1=2.5;
if xa=8 then xa1=4.5;
if xa=9 then xa1=7;
run;
1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

Keep your conversion data in a dataset, give it a proper structure for proc format, create a format, and use that:

data lookup;
input start label;
fmtname = 'convert';
type = 'I';
datalines;
0 0
1 0.033
2 0.067
3 0.143
4 0.429
5 0.857
6 1
7 2.5
8 4.5
9 7
;

proc format cntlin=lookup;
run;

data have;
input xa;
datalines;
0
1
2
3
4
5
6
7
8
9
;

data want;
set have;
xa1 = input(xa,convert.);
run;

If you only have a single if/then structure like this, use the data step select() statement:

data one;
set fooddata;
select (a);
  when (0) xa1 = 0;
  when (1) xa1 = 0.033;
  .....
  otherwise xa1 = -99; * or any other value that indicates "N/A";
end;
run;

View solution in original post

9 REPLIES 9
Kurt_Bremser
Super User

Keep your conversion data in a dataset, give it a proper structure for proc format, create a format, and use that:

data lookup;
input start label;
fmtname = 'convert';
type = 'I';
datalines;
0 0
1 0.033
2 0.067
3 0.143
4 0.429
5 0.857
6 1
7 2.5
8 4.5
9 7
;

proc format cntlin=lookup;
run;

data have;
input xa;
datalines;
0
1
2
3
4
5
6
7
8
9
;

data want;
set have;
xa1 = input(xa,convert.);
run;

If you only have a single if/then structure like this, use the data step select() statement:

data one;
set fooddata;
select (a);
  when (0) xa1 = 0;
  when (1) xa1 = 0.033;
  .....
  otherwise xa1 = -99; * or any other value that indicates "N/A";
end;
run;
ChuksManuel
Pyrite | Level 9

Thanks! One question. My original variable were in numerals. Would this keep them all numerical?

Kurt_Bremser
Super User

Since I used the input() function with a numeric informat, the result will be numeric. Just test the code I posted.


@ChuksManuel wrote:

Thanks! One question. My original variable were in numerals. Would this keep them all numerical?


 

KachiM
Rhodochrosite | Level 12

If there is functional relationship between XA and XA1 then you can write one statement like:

xa1 = F(xa) where F is the function.

When there is no relationship you can hold XA1 Values in a _temporary_ array_ which reduces the steps.

data one;
   set fooddata
   array x[0:9] _temporary_ (0 0.033 0.067 0.143 0.429 0.857 1 2.5 4.5 7);
   do xa = 0 to 9;
      xa1 = x[xa];
   end;
run;
ChuksManuel
Pyrite | Level 9

Thank you. Can i also use this your format for  multiple variables?

Eg can i do something like this:

data one;
   set fooddata
   array x[0:9] _temporary_ (0 0.033 0.067 0.143 0.429 0.857 1 2.5 4.5 7);
   do xa = 0 to 9;
      xa1 = x[xa];
   end; run;
do xb = 0 to 9; xb1 = x[xb]; end; run;
do xc = 0 to 9; xc1 = x[xc]; end; run;
do xd = 0 to 9; xd1 = x[xd]; end; run;

 

KachiM
Rhodochrosite | Level 12

Yes. You can.

Kurt_Bremser
Super User

And if you want to fill your array from a dataset, you can also do that:

data have;
input xa;
datalines;
0
1
2
3
4
5
6
7
8
9
;

data values;
input value;
datalines;
0
0.033
0.067
0.143
0.429
0.857
1
2.5
4.5
7
;

proc sql noprint;
select nobs - 1 into :nobs trimmed from dictionary.tables
where libname = 'WORK' and memname = 'VALUES';
quit;

data want;
set have;
if _n_ = 1
then do;
  array x{0:&nobs.} _temporary_;
  do _i = 1 to dim(x);
    set values point=_i;
    x{_i-1} = value;
  end;
end;
xa1 = x{xa};
drop _i value;
run;

or (Maxim 51) use a hash:

data lookup;
input start label;
fmtname = 'convert';
type = 'I';
datalines;
0 0
1 0.033
2 0.067
3 0.143
4 0.429
5 0.857
6 1
7 2.5
8 4.5
9 7
;

data have;
input xa;
datalines;
0
1
2
3
4
5
6
7
8
9
;

data want;
set have;
if _n_ = 1
then do;
  declare hash h (dataset:"lookup");
  h.definekey("start");
  h.definedata("label");
  h.definedone();
  call missing(label);
end;
start = xa;
if not h.find() then xa1 = label;
drop start label;
run;

 

gamotte
Rhodochrosite | Level 12

Hello,

 

proc format;
    value food
    0=0
    1=0.033
    2=0.067
    3=0.143
    4=0.429
    5=0.857
    6=1
    7=2.5
    8=4.5
    9=7
    ;
run;

data two;
    set fooddata;
    xa1=input(put(xa,food.),best.);
run;

data three;
    set fooddata;
    xa1=input(scan("0 0.033 0.067 0.143 0.429 0.857 1 2.5 4.5 7", xa+1), best.);
run;
Kurt_Bremser
Super User

You can make it easier by defining an informat:

proc format;
    invalue food
    0=0
    1=0.033
    2=0.067
    3=0.143
    4=0.429
    5=0.857
    6=1
    7=2.5
    8=4.5
    9=7
    ;
run;

data two;
    set fooddata;
    xa1=input(xa,food.);
run;

hackathon24-white-horiz.png

The 2025 SAS Hackathon has begun!

It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.

Latest Updates

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

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
  • 9 replies
  • 2117 views
  • 6 likes
  • 4 in conversation