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
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 ...
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).
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).
Do NOT put leading spaces into the macro variable.
So DO NOT use CALL SYMPUT(). Use CALL SYMPUTX() instead.
@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.
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.
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;
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:
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 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.