BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
LL5
Pyrite | Level 9 LL5
Pyrite | Level 9

Hi, I am trying to convert a six-digit number or string to a date with yyyymm format, then create two (or potentially) more new date variables, one is 12 months prior to that date, and another is 24 months prior to that date. 

 

Below is the example. Let's say I have a pre-define date in yyyymm format (i.e 202312 for December 2023), I want to 

1) convert this 202312 to a date. Since at this time I am not 100% sure if data will flow in from upstream process as a string or a numeric value, I tried to convert to both numeric and character (using input and put function, respectively)

2) create two more new fields. dt12 is 12 months prior to 202312, which would be 202301. dt24 is 24 months prior to 202312, which would be 202201

3) these new fields will be used as a filter in the where statement to extract subset of data within specific time period. 

 

I was not able to create dt12 and dt24, any advice or guidance will be greatly appreciated.

%let yyyymm_character='202312';
%let yyyymm_numeric=202312;
data test;
dt_numeric = input(&yyyymm_numeric,YYMMNw.);
dt_character = put(&yyyymm_numeric,YYMMNw.);
dt12 = intnx('month',dt_numeric,-12,'e');
dt24 = intnx('month',dt_numeric,-24,'e');
run;
1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

 

You did not provide a width, number of characters for the YYMMN informat to use so nothing was performed. Your log would show something like

966  data test;
967  dt_numeric = input(&yyyymm_numeric,YYMMNw.);
                                        -------
                                        485
968  dt_character = put(&yyyymm_numeric,YYMMNw.);
                                        -------
                                        484
NOTE 485-185: Informat YYMMNW was not found or could not be loaded.

NOTE 484-185: Format YYMMNW was not found or could not be loaded.

969  dt12 = intnx('month',dt_numeric,-12,'e');
970  dt24 = intnx('month',dt_numeric,-24,'e');
971  run;

Not loaded means nothing was done because the informat could not be found.

 

Also, INPUT function requires character values. If  you give SAS a numeric value then it does a default numeric to character conversion that is generally using a BEST12 format resulting in 6 leading spaces that the YYMMN informat will not use as you might want. 

This is what your log would show if you provided the proper width value for the informat:

975  dt_numeric = input(&yyyymm_numeric,YYMMN6.);
976  /*dt_character = put(&yyyymm_numeric,YYMMNw.);*/
977  dt12 = intnx('month',dt_numeric,-12,'e');
978  dt24 = intnx('month',dt_numeric,-24,'e');
979  run;

NOTE: Numeric values have been converted to character values at the places given by:
      (Line):(Column).
      975:20
NOTE: Missing values were generated as a result of performing an operation on missing values.
      Each place is given by: (Number of times) at (Line):(Column).
      1 at 977:8   1 at 978:8

And the result is missing values because of the conversion.

So use the CHARACTER version.

Note that I use a DATE9 format so you can see the result below.

%let yyyymm_character='202312';
data test;
dt_numeric = input(&yyyymm_character,YYMMN6.);
dt12 = intnx('month',dt_numeric,-12,'e');
dt24 = intnx('month',dt_numeric,-24,'e');
format dt_numeric dt12 dt24 date9.;
run;

Note: your attempt to display a simply number number, which is what 202312 is, with a date format would not show anything resembling a desired date. SAS dates are number of days since 01JAN1960. So add 20,312 days and you get a date in year 2513.

 

 

 

View solution in original post

6 REPLIES 6
PaigeMiller
Diamond | Level 26
%let yyyymm_character='202312';
%let yyyymm_numeric=202312;
data test;
dt_numeric = input(&yyyymm_character,YYMMN6.);
dt_character = put(&yyyymm_numeric,6.);
dt12 = intnx('month',dt_numeric,-12,'e');
dt24 = intnx('month',dt_numeric,-24,'e');
format dt_numeric dt12 dt24 yymmn6.;
run;

 

Format names never end with W, the W indicates width, which must be a number, or can be left out. Your original code tried to INPUT &yyyymm_numeric, but INPUT works on character strings.

 

