I have an admit date variable (admitdt) that needs to be brought in to define a few month and week variables but these have to be done in a separate step. Is there a way to create a macro in one data step that can be used in several? Do I just do a LET statement The admitdt format is mmddyy10.
Example:
data _null_;
set dataset1;
call symputx('admitdt',admitdt);
run;
data use_macro_var;
set dataset2;
if date<&admitdt then do ... ;
end;
run;
You have provided such a vague description of the problem that all I can do is provide a vague solution, above. Please be more specific and give actual examples of how you would want to use the macro variable.
I was just about to edit my message but here is an example:
if year="2024" then do;
wk1=(compress('wk'||put(week(AdmitDt) + 1,z2.)));
wk2=compress(substr(year,3,2)||'_'||wk1);
end;
I want to be able to call the macro where it says AdmitDt in the above.
@bhca60 wrote:
I was just about to edit my message but here is an example:
if year="2024" then do;
wk1=(compress('wk'||put(week(AdmitDt) + 1,z2.)));
wk2=compress(substr(year,3,2)||'_'||wk1);
end;I want to be able to call the macro where it says AdmitDt in the above.
If I am understanding you properly, you could use &admitdt in place of AdmitDt. But I still get the feeling there are things I don't understand about your request, and if this suggestion doesn't work, please explain the whole thing in detail, instead of details for part of the problem.
Let's also see if we can get the terminology correct. We are not talking about macros. We are talking about macro variables, which are different than macros.
What you provided looks like it kinda worked but for some reason it's just bringing in the same dates for the columns that are using it (for ex, for wbeg: 26JAN20 filled the column ; wend: 01FEB20 filled the column). Basically, in the end, I am trying to join a summarized data set to a detailed data set. I can't bring in AdmitDt as a field because it wont match onto the summarized data set. In the end, I will need variables that are using AdmitDt in their calculation (such as mend, wk1,wk2..) and using "&admitdt" instead of bringing the AdmitDt into the data is the only solution I can think of. Here is my code where the macro variable is being used:
data table2;
set table1;
format wbeg wend mbeg mend date8.;
AdmitDt = admitdt_1;
format AdmitDt mmddyy10.;
/* created macro to use in other steps without bringing in admitdt downstream*/
call symputx('admitdt',admitdt);
if &admitdt. >= '03sep2017'd and &admitdt. <= intnx('week',today(),-1,'e');
*Determine if a week shared between two months belongs to present month or the previous one;
mbeg= intnx('month',&admitdt.,0,'b');
mend= intnx('month',&admitdt.,0,'e');
wbeg = intnx('week',&admitdt.,0,'b');
wend = intnx('week',&admitdt.,0,'e');
madm = month(&admitdt.);
mwbeg = month(wbeg);
mwend = month(wend);
if month(wbeg) = month(wend) then do;
month3 = put(year(&admitdt.),4.)||put(month(&admitdt.),z2.);
end;
else if mend - wbeg < 7 then do;
if mend - wbeg < 3 then do;
if month(&admitdt.) = 12 then month3 = put(year(&admitdt.)+1,4.)||"01";
else month3 = put(year(&admitdt.),4.)||put(month(&admitdt.)+1,z2.);
end;
else month3 = put(year(&admitdt.),4.)||put(month(&admitdt.),z2.);
end;
else if wend - mbeg < 7 then do;
if wend - mbeg < 3 then do;
if month(&admitdt.) = 1 then month3 = put(year(&admitdt.) - 1,4.) || "12";
else month3 = put(year(&admitdt.),4.)||put(month(&admitdt.)-1,z2.);
end;
else month3 = put(year(&admitdt.),4.)||put(month(&admitdt.),z2.);
end;
Is your real code like you showed it, with all of the code in one DATA step?
If that's the case, the approach won't work, because you can't use CALL SYMPUTX to create a macro variable and then use the macro variable in the same DATA step. The timing doesn't work out.
But if it's all in one step, then you shouldn't need a macro variable at all.
Also, it's a bad idea to write a DATA step that over-writes the data set it reads in, i.e.:
data table1;
set table1;
Every time the step runs, it over writes the input data. When something goes wrong, and you need to de-bug it, you can't, because you don't have the input data anymore. It's better to write a new data set with each DATA step, e.g.:
data table1b;
set table1;
Ok so in Paige's example he creates a data_null to do the call symputx. I will try that and see if that works.
Ok I tried it and it still filled columns with the same week numbers and dates. This is what I did:
data _null_;
set table4;
format AdmitDt mmddyy10.;
call symputx('admitdt',admitdt);
run;
%put &admitdt.;
@bhca60 Looking at the code you shared I believe you are overcomplicating things. I'm even not sure that you need a macro variable at all.
Why don't you explain us what you've got and what you're trying to achieve. Ideally share some sample data with us and show us the desired outcome.
Below some sample code that demonstrates how you could figure out if the days of a week (starting on Sundays) span over two months.
data demo;
length week_num 8;
format week_begin_dt dt week_end_dt weekdatx.;
do dt='01jan2024'd to '31dec2024'd;
week_num=week(dt);
week_begin_dt =intnx('week',dt,0,'b');
week_end_dt =intnx('week',dt,0,'e');
week_two_month_flg =intck('month',intnx('week',dt,0,'b'),intnx('week',dt,0,'e'));
weekday_in_diff_month_flg =intck('month',intnx('week',dt,0,'b'),dt);
output;
end;
run;
proc print data=demo;
where week_two_month_flg = 1;
run;
If you don't want to use the defaults then you also need to tell us when for you a new year and a new week starts.
This is what I wrote up top:
Basically, in the end, I am trying to join a summarized data set to a detailed data set. I can't bring in AdmitDt as a field because it wont match onto the summarized data set. In the end, I will need variables that are using AdmitDt in their calculation (such as mend, wk1,wk2..) and using "&admitdt" instead of bringing the AdmitDt into the data is the only solution I can think of. I think doing a call symputx is the right track for what I'm looking to do. I want to call admitdt throughout the program so as to not have to include admitdt in the data steps.
...and using "&admitdt" instead of bringing the AdmitDt into the data is the only solution I can think of.
Which is why I proposed that you share some representative sample data, show the desired result based on this sample data and explain the logic to get from have to want. Someone else can eventually think of a different solution.
If using a SAS macro variable in SAS data step code the macro variable will resolve before the data step gets compiled and executes. It's therefore on the data step level a constant value.
The macro variable will only ever have a single value. In below based on what you've posted...
data table4;
do AdmitDt='01jan2024'd to '31jan2024'd;
output;
end;
run;
data _null_;
set table4;
call symputx('admitdt',admitdt);
run;
%put AdminDT: %sysfunc(putn(&admitdt.,date9.));
...the value of macro variable &admitdt is the last value written to it (=last row from table4).
39 %put AdminDT: %sysfunc(putn(&admitdt.,date9.)); AdminDT: 31JAN2024
Below code leads to the exactly same outcome.
data _null_;
set table4 end=last;
if last then call symputx('admitdt',admitdt);
run;
@bhca60 wrote:
Ok I tried it and it still filled columns with the same week numbers and dates. This is what I did:
Describe the entire problem in detail. Do not make us guess, that doesn't work.
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.