Here is my data set:
data aaa;
infile cards missover;
input no a1 $ b1 c1 a2 $ b2 c2 a3 $ b3 c3;
cards;
1 x1 1 1 z1 2 1 y1 1 2
2 x2 1 2 y2 1 2
3 x3 2 2
;
run;
proc format;
value b1fmt 1="a" 2="b";
value c1fmt 1="m" 2="f";
run;
Here is what I want to get:
data set:
no a1 b1 c1
1 x1 a m
1 z1 b m
1 y1 a f
2 x2 a f
2 y2 a f
3 x3 b f
Following is my code:
%macro new;
Data _1;
array num{9,3} ;
if _n_=1 then do z=1 to 3;
retain i;
set aaa;
array avar{*} no b1 c1 b2 c2 b3 c3;
%let S=3;
%let Four=4;
%DO k=1%TO 3;
i=i+1;
num{i,1}=avar(1);
num{i,3}=avar(&S);
num{i,4}=avar(&Four);
S=%EVAL(&S+3);
Four=%EVAL(&Four+3);
%END;
end;
run;
%mend;
%new;
the error is :Array subscript out of range at line 3 column 45
The other problem is a1 a2 a3 is not numeric. So here in the code I did not put a1,a2,a3. How could I solve this problem?
Also I have not use format to convert the value to 'a,b,m,f'. But I know how to convert them in the last step. So At first I need to solve above problems.
How could I do?
Here's one way:
data aaa;
infile cards missover;
input no a1 $ b1 c1 a2 $ b2 c2 a3 $ b3 c3;
cards;
1 x1 1 1 z1 2 1 y1 1 2
2 x2 1 2 y2 1 2
3 x3 2 2
;
run;
proc format;
value b_fmt 1="a" 2="b";
value c_fmt 1="m" 2="f";
run;
data bbb;
set aaa;
array bc(3,2) b1 c1 b2 c2 b3 c3;
do i=1 to 3;
a=vvaluex("a"||put(i, 2. -l));
b=bc(i,1);
b_format=put(b, b_fmt.);
c=bc(i,2);
c_format=put(c, c_fmt.);
if not missing(a) then output;
end;
drop a1-a3 b1-b3 c1-c3 i;
run;
Is that a simplified form of your data? Do you expect more occurrences of a/b/c?
In that simple form there are easier methods.
Your out of bounds is coming because you define the array
array num{9,3} ; which says in effect each row has 3 elements
but you use:
num{i,1}=avar(1);
num{i,3}=avar(&S);
num{i,4}=avar(&Four); < the 4 is larger than the 3 defined above.
You may have meant to use
num{i,1}=avar(1);
num{i,2}=avar(&S);
num{i,3}=avar(&Four);
The DATA step variable S is not the Same as the macro variable &S.
I recommend that you also remove all of the macro variables within the data step as I don't think any of them are doing what you want. They should all be data step variables.
Also the loop
%DO k=1%TO 3;
will just generate the code within it 3 times without change and also doesn't need to be a macro loop at all.
now I have changed the array. But it still says 'Array subscript out of range'
You may want to show your complete new code.
%macro new;
Data _1;
array num{9,3} ;
if _n_=1 then do z=1 to 3;
retain i;
set aaa;
array avar{*} no b1 c1 b2 c2 b3 c3;
%let S=3;
%let Four=4;
%DO k=1%TO 3;
i=i+1;
num{i,1}=avar(1);
num{i,2}=avar(&S);
num{i,3}=avar(&Four);
S=%EVAL(&S+3);
Four=%EVAL(&Four+3);
%END;
end;
run;
%mend;
%new;
It is my new code...But that error still occurs
Here's one way:
data aaa;
infile cards missover;
input no a1 $ b1 c1 a2 $ b2 c2 a3 $ b3 c3;
cards;
1 x1 1 1 z1 2 1 y1 1 2
2 x2 1 2 y2 1 2
3 x3 2 2
;
run;
proc format;
value b_fmt 1="a" 2="b";
value c_fmt 1="m" 2="f";
run;
data bbb;
set aaa;
array bc(3,2) b1 c1 b2 c2 b3 c3;
do i=1 to 3;
a=vvaluex("a"||put(i, 2. -l));
b=bc(i,1);
b_format=put(b, b_fmt.);
c=bc(i,2);
c_format=put(c, c_fmt.);
if not missing(a) then output;
end;
drop a1-a3 b1-b3 c1-c3 i;
run;
oh...thank you! That is what I want to get.
I have an another small question.
put(i, 2. -l)
Here....'-l' why do you use this? What is the meaning of it? Could you tell me?
It tells SAS to left align the number when it does the conversion. If the number is less than the format length you'll end up with extra spaces in the new variable, ie a1 would be "a 1" otherwise.
data have;
set sashelp.class;
age_char="a"||put(age, 8.);
age_char2="a"||put(age, 8. -l);
run;
proc print data=have (obs=4);
var age_char age_char2;
run;
Thank you!
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.