1
%let p1 = 1;
%let p2 = 2;

I would like to create a data set with the macro variable p1 in the column y1 and the macro variable p2 in the column y2 using a do loop.

Can you help me?

I tried the following:

data test;
    array y(2);
    do i = 1 to 2;
        y(i) = &&p&i;
    end;
run;

which results in the following error:

Syntax error, expecting one of the following: a name, a quoted string,
              a numeric constant, a datetime constant, a missing value, INPUT, PUT.
1
  • 1
    Why are you doing this? It seems likely that your problem can be accomplished without using macro variables like this at all. Are you storing data in macro variables? Commented Mar 24, 2015 at 16:43

1 Answer 1

4

Your i is a dataset variable (not a macro variable) and so cannot be referenced by &i.

You could either change your do loop into a macro %do loop (and wrap in a macro) as this creates a macro variable or use the symget() function to get the macro variable value based on the name of the macro variable as a string.

macro approach:

%macro t;
data test;
    %do i = 1 %to 2;
        y&i = &&p&i;
    %end;
run;
%mend t;
%t;

symget approach:

data test;
    array y(2);
    do i = 1 to 2;
        y(i) = symget("p" || put(i, 1.));
    end;
    drop i;
run;

As the macro is actually creating the statements y# = #; before the data step is executed the array is a bit redundant (unless it is going to refer to variables with other names). I've added a drop statement to the second example it just removes the variable i from the output dataset.


Edit: Discussion of types

Macro variables do not have type, they contain text. SAS treats macro variables the same regardless of what you store in them %let a = 1; and %let a = Cats; are both storing text.

In general macro variables are used to substitute the text you store in them into a SAS program before it executes. In the first example above SAS evaluates the macro statements and resolves the macro variables before the data step is executed, it becomes:

data test;
    y1 = 1;
    y2 = 2;
run;

Used in this way the macro language can automate the writing of tedious or repetitive parts of base SAS programs when you down want to type stuff out by hand. With that in mind consider the situation where you want to pass a string into a dataset variable from a macro variable.

%let p1 = Canada;

The code above would complain about not variable called canada as it would try to resolve y1 = Canada. However, if you wrapped one (but not both) of your assignments in quotes it would work as expected: y&i = "&&p&i"; (or %let p1 = "Canada";).

symget() will create a character variable (length $200.) if used as a new assignment, and it always returns a character value when used for accessing a macro variable.


In general macro variables are not a great method for storing/moving data, they are good for parametrising scripts if you have values that change the way your program works, but if you are moving a lot of data then there is probably a better approach available. As Joe notes above there may be a better way to approach your problem.

Sign up to request clarification or add additional context in comments.

3 Comments

What if the macro variable value is a character i.e. &&p&i resolves to Canada?
Macro variables are all text, there is no concept of a type for macro variables. If you want to put the contents of a macro variable into a character dataset variable wrap it in double quotes: dsVar = "&mVar.", symget returns a character string.
Sorry Reeza, I assumed your comment was a question from OP. I've added a bit on types at the bottom.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.