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

I'm trying to do the following extracts. I successfully converted tmonth to date/numeric so it's reading as
202201, for example. But I am having a hard time extracting year, yr, quarter, inc_mnth and month2 - these are showing blanks
in the data.

data tab ;
set bat;


format tmonth yyyymm6.;
tmonth=input(put(YrMth,6.),yyyymm6.);

year = year(tmonth);
Quarter = "Q" || put(QTR(tmonth),$1.); 
yr = put (year,z4.); 
inc_mnth = put(year(tmonth),z4.) || put(month(tmonth),z2.);
month2=put(put(month(tmonth),z2.), $mth.);

run;
1 ACCEPTED SOLUTION

Accepted Solutions
jebjur
SAS Employee

Converting a character string of '202201' to numeric is still not a SAS date value, so you won't be able to extract the year, quarter, etc. A SAS date is the number of days since January 1, 1960. In order to create a true SAS date, you can use the MDY function, along with the SUBSTR and PUT functions to parse out the year and month and convert to numeric, and then add a 'day' value of 1 for example:

 

data tab ;
YrMth='201202';
tmonth=MDY(put(substr(YrMth,5),2.),1,put(substr(YrMth,1,4),4.)); /* create a numeric SAS date value */


year = year(tmonth);
Quarter = "Q" || put(QTR(tmonth),1.);
yr = put (year,z4.);
inc_mnth = put(year(tmonth),z4.) || put(month(tmonth),z2.);
month2=put(put(month(tmonth),z2.), $mth.);
format tmonth yymm6.;
run;

 

Does that help?

View solution in original post

16 REPLIES 16
Reeza
Super User

Can you show your log?

 

You do have some logical issues, though, what does Yrmth look like and what is the format/type?

 

 

 

 

bhca60
Quartz | Level 8

This is the log. I was wrong, it didint "successfully" convert because of the note in the log but it still shows yrmonth
format. The format type for YrMth was originally CHAR 200 and it looks like 202102.

(Also , $mth. is just Jan, Feb, mar, etc.)

83    data tab;
84    set bat;
85    
86    
87    format tmonth yyyymm6.;
                            ---------
                            484
88    tmonth =input(put(YrMth,6.),yyyymm6.);
                                         ---------
                                         485
NOTE 484-185: Format YYYYMM was not found or could not be loaded.
NOTE 485-185: Informat YYYYMM was not found or could not be loaded.
89    
90    year = year(tmonth);
91    Quarter = "Q" || put(QTR(tmonth),$1.);
WARNING: Character format specified for the result of a numeric expression.
92    yr = put (year,z4.);
93    inc_mnth = put(year(tmonth),z4.) || put(month(tmonth),z2.);
94    month2=put(put(month(tmonth),z2.), $mth.);
95    
96    run;
NOTE: Variable YrMth is uninitialized.
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).
      1019039 at 90:8    1019039 at 91:22   1019039 at 93:16   1019039 at 93:49   1019039 at 94:16   
NOTE: There were 1019039 observations read from the data set WORK.bat.
NOTE: The data set WORK.bat has 1019039 observations and 12 variables.
NOTE: Compressing data set WORK.tab decreased size by 41.12 percent. 
      Compressed is 1101 pages; un-compressed would require 1870 pages.
NOTE: DATA statement used (Total process time):
      real time           1.29 seconds
      cpu time            0.99 seconds
      

 

yabwon
Onyx | Level 15

 

You missed the semicolon...

 

Remember SAS stands for "Semicolon, Always Semicolon" 

 

Bart

_______________
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



yabwon
Onyx | Level 15

I you have a valid SAS date variable this could do the job:

data test;

  /* have */
  d = '25apr2024'd;
  put d= / d= date11.;

  /* want */
  y = year(d);
  m = month(d);

  q_character = put(d, QTR.);
  q_numeric = qtr(d);

  yq = put(d, YYQ.);

  ym_character = put(d, YYMMN.);

  ym_numeric = y*100 + m;

  /* printout*/
  put (_ALL_) (=/);

run;

Bart

_______________
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



ballardw
Super User

Did you read your log?

When I create a single value for Yrmth and attempt some of your code there are immediate problems unless your organization has custom format and informat defined for yyyymmn.

You don't provided any definition of the $mth. format so can't tell how to "fix" that call

251  data example;
252     yrmth=202404;
253
254     format tmonth yyyymm6.;
                      --------
                      484
255     tmonth=input(put(YrMth,6.),yyyymm6.);
                                   --------
                                   485
NOTE 484-185: Format YYYYMM was not found or could not be loaded.

NOTE 485-185: Informat YYYYMM was not found or could not be loaded.

256
257  run;

Perhaps this will help:

data example;
   yrmth=202201;

   format tmonth yymm6.;
   tmonth=input(put(YrMth,6.),yymmn6.);
   year = year(tmonth);
   Quarter = "Q" || put(QTR(tmonth),1.); 
   yr = put (year,z4.); 
   inc_mnth = put(tmonth,yymmn6.);
   /*or*/
   inc_month2 = put(yrmth,f6.);
   month2=put(tmonth,monname.);
run;

Note that I am a bit concerned about the rationale for creating all of those character valued "date" bits. Those are generally not as flexible as a numeric date value.

I used the MONNAME format as a guess for the replacement of the $mth. format not supplied.

 

Also you may want to be aware that Proc Format with the PICTURE statement will let make your own custom formats so you could do something really useless like display the Year, week, quarter, weekday number and name,  month number and name all with one (ugly) format and have some of the "number" type values preceded with 0, blank or nothing leading.

