- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to identify a cohort of people over a range of years. One of the requirements is to remove people who died before the end of each measurement year. I'm using a macro for the years, so the end of each year is 31DEC20&yy. The macro generates the date correctly, but I keep getting an error: Expecting an arithmetic operator. That suggests to me that the value created by the macro is character rather that numeric. But I've tried adding "put", and the error is the same.
In the example below, it should delete all cases with dates in 2017 and retain all cases with dates in 2018.
/* Create a dimension table */
data DIM;
format date date9.;
do dt='01jan2017'd to '31dec2018'd;
date=dt;
month=month(dt);
year=year(dt);
quarter=QTR(dt);
output;
end;
drop dt;
run;
/* remove unnecessary rows and keep first date of the month */
data DIM;
set DIM;
by month;
if first.month then output;
run;
%macro YEAR (yy);
DATA test; SET DIM;
IF date <= put(31DEC20&yy.) THEN delete;
RUN;
%mend;
%YEAR (17)
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
%macro YEAR (yy);
DATA test; SET DIM;
IF date <= mdy(12,31,20&yy.) THEN delete;
RUN;
%mend;
%YEAR (17)
Why does
put(31DEC20&yy.)
not work? Several reasons
- SAS does not recognize text such as 31DEC2017 as a date. In fact, it doesn't know what it is, its not a text string, because text strings are always enclosed in quotes. Its not a number because a number because numbers don't have DEC in them.
- The PUT function must have a valid numeric variable and then a comma, and then a format, none of which appears in your usage
- Even if the PUT function worked, it creates a text string and SAS cannot compare a numeric date to a text string.
If you want SAS to recognize 31DEC2017 as a valid date, you have to translate it into something SAS understands. There are many ways to do this, one is the MDY function above, another is to use SAS date literals such as '31DEC2017'd. Except for the date literal such as '31DEC2017'd, if it looks like something humans understand, then SAS doesn't understand it and it has to be translated. Its like you speaking English to someone who doesn't speak English, you must do the translations to be understood, and for this the proper translations are done by using the proper SAS code.
Paige Miller
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
%macro YEAR (yy);
DATA test; SET DIM;
IF date <= mdy(12,31,20&yy.) THEN delete;
RUN;
%mend;
%YEAR (17)
Why does
put(31DEC20&yy.)
not work? Several reasons
- SAS does not recognize text such as 31DEC2017 as a date. In fact, it doesn't know what it is, its not a text string, because text strings are always enclosed in quotes. Its not a number because a number because numbers don't have DEC in them.
- The PUT function must have a valid numeric variable and then a comma, and then a format, none of which appears in your usage
- Even if the PUT function worked, it creates a text string and SAS cannot compare a numeric date to a text string.
If you want SAS to recognize 31DEC2017 as a valid date, you have to translate it into something SAS understands. There are many ways to do this, one is the MDY function above, another is to use SAS date literals such as '31DEC2017'd. Except for the date literal such as '31DEC2017'd, if it looks like something humans understand, then SAS doesn't understand it and it has to be translated. Its like you speaking English to someone who doesn't speak English, you must do the translations to be understood, and for this the proper translations are done by using the proper SAS code.
Paige Miller
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Just addressing the question you asked (no comment on the approach or the programming tools used), this would need to change:
IF date <= put(31DEC20&yy.) THEN delete;
Here's the correct way to refer to a particular date in SAS:
IF date <= put("31DEC20&yy."d) THEN delete;
But really you don't even need to go that far. Refer to the date in your programming statements:
if date <= "31DEC20&yy."d then delete;
No functions needed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
@Astounding wrote:
Here's the correct way to refer to a particular date in SAS:
IF date <= put("31DEC20&yy."d) THEN delete;
Syntax error, you need a format in the PUT statement.
Paige Miller