BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
tjain90
Fluorite | Level 6

Hi team,

 

I am trying to create dynamic macro variable with names in sequence and values as observation.

I have used below code but it is not working. Request you to please review:

data ab;
input id$;
cards;
A1
A2
A3
;
run;

 

%macro rowToMacroVariable(dataSetName,variableName,macroVariableName);

data &dataSetName;

set &dataSetName;

call symput(&macroVariableName||left(_n_),&variableName);

run;

 

%mend;

%rowToMacroVariable(ab,id,id);

%rowToMacroVariable(ab,id,TJ);

 

Now it should have created below macro variabls:

id1 A1

id2 A2

id3 A3

TJ1 A1

TJ2 A2

TJ3 A3

 

but it is not working 😞

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

If the only remaining issue is making these macro variables global, switch from CALL SYMPUT to CALL SYMPUTX.  It supports a third argument, that can simply be specified as "G" to make the macro variables global.

 

call symputx("macro_variable_name", "macro_variable_value", "G");

View solution in original post

11 REPLIES 11
gamotte
Rhodochrosite | Level 12

Hello,

 

You forgot to enclose &macroVariableName with double quotes as the first argument to call symput is a string.

 

%macro rowToMacroVariable(dataSetName,variableName,macroVariableName);
data &dataSetName;
	set &dataSetName;
	call symput("&macroVariableName"||left(_n_),&variableName);
run;
%mend;
tjain90
Fluorite | Level 6

Thanks gamotte,

 

But its not working 😞

Kurt_Bremser
Super User

Since you create your macro variables in a macro, they are created local to the macro and won't exist in the global table when the macro has finished.

Why do you want to put such a rather simple operation in a macro?

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Well, first off, as always, why.  Macro is not a replacement for Base SAS programming, it is just a find/replace mechanism.  In 99% of the cases I have seen people using macro it is because they don't know Base SAS well enough and try to patch it up, which ends up with messy, unmanigable code.  So the question is what are you trying to do with these macro variables - there are many methods of working with data, and even metadata which require no macro code (arrays, normalisation, variable lists, sashelp tables etc.) all designed to make your coding simple.  

The reason I mention the above is that from your code its clear you don't understand macro programming.  Let me start by suggesting you read up on Variable Scope.  Creating macros witihin the macro means that they are Local to the macro, and not available outside the macro.  Secondly your code needs a few tweaks:

data _null_;
set ab;
call symput("id"||strip(put(_n_,best.)),id);
run;

This code will work, note you don't need to create a dataset (data xyz;) to do this, as the data already exists.  Secondly the you need to quote the macro variable to get it to resolve in the above i just put "id", but it would be "&Macrovariable"||...

This will create a whole set of macro variables based on the data, and they will be Global to the area where you run it.

 

However that is all by the by, this is really not the way to proceed.

tjain90
Fluorite | Level 6

Hi RW9,

 

Thanks for such a good explanation. I agree with _null_ even i have used this in programming but while posting it on community i have designed a seperate example. Even my code was working fine with this way but I am not able to make this id1 variable as global. So can you please let me know where i am missing ?

 

Now why I have used this in macro is because in my scripts we have 10 separate datasets and I need to create seperate global macro variables that are already used in further programming. I know we can optimize these things but its an level 2 task so please understand somebody's situation before commenting on there knowledge skills or why they have used those thing.

 

I agree that you must be having wide knowldge and I am happy to have people like you on SAS community because this is how we can learn and enhance our skills on SAS 🙂

 

 

RW9
Diamond | Level 26 RW9
Diamond | Level 26

You have hilighted the issue yourself then "we have 10 separate datasets" - if your able to generalise your code, then these datasets will be similar if not the same, structurally.  Thus put those 10 datasets together on under the other, use indsname= to get filename if you need to, then process the data as one file with by groups.

 

You can't define macros witihin a macro as they will be local, unless you explicitly set them as global beforehand - hence you would need to hard code either in the main program as %global, or define them in the main program as I gave earlier.  Even a change to the thinking would mitigate this, rather than have these in a macro, define them in the main program, and have your macro calls just do the function.  

Kurt_Bremser
Super User

If you need to keep lists of things from step to step, it's usually better to store them in datasets and use those to create dynamic code or formats or similar. It depends on what you need to do with those lists further on.

Another way to store lists in macro variables is

%macro rowToMacroVariable(dataSetName,variableName,macroVariableName);
%global &macrovariablename;
proc sql noprint;
select &variablename into :&macrovariablename separated by ','
from &datasetname
;
quit;
%mend;

%rowToMacroVariable(sashelp.class,name,test);

%put &test;

Now you have one global macro variable that contains all values.

 

Kurt_Bremser
Super User

And keep in mind that all those macro variables have to be kept in memory, and you can run out of RAM space. Or macro variables with lists can exceed the maximum size of macro variables. Datasets are virtually infinite in comparison.

Astounding
PROC Star

If the only remaining issue is making these macro variables global, switch from CALL SYMPUT to CALL SYMPUTX.  It supports a third argument, that can simply be specified as "G" to make the macro variables global.

 

call symputx("macro_variable_name", "macro_variable_value", "G");

tjain90
Fluorite | Level 6

Thanks Astounding ! It works ... Thanks a lot :smileyhappy

rogerjdeangelis
Barite | Level 11
Related but does not answer ops question

Defining a large number of global macro variables;

inspired by
https://goo.gl/YRzFGM
https://communities.sas.com/t5/Base-SAS-Programming/Create-Dynamic-macro-variable-with-Call-Symput/m-p/336912

HAVE
====

Up to 40 obs from sashelp.class total obs=19

Obs    NAME       SEX    AGE    HEIGHT    WEIGHT

  1    Alfred      M      14     69.0      112.5

  2    Alice       F      13     56.5       84.0  (turn into macro variables)

  3    Barbara     F      13     65.3       98.0
  4    Carol       F      14     62.8      102.5
  5    Henry       M      14     63.5      102.5
  6    James       M      12     57.3       83.0
  7    Jane        F      12     59.8       84.5
  8    Janet       F      15     62.5      112.5
  9    Jeffrey     M      13     62.5       84.0
 10    John        M      12     59.0       99.5
 11    Joyce       F      11     51.3       50.5
 12    Judy        F      14     64.3       90.0
 13    Louise      F      12     56.3       77.0
 14    Mary        F      15     66.5      112.0
 15    Philip      M      16     72.0      150.0
 16    Robert      M      12     64.8      128.0
 17    Ronald      M      15     67.0      133.0
 18    Thomas      M      11     57.5       85.0
 19    William     M      15     66.5      112.0


WANT macro variables NAME SEX AGE HEIGHT WEIGHT
===============================================

NAME        = Alice
SEX         = F
AGE         = 13
HEIGHT      = 56.5
WEIGHT      = 84

FULL SOLUTION
=============

%symdel name sex age height weight; * just in case you rerun;
%let dsid = %sysfunc(open(sashelp.class(where=(name='Alice')),i));
%syscall    set(dsid);
%let rc   =%sysfunc(fetchobs(&dsid,1));
%let rc   =%sysfunc(close(&dsid));


%put
   &=NAME
   &=SEX
   &=AGE
   &=HEIGHT
   &=WEIGHT
   ;

NAME        = Alice
SEX         = F
AGE         = 13
HEIGHT      = 56.5
WEIGHT      = 84

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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
  • 11 replies
  • 7626 views
  • 2 likes
  • 6 in conversation