bhca60
Quartz | Level 8
I tried yymm6. before and it didn't come through; same with yymmn6.
yabwon
Onyx | Level 15

Look into this documentation page: https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/leforinforref/n0c9zxlm4e6m7tn1vrn76c98zw66.ht...

It will help you.

 

Bart

_______________
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



ballardw
Super User

@bhca60 wrote:
I tried yymm6. before and it didn't come through; same with yymmn6.

Since your example code didn't have a semicolon for the SET statement I have to assume that you had a similar problem with what ever you were trying with the various formats/informats. So the step failed before ever considering them.

 

Show YOUR log when you have a question about what the log means when it shows things you don't understand.

And please do not say "doesn't work" without attaching a log showing it not "not working". The first thing we will ask for is the log to show what is going on.

Believe it or not, SAS logs are actually helpful. It just takes a bit of experience to understand them.

And you should always check your log. It is not uncommon for someone to say "something isn't working" because values aren't changing when code is changed. Then we find in error in the code that meant the data set isn't replaced. SAS protects you to some extent by not deleting sets when you have errors.

bhca60
Quartz | Level 8

the missing semicolon was just copy/paste error.

bhca60
Quartz | Level 8

the log didnt say anything more than what is shown in the log I posted.

ballardw
Super User

If you mean this log:

 

83    data tab;
84    set bat;
85    
86    
87    format tmonth yyyymm6.;
                            ---------
                            484
88    tmonth =input(put(YrMth,6.),yyyymm6.);
                                         ---------
                                         485
NOTE 484-185: Format YYYYMM was not found or could not be loaded.
NOTE 485-185: Informat YYYYMM was not found or could not be loaded.
89    
90    year = year(tmonth);
91    Quarter = "Q" || put(QTR(tmonth),$1.);
WARNING: Character format specified for the result of a numeric expression.
92    yr = put (year,z4.);
93    inc_mnth = put(year(tmonth),z4.) || put(month(tmonth),z2.);
94    month2=put(put(month(tmonth),z2.), $mth.);
95    
96    run;
NOTE: Variable YrMth is uninitialized.
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).
      1019039 at 90:8    1019039 at 91:22   1019039 at 93:16   1019039 at 93:49   1019039 at 94:16   
NOTE: There were 1019039 observations read from the data set WORK.bat.
NOTE: The data set WORK.bat has 1019039 observations and 12 variables.
NOTE: Compressing data set WORK.tab decreased size by 41.12 percent. 
      Compressed is 1101 pages; un-compressed would require 1870 pages.
NOTE: DATA statement used (Total process time):
      real time           1.29 seconds
      cpu time            0.99 seconds

 

That log shows multiple problems. The biggest is this:

 

NOTE: Variable YrMth is uninitialized.

That means that there is NEVER a value of YrMth to work with. So everything fails.

 

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).
      1019039 at 90:8    1019039 at 91:22   1019039 at 93:16   1019039 at 93:49   1019039 at 94:16   
NOTE: There were 1019039 observations read from the data set WORK.bat.

See that note about missing values generated? When it says 1019039 at 90:8 that means line 90, or

90    year = year(tmonth);

had a missing result 1019039 times. Since there are 1019039 observations in the data set that means every one of those Year values are missing. And others. Because the data set Work.bat did not have any values of YrMth.

So you apparently need to fix Work.BAT before attempting this code.

 

It also shows use of formats and informats that do not exist: YYYYMM or YYYYMMN are not provided by SAS. All of those format and informats use 2 Y's not 4. YYMM or YYMMN.

Use a non-existing Informat an the result in SAS guessing an appropriate format and for numbers that usually means a best. So Tmonth would not be a date value but would look exactly like Yrmth (if a value was provided). Because of the format you attempted to use, if it didn't exist, you might think that it "worked" because 202201 would still look like 202201, but not a date.

 

jebjur
SAS Employee

Converting a character string of '202201' to numeric is still not a SAS date value, so you won't be able to extract the year, quarter, etc. A SAS date is the number of days since January 1, 1960. In order to create a true SAS date, you can use the MDY function, along with the SUBSTR and PUT functions to parse out the year and month and convert to numeric, and then add a 'day' value of 1 for example:

 

data tab ;
YrMth='201202';
tmonth=MDY(put(substr(YrMth,5),2.),1,put(substr(YrMth,1,4),4.)); /* create a numeric SAS date value */


year = year(tmonth);
Quarter = "Q" || put(QTR(tmonth),1.);
yr = put (year,z4.);
inc_mnth = put(year(tmonth),z4.) || put(month(tmonth),z2.);
month2=put(put(month(tmonth),z2.), $mth.);
format tmonth yymm6.;
run;

 

Does that help?

jebjur
SAS Employee
Sorry, meant to say along with the SUBSTR and INPUT functions:
data tab ;
YrMth='201202';
tmonth=MDY(input(substr(YrMth,5),2.),1,input(substr(YrMth,1,4),4.));
year = year(tmonth);
Quarter = "Q" || put(QTR(tmonth),1.);
yr = put (year,z4.);
inc_mnth = put(year(tmonth),z4.) || put(month(tmonth),z2.);
*month2=put(put(month(tmonth),z2.), $mth.);
format tmonth yymm6.;
run;
bhca60
Quartz | Level 8

THANK YOU!!!

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

SAS Enterprise Guide vs. SAS Studio

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.

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
  • 16 replies
  • 540 views
  • 4 likes
  • 5 in conversation