BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Hugo1989
Calcite | Level 5

I am currently writing a piece of code to extract specific elements of raw data into a new file. My raw data file imports from an Excel.XLSX file and has 36 columns which are titled as dates input as "dd/mm/yyyy".

 

When I bring this data into SAS using Proc Import it converts the format of the column titles with the following stated within the log:

 

e.g. Variable Name Change. 42370 -> _42370

 

What I now need is to change the column titles back to a date format as they are showing in my data extract in the above format, e.g. "_ddddd". I need a piece of code to identify where columns have a title such as the one above or similar (I have 36 columns each with a unique header according to which month it is) and then takes that and converts it to a date value.

 

Any help would be really appreciated.

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

You probably want to make the output as a REPORT instead of a dataset.  

So let's mimic your input gibberish.

data have ;
  input id :$10. _42370 _42401;
cards;
NJ 345  456
NY 1234 789
;
proc print data=have; run;
Obs    id    _42370    _42401

 1     NJ      345       456
 2     NY     1234       789

First convert it to a TALL structure where the column header is now in a variable that you can manipulate.

proc transpose data=have out=tall ;
  by id ;
  var _: ;
run;

Now you can convert those goofy numbers into actual DATE values.

data tall2;
  set tall ;
  date = input(substr(_name_,2),32.)+'30DEC1899'd;
  format date date9. ;
run;
proc print data= tall2;
run;
Obs    id    _NAME_    COL1         date

 1     NJ    _42370     345    01JAN2016
 2     NJ    _42401     456    01FEB2016
 3     NY    _42370    1234    01JAN2016
 4     NY    _42401     789    01FEB2016

Now you can make a REPORT that uses the value of the date as the column header.

proc report data=tall2 ;
  column id col1,date ;
  define id / group ;
  define date / across order=internal format=monyy7. ' ';
  define col1 / sum ' ';
run;
  id            JAN2016    FEB2016
  NJ                345        456
  NY               1234        789

View solution in original post

7 REPLIES 7
PaigeMiller
Diamond | Level 26

@Hugo1989 wrote:

What I now need is to change the column titles back to a date format


SAS variable names cannot be dates, so I am not sure what you are wanting as the desired end result.

--
Paige Miller
Hugo1989
Calcite | Level 5

As I say the raw data has the columns named as 'dd/mm/yyyy' but are formatted to display as 'mmm-yy', e.g. the current month is displayed as 'Nov-19'.

 

What I would like to do is reformat my SAS output so that I can get it back to the format in the raw data, whether that be 'dd/mm/yyyy' or 'mmm-yy' I'm not precious about.

Kurt_Bremser
Super User

@Hugo1989 wrote:

As I say the raw data has the columns named as 'dd/mm/yyyy' but are formatted to display as 'mmm-yy', e.g. the current month is displayed as 'Nov-19'.

 

What I would like to do is reformat my SAS output so that I can get it back to the format in the raw data, whether that be 'dd/mm/yyyy' or 'mmm-yy' I'm not precious about.


Don' perpetuate the layout mistakes frequently committed in Excel, which is not designed for mass data processing, but presenting small-scale data to humans.

Free yourself from "spreadsheet thinking", and think SAS (which works more like a database) instead (Maxim 17).

Kurt_Bremser
Super User

First, you need to correct your data layout and transpose from wide to long (Maxims 33 & 19).

Then you extract substr(_name_,2) and convert it to a number. You add '30dec1899'd, attach a date format, and you're done.

Tom
Super User Tom
Super User

You probably want to make the output as a REPORT instead of a dataset.  

So let's mimic your input gibberish.

data have ;
  input id :$10. _42370 _42401;
cards;
NJ 345  456
NY 1234 789
;
proc print data=have; run;
Obs    id    _42370    _42401

 1     NJ      345       456
 2     NY     1234       789

First convert it to a TALL structure where the column header is now in a variable that you can manipulate.

proc transpose data=have out=tall ;
  by id ;
  var _: ;
run;

Now you can convert those goofy numbers into actual DATE values.

data tall2;
  set tall ;
  date = input(substr(_name_,2),32.)+'30DEC1899'd;
  format date date9. ;
run;
proc print data= tall2;
run;
Obs    id    _NAME_    COL1         date

 1     NJ    _42370     345    01JAN2016
 2     NJ    _42401     456    01FEB2016
 3     NY    _42370    1234    01JAN2016
 4     NY    _42401     789    01FEB2016

Now you can make a REPORT that uses the value of the date as the column header.

proc report data=tall2 ;
  column id col1,date ;
  define id / group ;
  define date / across order=internal format=monyy7. ' ';
  define col1 / sum ' ';
run;
  id            JAN2016    FEB2016
  NJ                345        456
  NY               1234        789
Hugo1989
Calcite | Level 5

Really helpful Tom, thanks very much!!

Kurt_Bremser
Super User

Note how the transposition I was talking about (and which is the most important step in @Tom's solution) immediately opens you up to make use of the powers of SAS.

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!
Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 7 replies
  • 2630 views
  • 2 likes
  • 4 in conversation