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;
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
  • 2244 views
  • 6 likes
  • 4 in conversation