BookmarkSubscribeRSS Feed
hmdabbas
Calcite | Level 5

Greetings,

I have a data step that calculates the maximum number of days. Then I use this code works perfectly and capture that value to be used in an array:

data _null_;

  set have;

  call symput("xbarmac",max_number);

run;

%put &xbarmac;

The Problem: 

I can't figure out how to use the value to replace the 3200 in the array below. The max number captured for example is 3562, I would like to replace the 3200 string with 3562.

Before

data want(drop=day366-day3200); set have;

array daydummy(*) day1-day3200;

                end;

run;

 

After

data want(drop=day366-day3562); set have;

array daydummy(*) day1-day3562;

                end;

run;

I would like to use some sas code to programmatically find the 3200 and replace it with whatever the max_number.

Regards

 

 

8 REPLIES 8
PaigeMiller
Diamond | Level 26
data want(drop=day366-day&xbarmac);
set have; array daydummy(*) day1-day&xbarmac;

 

Of course, the whole problem goes away if your data was arranged differently. Instead of variable names with day number as part of the column name, and &xbarmac different columns, you should re-arrange the data so that the day number is the value of a variable, like this:

 

day_number    variable1 variable2
1                       
2
...
3562

and now you don't even need to know how many days there are, SAS figures it out without you having to program it and create macro variable and then add this macro variable into places in your code. A word to the wise ...

--
Paige Miller
hmdabbas
Calcite | Level 5

When I use the macro &xbarmac i get this error. 

 

want(drop=day366-&xbarmac); set have;

SYMBOLGEN:  Macro variable XBARMAC resolves to         3469

NOTE: Line generated by the macro variable "XBARMAC".

37                 3469

                   ____

                   80

ERROR 80-322: Expecting a variable name.

 

38         array daydummy(*)

38       ! day1-day&xbarmac;

SYMBOLGEN:  Macro variable XBARMAC resolves to         3469

NOTE: Line generated by the macro variable "XBARMAC".

3                                                          The SAS System                            13:55 Thursday, August 29, 2024

 

38         day        3469

                      ____

                      22

                      200

ERROR: Missing numeric suffix on a numbered variable list (day1-day).

ballardw
Super User

Enumerated variable lists require the "stem" part:  day1 - day3000 not day1-3000 (which in most places looks like subtraction).

So your code :

want(drop=day366-&xbarmac);

has to be:

want(drop=day366-day&xbarmac);

 

And now that looks suspiciously like someone only wants a years worth of values (and fails to ever consider the year with Leap days).

Tom
Super User Tom
Super User

Do NOT put leading spaces into the macro variable.

So DO NOT use CALL SYMPUT().  Use CALL SYMPUTX() instead.

PaigeMiller
Diamond | Level 26

@hmdabbas wrote:

When I use the macro &xbarmac i get this error. 

 

want(drop=day366-&xbarmac); set have;

SYMBOLGEN:  Macro variable XBARMAC resolves to         3469

NOTE: Line generated by the macro variable "XBARMAC".

37                 3469

                   ____

                   80

ERROR 80-322: Expecting a variable name.

 

38         array daydummy(*)

38       ! day1-day&xbarmac;

SYMBOLGEN:  Macro variable XBARMAC resolves to         3469

NOTE: Line generated by the macro variable "XBARMAC".

3                                                          The SAS System                            13:55 Thursday, August 29, 2024

 

38         day        3469

                      ____

                      22

                      200

ERROR: Missing numeric suffix on a numbered variable list (day1-day).


This is just one reason why re-arranging your data as I suggested is the far superior approach. I would be happy to help with that.

--
Paige Miller
ballardw
Super User

or

array day (&xbarmac.);

unless you already have a variable named Day in the data set this will create variables day1 to day&xbarmac.

 

But since this is pretty obviously appearing in the middle of a process I would also question some decisions and approaches that does this. Many approaches that create that many temporary variables are sometimes amenable to approaches that don't require such steps.

 

Tom
Super User Tom
Super User

You almost never want to use the ancient CALL SYMPUT() method.  Instead use the modern CALL SYMPUTX() method (think it is probably only about 30 years old at this point, so it is NEW).  That will remove the leading and trailing spaces.   The only reason to ever use the old method is if you want the macro variable generated to contain leading and/or trailing spaces.  You also won't get that annoying conversion message in the SAS log.

1    data _null_;
2      call symput("symput",3200);
3      call symputX("symputx",3200);
4    run;

NOTE: Numeric values have been converted to character values at the places given by: (Line):(Column).
      2:24
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


5    %put >&symput< ;
>        3200<
6    %put >&symputx<;
>3200<

Are you asking how to read in CODE in SAS?  You can just read it as text strings. You can use TRANWRD() function to replace text.  You could use the STRIP() function to remove leading and trailing spaces from your macro variable.

data _null_;
   infile 'oldprogram.sas';
   file 'newprogram.sas';
   _infile_ = tranwrd(_infile_,'3200',strip("&max_number"));
   put _infile_;
run;

Or are you asking how to make your program dynamic so that it calculates the macro variable and then uses it?

proc sql noprint;
select max(xbarmac)
  into :max_number trimmed
  from have
;
quit;
data want; 
  set have;
  array daydummy day1-day&max_number;
* other code ;
  drop day366-day&max_number;
run; 

 

 

 

 

 

 

Sarath_A_SAS
Obsidian | Level 7

To replace the 3200 with the value stored in the macro variable &xbarmac, you can use the following approach. This involves dynamically constructing the array declaration with the macro variable:

  1. Calculate the Maximum Number and Store in a Macro Variable:

    You've already done this step correctly:

data _null_;
set have;
call symput("xbarmac", max_number);
run;

%put &xbarmac;

 

Use the Macro Variable in the Array Declaration:

You can now use the macro variable &xbarmac in the array declaration:

data want(drop=day366-day&xbarmac);
set have;

array daydummy(*) day1-day&xbarmac;

/* Your code logic here */

run;

Explanation:

  • day366-day&xbarmac: This will dynamically drop the range of variables from day366 to day3562 (if &xbarmac is 3562).
  • array daydummy(*) day1-day&xbarmac;: This will create an array daydummy that includes all variables from day1 to day3562.

 

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

SAS Enterprise Guide vs. SAS Studio

What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.

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
  • 668 views
  • 1 like
  • 5 in conversation