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

Hi,

 

I am trying to create macro variables to identify how many variables start with "GROUP" in a number of datasets.

 

For each dataset I want a macro variable called Tree_Group&i. where &i. relates to the dataset. Does anyone know how to achieve this? I know you cant use a macro variable in symputx when creating a new macro so unsure how to proceed as the below wont work!

 

%macro Test(i);
proc contents
     data = Test_&i.
          out = data_info&i.(where=(upcase(substr(name,1,5)="GROUP"))
               keep = name);
run;

data _NULL_;
set data_info&i. nobs=GROUP_NUMBER;
call symputx(Tree_Group&i,GROUP_NUMBER);
run;

%mend;
%Test(1);
%Test(2);
1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26

Try this:

 

call symputx("Tree_Group&i",GROUP_NUMBER);

 

If the data sets have the same name except for consecutive numbering at the end of the data set name, there's really no need to do this via macros. PROC FREQ working on SASHELP.VCOLUMN ought to produce this without macros and without loops.

--
Paige Miller

View solution in original post

5 REPLIES 5
PaigeMiller
Diamond | Level 26

Try this:

 

call symputx("Tree_Group&i",GROUP_NUMBER);

 

If the data sets have the same name except for consecutive numbering at the end of the data set name, there's really no need to do this via macros. PROC FREQ working on SASHELP.VCOLUMN ought to produce this without macros and without loops.

--
Paige Miller
Tom
Super User Tom
Super User

 I know you cant use a macro variable in symputx when creating a new macro so unsure how to proceed as the below wont work!

That is just a flat out false statement.

 

This line in your code:

call symputx(Tree_Group&i,GROUP_NUMBER);

Is looking for a variable named TREE_GROUP1 or TREE_GROUP2 that contains the name of the macro variable you want to create.

If instead you want it to create a macro variable named TREE_GROUP1 or TREE_GROUP2 then you need to pass that STRING to the function call.

call symputx("Tree_Group&i",GROUP_NUMBER);

 

Quentin
Super User

Hi,

 

Note there are some other issues in your macro as well.  There is a parentheses problem, and you will also need to add the "G" parameter to CALL SYMPUTX assuming your goal is to make a global macro variable:

 

 

%macro Test(i);
proc contents
     data = Test_&i.
          out = data_info&i.(where=(upcase(substr(name,1,5))="GROUP")  /*fixed parentheses*/
               keep = name);
run;

data _NULL_;
set data_info&i. nobs=GROUP_NUMBER;
call symputx("Tree_Group&i",GROUP_NUMBER,"G");    /*added quotes to first argument, and third argument G to make global macro var*/
stop ;  /*you only need to read one record*/ 
run;

%mend;

data test_1  ;
  array foo{*} Group1 Grouper NotGroup ;
run ;

%Test(1)

%put &Tree_group1 ;

 

 

Note if you're going to build a macro, and are interested in macro programming, you might think about options for making this a more general macro, e.g. below macro uses your core approach, but allows user to input the dataset name, variable name prefix, and name of the global macro variable to be created:

 

%macro CountVars
  (data=
  ,prefix=
  ,macvar=
   );

proc contents 
  data = &data (keep=&prefix: )
  out = __MyVars(keep = name) 
  noprint
;
run;

data _NULL_;
  set __MyVars nobs=GROUP_NUMBER;
  call symputx("&macvar",GROUP_NUMBER,"G");   
  stop ;  
run;

proc delete data=__MyVars ;
run ;

%mend;

%CountVars
  (data=Test_1
  ,prefix=Group
  ,macvar=GroupCount1
   )

%put &groupcount1 ;

 

Another macro solution would be to write a function-style macro %VarList which allows a user to input a dataset and will return a list of the variables found.  Such macros exist in user group papers in lexjansen.com, they are intermediate / advanced macro coding.  If you have the macro, and then you could find the count with just:

 

%put There are %sysfunc(countw(%varlist(mydata(keep=Group: )))) variables in work.mydata that have a variable name starting with GROUP ;

There is complexity to writing a VARLIST macro that allows you to specify keep/drop options in the usual SAS way, but once you have such a function-style macro, it becomes handy in many situations.

 

 

The Boston Area SAS Users Group is hosting free webinars!
Next up: Joe Madden & Joseph Henry present Putting Power into the Hands of the Programmer with SAS Viya Workbench on Wednesday Nov 6.
Register now at https://www.basug.org/events.
xxformat_com
Barite | Level 11

Alternative solution: use dictionaries - Here is an example which only create the macro variable is there is at least one group variable. You can extend it with all the cases with a merge...

 

data one;
    group_A=1;
    group_B=1;
    tmp=1;
run;

data two;
    group=1;
run;

data three;
    tmp=1;
run;


proc sql;
    create table ref as
    select distinct memname, count(*) as cnt_group
    from dictionary.columns
    where upcase(libname)='WORK' and
          upcase(name) like 'GROUP%'
    group by memname;
quit;


data _null_;
    set ref;
    call symputx (cats(memname,_n_),cnt_group);
run;
Tom
Super User Tom
Super User

Why?

What is the purpose of stuffing so much information into macro variables?

What are you going to do with the macro variables?

If you want a list of the variables for a given dataset why not put the list into one macro variable?

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 706 views
  • 1 like
  • 5 in conversation