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

I have a macrovariable  &var_list which stores a list of integer variable names from the dataset have.

>>%put &var_list.;
id trt grade

Now I want to create a new dataset want where each of the above variable names itself becomes an array. I want macro code that creates a new data set where all the existing variables become arrays of length 4. Like so:

data want;

array id_var{4};

array trt_var{4};

array grade_var{4};

set have;

run;

I have tried the following macro code but it doesn't run correctly. I am trying to iterate through &var_list, concatenate the string "var" to the variable name and also add a {4} at the end to declare each variable as an array. But SAS complains that the keyword "array" is itself an undeclared array variable. It doesn't realise that I am trying to use the keyword array inside the %do macro. Also, what do I do about the {4} in the declaration statement? 

>>%put &var_list.;
id trt grade

%macro getArrayData(dat);

data &dat;

%do i=1 %to 3;

       array %scan(&var_list,&i.)_var {4};

%end;

set have;
run;
%mend getArrayData;

%getArrayData(want);

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

Will it make you feel better if I tell you that you were one semicolon short of a solution? The semicolon immediately after the {4} is basically ending the statement in the macro using the %scan. You need one more to complete the Array statement.

 

%macro getArrayData(dat);

data &dat;
%do i=1 %to 3;
       array %scan(&var_list,&i.)_var {4};     ;
%end;
set have;
run;
%mend getArrayData;

If you ran the original version after setting OPTIONS MPRINT you might notice the generated code was missing the semicolon for the Array.

 

Suggestion: provide your VAR_LIST values as a parameter to the macro. Having a magic macro variable just appear in the code body as in the %scan function means that reusing the code later may fail because you don't remember when/where/how varlist was created.

 

You can also make this more dynamic using

%do i=1 %to %sysfunc(countw(&var_list.));

Sysfunc allows use of data step functions like Countw, which will count the number of space delimited "words", i.e. variables are in the list. So you don't have to figure out why array ABC_var is not created when you add it to Var_list. Or why you get an error when Var_list only has 2 variables.

 

View solution in original post

3 REPLIES 3
ballardw
Super User

Will it make you feel better if I tell you that you were one semicolon short of a solution? The semicolon immediately after the {4} is basically ending the statement in the macro using the %scan. You need one more to complete the Array statement.

 

%macro getArrayData(dat);

data &dat;
%do i=1 %to 3;
       array %scan(&var_list,&i.)_var {4};     ;
%end;
set have;
run;
%mend getArrayData;

If you ran the original version after setting OPTIONS MPRINT you might notice the generated code was missing the semicolon for the Array.

 

Suggestion: provide your VAR_LIST values as a parameter to the macro. Having a magic macro variable just appear in the code body as in the %scan function means that reusing the code later may fail because you don't remember when/where/how varlist was created.

 

You can also make this more dynamic using

%do i=1 %to %sysfunc(countw(&var_list.));

Sysfunc allows use of data step functions like Countw, which will count the number of space delimited "words", i.e. variables are in the list. So you don't have to figure out why array ABC_var is not created when you add it to Var_list. Or why you get an error when Var_list only has 2 variables.

 

PaigeMiller
Diamond | Level 26

Hello, @ballardw I don't understand your answer, and when I run the code without the extra semi-colon that you would insert, I get a clean log.

 

Code:

%let var_list=height weight age;
options mprint;
%macro getArrayData(dat);
data &dat;
    %do i=1 %to 3;
       array %scan(&var_list,&i.)_var {4};
    %end;
    set sashelp.class;
run;
%mend getArrayData;

%getArrayData(want)

 

Log:

 69         %let var_list=height weight age;
 70         options mprint;
 71         %macro getArrayData(dat);
 72         data &dat;
 73         %do i=1 %to 3;
 74                array %scan(&var_list,&i.)_var {4};
 75         %end;
 76         set sashelp.class;
 77         run;
 78         %mend getArrayData;
 79         
 80         %getArrayData(want)
 MPRINT(GETARRAYDATA):   data want;
 MPRINT(GETARRAYDATA):   array height_var {4};
 MPRINT(GETARRAYDATA):   array weight_var {4};
 MPRINT(GETARRAYDATA):   array age_var {4};
 MPRINT(GETARRAYDATA):   set sashelp.class;
 MPRINT(GETARRAYDATA):   run;

 NOTE: There were 19 observations read from the data set SASHELP.CLASS.
 NOTE: The data set WORK.WANT has 19 observations and 17 variables.
 NOTE: DATA statement used (Total process time):
       real time           0.00 seconds
       user cpu time       0.00 seconds
       system cpu time     0.00 seconds
--
Paige Miller
Quentin
Super User

I think you must be misreading your log, or have a problem somewhere else in your SAS session.  As @PaigeMiller showed, if you start a new SAS session and run your code, it works fine.

 

If you have still have the log with the error message, please post it.  You might be misunderstanding the message.

BASUG is hosting free webinars Next up: Don Henderson presenting on using hash functions (not hash tables!) to segment data on June 12. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.

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
  • 3 replies
  • 486 views
  • 2 likes
  • 4 in conversation