SAS Programming

DATA Step, Macro, Functions and more
BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Wolverine
Pyrite | Level 9

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)

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26
%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

View solution in original post

3 REPLIES 3
PaigeMiller
Diamond | Level 26
%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
Astounding
PROC Star

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. 

PaigeMiller
Diamond | Level 26

@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

sas-innovate-white.png

Special offer for SAS Communities members

Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.

 

View the full agenda.

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 3 replies
  • 287 views
  • 0 likes
  • 3 in conversation