DATA Step, Macro, Functions and more

Dynamic variable name

Accepted Solution Solved
Reply
Contributor
Posts: 49
Accepted Solution

Dynamic variable name

Hi ,
I create this data set:

data temp;
 do i=1 to 5;
    a1=999;
    a2=999;
    a3=999;
    ...
   a10 =999;
   output;
 end;
run;


is there a better solution that create a second do-loop inside the first do-loop?

for example like this:

data temp;
 do i=1 to 10;
  do j=1 to 10;
call symput("index",j);
a&index=999; end;
output;
end; run;

The last example, doesn't work, because it doesn't recognize the index variable.

Is there some solution?

 


Accepted Solutions
Solution
‎03-14-2017 05:37 AM
Super User
Posts: 6,963

Re: Dynamic variable name

data temp;
array vars {*} a1-a10;
do i = 1 to 5;
  do j = 1 to dim(vars);
    vars{j} = 999;
  end;
end;
drop j;
run;
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers

View solution in original post


All Replies
Solution
‎03-14-2017 05:37 AM
Super User
Posts: 6,963

Re: Dynamic variable name

data temp;
array vars {*} a1-a10;
do i = 1 to 5;
  do j = 1 to dim(vars);
    vars{j} = 999;
  end;
end;
drop j;
run;
---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 5,090

Re: Dynamic variable name

SInce your new variables are constant, a better solution would not nest loops:

 

data want;

retain a1-a10 999;

do i=1 to 5;

   output;

end;

run;

 

To answer your original question, no there is no solution.  SAS does not let you change what "a&index" resolves to, as the DATA step executes.

Contributor
Posts: 49

Re: Dynamic variable name

thanks!!!

Super User
Posts: 17,898

Re: Dynamic variable name

@window please mark the question as answered.

Valued Guide
Posts: 505

Re: Dynamic variable name

A slightly more interesting problem;

Generating 10 observations with a random number of variables

Minimum number of variables is 1(a1) max is 5(a1-a5)

This is trivial in IML or R.

  n <- as.integer(5*runif(1)) +1;
  runif(n);

> n <- as.integer(5*runif(1)) +1;
  runif(n);
[1] 0.13442659 0.07485726 0.22734428 0.84948492
>

HAVE a random number between 1 and 5
========================================

    n=int(5*uniform(5739)) + 1;

  Note N could be meta data

WANT  Suppose the random n is 3
===============================

Up to 40 obs from want total obs=10

Obs       A1         A2         A3

  1    0.39041    0.51861    0.19275
  2    0.13243    0.54758    0.86705
  3    0.89960    0.18865    0.46915
  4    0.62604    0.15337    0.34970
  5    0.50958    0.16918    0.61778
  6    0.81300    0.88339    0.36657
  7    0.79296    0.56760    0.66014
  8    0.37525    0.19073    0.66443
  9    0.70009    0.31034    0.72677
 10    0.56065    0.93989    0.41765

SOLUTION
========

data _null_;
  n=int(5*uniform(5739)) + 1;
  call symputx('dim',put(n,3.));
   rc=dosubl('
      data want(drop=rec i);
        array a[&dim.] a1-a&dim;
        do rec=1 to 10;
           do i=1 to &dim;
              a[i]=uniform(5733);
           end;
           output;
        end;
      run;quit;
   ');
  stop;
run;quit;
☑ This topic is solved.

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

Discussion stats
  • 5 replies
  • 227 views
  • 4 likes
  • 5 in conversation