Also, since I dislike macro variables that have quotes around the values (I feel it is unnecessary and can cause problems in some situations), this works too

 

%let yyyymm=202312;
data test;
dt_numeric = input("&yyyymm",YYMMN6.);
dt_character = put(&yyyymm,6.);
dt12 = intnx('month',dt_numeric,-12,'e');
dt24 = intnx('month',dt_numeric,-24,'e');
format dt_numeric dt12 dt24 yymmn6.;
run;
--
Paige Miller
LL5
Pyrite | Level 9 LL5
Pyrite | Level 9

@PaigeMiller Thanks a lot for the explanation of my code error and providing a solution. Really appreciate for your insights and advice.  

yabwon
Onyx | Level 15
%let yyyymm_character='202312';
%let yyyymm_numeric=202312;
data test;

numeric=&yyyymm_numeric.;

character=&yyyymm_character.;

/* NUMERIC case */
dt_numeric = MDY(mod(numeric,100),01,int(numeric/100));

dt_numeric12 = intnx('month',dt_numeric,-12,'e');
dt_numeric24 = intnx('month',dt_numeric,-24,'e');

put (dt_numeric:) (/=date11.);




/* CHARACTER case */
dt_character = input(character !! '01',YYMMdd10.);
dt_character12 = intnx('month',dt_character,-12,'e');
dt_character24 = intnx('month',dt_character,-24,'e');

put (dt_character:) (/=date11.);

run;
_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



LL5
Pyrite | Level 9 LL5
Pyrite | Level 9

@yabwon Thanks for illustrating the solution for both numeric and character value. Much appreciated it. 

ballardw
Super User

 

You did not provide a width, number of characters for the YYMMN informat to use so nothing was performed. Your log would show something like

966  data test;
967  dt_numeric = input(&yyyymm_numeric,YYMMNw.);
                                        -------
                                        485
968  dt_character = put(&yyyymm_numeric,YYMMNw.);
                                        -------
                                        484
NOTE 485-185: Informat YYMMNW was not found or could not be loaded.

NOTE 484-185: Format YYMMNW was not found or could not be loaded.

969  dt12 = intnx('month',dt_numeric,-12,'e');
970  dt24 = intnx('month',dt_numeric,-24,'e');
971  run;

Not loaded means nothing was done because the informat could not be found.

 

Also, INPUT function requires character values. If  you give SAS a numeric value then it does a default numeric to character conversion that is generally using a BEST12 format resulting in 6 leading spaces that the YYMMN informat will not use as you might want. 

This is what your log would show if you provided the proper width value for the informat:

975  dt_numeric = input(&yyyymm_numeric,YYMMN6.);
976  /*dt_character = put(&yyyymm_numeric,YYMMNw.);*/
977  dt12 = intnx('month',dt_numeric,-12,'e');
978  dt24 = intnx('month',dt_numeric,-24,'e');
979  run;

NOTE: Numeric values have been converted to character values at the places given by:
      (Line):(Column).
      975:20
NOTE: Missing values were generated as a result of performing an operation on missing values.
      Each place is given by: (Number of times) at (Line):(Column).
      1 at 977:8   1 at 978:8

And the result is missing values because of the conversion.

So use the CHARACTER version.

Note that I use a DATE9 format so you can see the result below.

%let yyyymm_character='202312';
data test;
dt_numeric = input(&yyyymm_character,YYMMN6.);
dt12 = intnx('month',dt_numeric,-12,'e');
dt24 = intnx('month',dt_numeric,-24,'e');
format dt_numeric dt12 dt24 date9.;
run;

Note: your attempt to display a simply number number, which is what 202312 is, with a date format would not show anything resembling a desired date. SAS dates are number of days since 01JAN1960. So add 20,312 days and you get a date in year 2513.

 

 

 

LL5
Pyrite | Level 9 LL5
Pyrite | Level 9

@ballardw Thanks a lot for analyzing the log message line by line, as well as providing a solution along with a detail explanation. Really helpful and greatly appreciated. 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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.

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
  • 6 replies
  • 720 views
  • 3 likes
  • 4 in conversation