BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
sascode
Quartz | Level 8

I have a scenario as follows:

 

data have;
input id var1 var2;
datalines;

1  .  5
2  3  4
3  4  5
5  0  6
6  9  8
;
run;

 

%let nvar = 2;

%let v1 = 5; /*Condition for var1*/

%let v2 = 8; /*Condition for var2*/

When i run this array , i am getting error.


data want;
set have;
array var{2} var1 : var&nvar;
array flag{2} flag1-flag&nvar;
do i = 1 to 2;
if var{i} >= 5 then flag{i} = 1;
else flag{i} = 0;
end;
drop i;
run;

This above code run correct but what i need is that instead of var{i} >= 5  i have to replace by var{i} >= &v{i} so i make 

the condition to change as i changes.

However this modification does not work ,saying it can not resolve &v{i}.

Any suggestion ?
Thank you.

1 ACCEPTED SOLUTION

Accepted Solutions
MarkusWeick
Barite | Level 11

Hi @sascode , v1, v2 is not an array but just two macrovariables. If you want to keep them as macrovariables, one way to achieve your goal might be using a macro in your second data step:

data want;
set have;
array var{2} var1 : var&nvar;
array flag{2} flag1-flag&nvar;
%macro steps;
%do i = 1 %to 2;
if var{&i} >= &&v&i then flag{&i} = 1;
else flag{&i} = 0;
%end;
%mend;
%steps;
run;
Please keep the community friendly.
Like posts you agree with or like. Mark helpful answers as “accepted solutions”. Generally have a look at https://communities.sas.com/t5/Getting-Started/tkb-p/community_articles

View solution in original post

8 REPLIES 8
MarkusWeick
Barite | Level 11

Hi @sascode , v1, v2 is not an array but just two macrovariables. If you want to keep them as macrovariables, one way to achieve your goal might be using a macro in your second data step:

data want;
set have;
array var{2} var1 : var&nvar;
array flag{2} flag1-flag&nvar;
%macro steps;
%do i = 1 %to 2;
if var{&i} >= &&v&i then flag{&i} = 1;
else flag{&i} = 0;
%end;
%mend;
%steps;
run;
Please keep the community friendly.
Like posts you agree with or like. Mark helpful answers as “accepted solutions”. Generally have a look at https://communities.sas.com/t5/Getting-Started/tkb-p/community_articles
MarkusWeick
Barite | Level 11

another way might be to define v1 and v2 as (temporary) array:

data have;
input id var1 var2;
datalines;

1  .  5
2  3  4
3  4  5
5  0  6
6  9  8
;
run;

%let nvar = 2;

data want;
set have;
array v{2} _temporary_;
v{1} = 5;
v{2} = 8;
array var{2} var1 : var&nvar;
array flag{2} flag1-flag&nvar;
do i = 1 to 2;
if var{i} >= 5 then flag{i} = 1;
else flag{i} = 0;
end;
drop i;
run;
Please keep the community friendly.
Like posts you agree with or like. Mark helpful answers as “accepted solutions”. Generally have a look at https://communities.sas.com/t5/Getting-Started/tkb-p/community_articles
sascode
Quartz | Level 8
Thank you for suggestion. It worked.
Rick_SAS
SAS Super FREQ

I suggest you put the cutoff values into an array. You can initialize the array by using a predefined set of values, as I have done below. I also used a direct assignment for the flag[i] variable, rather than use an IF-THEN statement.

 

%let nvar = 2;
/* conditions for each var */
%let cutoffVal = (5 8);

data want;
set have;
array var[&nvar] var:;
array cutoff[&nvar] &cutoffVal;
array flag[&nvar];
do i = 1 to &nvar;
   flag[i] = (var[i] >= cutoff[i]);
end;
drop i;
run;

proc print;
run;
sascode
Quartz | Level 8
Hi Rick, Thank you for your suggestion .
It is working .
Tom
Super User Tom
Super User

Let's simplify a little here and avoid conflicting instructions to the SAS compiler.

 

For example you have this statement:

array var{2} var1 : var&nvar;

I think you want the array named VAR to consist of the variables VAR1 and VAR2 .    But the way you are listing the variable names is wrong.   You asked for all variables that start with VAR1 and then added an additional variable named VAR2 to the list.  If you want variables with numeric suffixes from VAR1 to VAR&nvar then use a hyphen and not a colon.

 

Note there is no need to both tell SAS the number of variables and also list the actual variable names.

If you list the variables then you don't need tell SAS the array dimension, it can count.

So either just list the variables.  Or tell SAS the number of variables and let it use the array name as the base for a series of variable names.  These two ways to define the array both define the same array with the same variables in it.

array var var1-var&nvar;
array var[&nvar];

 

You could use THREE arrays here.  One for the variables being checked. One for the flag variables being created. And one for the list of boundary points.

This will work easiest if you have all of the values in one macro variable:

%let values=5 8;
%let nvar=%sysfunc(countw(&values,%str( )));
data want;
  set have;
  array var[&nvar];
  array flag[&nvar];
  array boundary[&nvar] _temporary_ (&values);
  do index = 1 to &nvar;
    flag[index] = var[index] >= boundary[index];
  end;
  drop index;
run;

If you really need to start with multiple macro variables instead of just one macro variable then you can use SYMGETN() to retrieve the appropriate macro variable based on the value of the data step index variable.  So there is no need to define the third array.  Instead just set the flag variable this way:

    flag[index] = var[index] >= symgetn(cats('v',index));

 

sascode
Quartz | Level 8
Hi Tom, what you are saying is true based on the way i brought the probelm here. In my real situation , i had to tell sas the var names in the array because that dataset contains other vars which will be not part of this array.
I appreciate your help.
Tom
Super User Tom
Super User

@sascode wrote:
Hi Tom, what you are saying is true based on the way i brought the probelm here. In my real situation , i had to tell sas the var names in the array because that dataset contains other vars which will be not part of this array.
I appreciate your help.

That makes NO sense at all.  SAS will NOT add random variables into an array.  Only the variables you list

array xx varA VarB some_other_var;
array yy yy1-yy200;

or the ones you imply.

array yy [100] ;

 

Well actually using the : modifier in your variable list, like in your posted code, can make the set of variables included depend on the variables that already exist when the ARRAY statement is compiled.  In that case you can use the DIM() function to find the number of variables that ended up being included in the array.

array var var: ;
do index=1 to dim(var);
....
end;

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 8 replies
  • 416 views
  • 9 likes
  • 4 in conversation