Hi Everyone,
The below codes repeatedly analyze var_1x var_2d var_3e.... and create new variable exit_1x exit_2d exit_3d.... respectively.
I want to make a DO LOOP such as:
Do secondpart from 1x TO 3e;
Could you please help me with this?
Thank you,
HHC
data have;
input value var_1x var_2d var_3e var_4x;
datalines;
0 2 3 4 5
2 2 2 1 4
4 2 3 1 2
5 3 6 7 8
;run;
data have; set have;
id=_n_;run;
%let secondpart=1x;
data have;
drop i found v2 id2;
set have nobs=totalobs;
i+1;
do j=i to totalobs until (found=1);
set have (keep=value id rename=(value=v2 id=id2)) point=j;
if v2>var_&secondpart then do;
found=1;
exit_&secondpart=id2;
end;
end;
run;
%let secondpart=2d;
data have;
drop i found v2 id2;
set have nobs=totalobs;
i+1;
do j=i to totalobs until (found=1);
set have (keep=value id rename=(value=v2 id=id2)) point=j;
if v2>var_&secondpart then do;
found=1;
exit_&secondpart=id2;
end;
end;
run;
%let secondpart=3e;
data have;
drop i found v2 id2;
set have nobs=totalobs;
i+1;
do j=i to totalobs until (found=1);
set have (keep=value id rename=(value=v2 id=id2)) point=j;
if v2>var_&secondpart then do;
found=1;
exit_&secondpart=id2;
end;
end;
run;
I think it works for me.
HHC
data have;
input value var_1x var_2d var_3e var_4x;
datalines;
0 2 3 4 5
2 2 2 1 4
4 2 3 1 2
5 3 6 7 8
;run;
data have; set have;
id=_n_;run;
%let oldvar= 1x 2d 3e 4x;
%macro test;
%do i=1 %to %sysfunc(countw(&oldvar));
%let secondpart=%scan(&oldvar,&i);
data have;
drop i found v2 id2;
set have nobs=totalobs;
i+1;
do j=i to totalobs until (found=1);
set have (keep=value id rename=(value=v2 id=id2)) point=j;
if v2>var_&secondpart then do;
found=1;
exit_&secondpart=id2;
end;
end;
run;
%end;
%mend;
%test;
Bit at a loss as to why arrays won't work instead of macros.
Can you post the expected output based on data and/or logic for output.
Hi,
Totally agree with Reeza, post what you want as output and how to get there. Even running the program it makes no sense. Definitely investigate arrays or lag() function. Alternatively consider normalizing your data, i.e. have it vertically rather than across.
Thank you for asking,
One reason I like Do loop is that part of the name of the variable (_1x) will be included in the name of outcome variables.
Moreover, the actual code body is complicate so I find that doing DO LOOP gives me more flexibility.
HHC
Do loops and arrays go hand in hand. Look into vname and vvaluex functions if your interested in variable name m
But then you are merely creating a rod for your own back so to speak. Most of the functions have parameters to allow you to work with arrays of variables, but this requires a numeric suffix. So by avoiding using the numeric suffix you are losing a whole load of functionality? Please post example test data and required output (and what the required output is meant to be) and we can suggest alternatives. An example is generating the code which will shrink yours significantly (however based on required output, there may be (and probably is) better ways):
data _null_;
do I="1x","2d","3e";
call execute('data have;
drop i found v2 id2;
set have nobs=totalobs;
i+1;
do j=i to totalobs until (found=1);
set have (keep=value id rename=(value=v2 id=id2)) point=j;
if v2>var_'||strip(I)||' then do;
found=1;
exit_'||strip(I)||'=id2;
end;
end;
run;');
end;
run;
Hello,
Reeza and RW9 provided a different and better approach. in case you still want to stick with the DO LOOP:
data have;
input value var_1x var_2d var_3e var_4x;
datalines;
0 2 3 4 5
2 2 2 1 4
4 2 3 1 2
5 3 6 7 8
;
run;
data have; set have;
id=_n_;
run;
%macro calc (part);
%let i=1;
%let varcur=%scan(&part,&i);
%do %while(&varcur ne );
data have;
drop i found v2 id2;
set have nobs=totalobs;
i+1;
do j=i to totalobs until (found=1);
set have (keep=value id rename=(value=v2 id=id2)) point=j;
if v2>&varcur then do;
found=1;
exit_&varcur=id2;
end;
end;
run;
%let i=%eval(&i+1);
%let varcur=%scan(&part,&i);
%end;
%mend calc;
%calc(var_1x var_2d var_3e)
I agree with Reeza. Here's a little help using arrays:
data want;
set have nobs=totalobs;
array vars {3} var_1x var_2d var_3e;
array exits {3} exit_1x exit_2d exit_3e;
do _i_=1 to 3;
found=0;
do j=1 to totalobs until (found=1);
set have (keep=value id rename=(value=v2 id=id2)) point=j;
if v2 > vars{_i_} then do;
found=1;
exits{_i_} = id2;
end;
end;
end;
drop id2 v2;
run;
You get everything in one data set, with no macro language. Is that the eventual result you are looking for?
Hi Everyone,
Thank you for helping.
I guess I did not make my case clearer at the beginning.
The reason I want to do DO Loop is to accomplish the below kind of Macro
I do not have SAS with me right now to check if LoKo method works.
HHC
%MACRO doloop;
%do start=0 %to 2;
%do end=0 %to 4 %by 1;
%do secondpart **** %to ******;
*-------------------------;
Code body
*-------------------------;
%end;
%end;
%end;
%mend;
Still not clear.
My idea is to run the analysis for each of the variable
var_1x | var_2d | var_3e | var_4x; |
say: start=0 and end=0 and var_1x
start=0 and end=0 and var_2d
start=0 and end=0 and var_3e |
....
.... to
start=2 and end=4 and var_3e;
start=2 and end=4 and var_4x; |
Thank you for asking.
HHC
%MACRO doloop;
%do start=0 %to 2;
%do end=0 %to 4 %by 1;
%do secondpart from 1x, 2d, 3e, 4x;
*-------------------------;
Code body
*-------------------------;
%end;
%end;
%end;
%mend;
I think it works for me.
HHC
data have;
input value var_1x var_2d var_3e var_4x;
datalines;
0 2 3 4 5
2 2 2 1 4
4 2 3 1 2
5 3 6 7 8
;run;
data have; set have;
id=_n_;run;
%let oldvar= 1x 2d 3e 4x;
%macro test;
%do i=1 %to %sysfunc(countw(&oldvar));
%let secondpart=%scan(&oldvar,&i);
data have;
drop i found v2 id2;
set have nobs=totalobs;
i+1;
do j=i to totalobs until (found=1);
set have (keep=value id rename=(value=v2 id=id2)) point=j;
if v2>var_&secondpart then do;
found=1;
exit_&secondpart=id2;
end;
end;
run;
%end;
%mend;
%test;
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 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.