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;
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;
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;
Thanks! One question. My original variable were in numerals. Would this keep them all numerical?
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?
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;
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;
Yes. You can.
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;
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;
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;
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.
Ready to level-up your skills? Choose your own adventure.