Help with DO LOOP on second part of variables name

Accepted Solution Solved
Reply
Super Contributor
Posts: 371
Accepted Solution

Help with DO LOOP on second part of variables name

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;


Accepted Solutions
Solution
‎12-16-2014 04:02 PM
Super Contributor
Posts: 371

Re: Help with DO LOOP on second part of variables name

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;

View solution in original post


All Replies
Grand Advisor
Posts: 17,331

Re: Help with DO LOOP on second part of variables name

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.

Esteemed Advisor
Esteemed Advisor
Posts: 7,203

Re: Help with DO LOOP on second part of variables name

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.

Super Contributor
Posts: 371

Re: Help with DO LOOP on second part of variables name

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

Grand Advisor
Posts: 17,331

Re: Help with DO LOOP on second part of variables name

Do loops and arrays go hand in hand. Look into vname and vvaluex functions if your interested in variable name m

Esteemed Advisor
Esteemed Advisor
Posts: 7,203

Re: Help with DO LOOP on second part of variables name

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;

Super Contributor
Posts: 305

Re: Help with DO LOOP on second part of variables name

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)

Respected Advisor
Posts: 4,969

Re: Help with DO LOOP on second part of variables name

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?

Super Contributor
Posts: 371

Re: Help with DO LOOP on second part of variables name

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;

Grand Advisor
Posts: 17,331

Re: Help with DO LOOP on second part of variables name

Still not clear.

Super Contributor
Posts: 371

Re: Help with DO LOOP on second part of variables name

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;

Solution
‎12-16-2014 04:02 PM
Super Contributor
Posts: 371

Re: Help with DO LOOP on second part of variables name

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;

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 11 replies
  • 603 views
  • 7 likes
  • 5 in conversation