问题
When I imported my excel sheet some dates imported differently than others. I tried to fix this with the code below to format the date.
DATA volume;
SET mice.volume;
format Date MMDDYY10.;
run;
However, I received the following error.
ERROR 48-59: The format $MMDDYY was not found or could not be loaded.
I had also tried with the following code
DATA volume;
SET mice.volume;
If date= 44138 then date= '11/3';
If date= 44141 then date= '11/6';
run;
NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column).
A Proc Contents shows the variable= Date type= Char Len=7 format=$7 Informat=$7 Label= Date
How do I fix this?
回答1:
The date column being character having a mix of 'date looking' strings, and Excel date value numbers tells me some of the date values in your Excel are actually strings, such as '11/10
or ='11/10'
.
The raw number 44138
is:
- a SAS date value is
04-NOV-2080
(obviously not what is wanted) - an Excel date value
03-NOV-2020
(aha!) 03-NOV-2020
as SAS date value is22222
- an offset of
-21916
from Excel
- an offset of
-21916
is the SAS date30-DEC-1899
Date Epochs
An epoch is the date corresponding to a base number 0
in a systems calendar.
SAS Base year is 1960
and Excel Base year is 1900
.
Formatted
Number Actual Date Date Shown System/Format
------ ----------- ----------- ----------
0 31-DEC-1899 1/0/1900 Excel / Short Date (Formatter is weird at Epoch)
0 01-JAN-1960 01-JAN-1960 SAS / DATE11.
21916 01-JAN-1960 1/1/1960 Excel / Short Date
-21916 30-DEC-1899 31-DEC-1899 SAS / DATE11.
Notice the round trip is from 31-dec-1899
to 30-dec-1899
. This due to an Excel 97 bug that has been carried forth for legacy reasons. See Microsoft's explanation in "Excel incorrectly assumes that the year 1900 is a leap year" which pushes the blame back even further to Lotus 1-2-3
The formula to convert between systems S1 and S2 date numbers is to add the # for the other systems epoch date (@ # 0)
SAS#(date) = Excel#(date) + SAS#(Excel Epoch Date) - 1 (Excel leap year bug), or
sas_dt = excel_dt + '31-DEC-1899'd - 1; *or;
sas_dt = excel_dt + '30-DEC-1899'd;
What happened
Mixed value types in the Excel date
column forced IMPORT
to perceive the date
variable as character.
- The Excel cells with a date looking m/d string were brought in as the string
- The Excel cells with a date, likely custom formatted as m/d, were brought in as the underlying Excel date number.
The ERROR
You tried to apply the date format MMDDYY.
to the character variable Date
.
A character column can not be assigned a numeric or date format, thus you get the
ERROR 48-59: The format $MMDDYY was not found or could not be loaded.
SAS automatically presumed MMDDYY.
meant a character format $MMDDYY.
because the variable type was character.
The Fix
You can convert the values in the character date
column with code such as the following (untested):
if index(date,'/') then
date_fixed = input (trim(date)||'/2020', mmddyy10.);
else
date_fixed = input(date,best12.) + '30-DEC-1899'D;
format date_fixed yymmdd10.;
If you want to continue showing only mm/dd in SAS, use the format NLDATEM5.
format date_fixed NLDATEM5.;
来源:https://stackoverflow.com/questions/64979048/sas-date-imported-wrong