Good afternoon
so I have BEST12.
I want to convert to date9.
so my code is
data step7_1;
set step7;
service_day2= input(put(datedate, z8.),yymmdd8.);
format service_day2 date9.;
run;
the error is
NOTE: Invalid argument to function INPUT at line 92 column 15.
NOTE: Mathematical operations could not be performed at the following places. The results of the
operations have been set to missing values.
Each place is given by: (Number of times) at (Line):(Column).
4 at 97:15
how can I fix this issue?
Thanks
Kazu
A format is just a mechanism of displaying data, so there's no need to apply functions to 'convert' it, just apply a format using the format statement:
data step7_1;
set step7;
service_day2 = datedate;
format service_day2 date9.;
run;
If you don't need a new variable, you can just use the format statement alone:
data step7_1;
set step7;
format datedate date9.;
run;
Or you can just alter the original dataset directly using PROC DATASETS:
proc datasets lib=work nolist;
modify step7;
format datedate date9.;
quit;
This has the advantage of not copying data, it will run more quickly and simply modifies the dataset metadata in place.
Related
How can I display the internal date value of a date variable in sas?
I have it currently formatted as a date in the format ddmmyy10. and I would like to display the internal date value.
I initially thought of using the datediff function to get the difference from my date and January 1st 1960 but was wondering if there were a simpler way.
Thanks in advance
Alex
Simply set it as the numeric format 8.
/* Example data */
data have;
date = '02MAY2022'd;
format date date9.;
run;
/* Change the format of date in the dataset 'have' */
proc datasets lib=work nolist;
modify have;
format date 8.;
quit;
Output:
date
22767
Or, in Enterprise Guide, change the format through the GUI:
Just use a different format. Since recent dates are in the tens of thousands of days since 1/1/1960 the COMMA format would work well.
proc print data=have ;
format date comma8. ;
run;
Or remove the format completely and let SAS use its default display method for the numbers.
proc print data=have ;
format date ;
run;
I've excel file shown below as input,
Report Name Address June14,2019 June 15,2019
Daily CH CJ MJ
After i used below syntax to import
proc import out=ds_new datafile="/Sasdata/SAS_Reports_Tracker_2019.xlsx"
dbms=xlsx replace;
sheet="SAS_Reports_June19";
run;
I'm not getting same output as input, I'm getting as
Report Name Address 43586 43587
Daily CH CJ MJ
Both Dates (June14,2019 June 15,2019) has converted to SAS internal Date format, However i need exact same output as input.
By default, a SAS variable name cannot contain a comma.
Try using the VALIDVARNAME option.
options validvarname=any;
libname data xlsx "/home/loicpalma0/stackoverflow.xlsx";
data want;
set data.sheet1;
run;
However, this is not recommended. You will have trouble at a later stage if you want to perform operations using those two columns. You will have to use "<columns>"n otherwise it will return an error.
Use options validvarname=v7; to change the columns name to a valid SAS name, which are for SAS 7 and later:
Up to 32 mixed-case alphanumeric characters are allowed.
Names must begin with an alphabetic character or an underscore.
Invalid characters are changed to underscores.
Any column name that is not unique when it is normalized is made unique by appending a counter (0, 1, 2, and so on) to the name.
And if you want to see the output with a comma, just use the label option
proc print data=want label;run;
PS: Note that in the example you provide, you specify 5 columns and only fill 4 of them.
When SAS retrieves an Excel DATE value as text instead of numeric you get the raw Excel value converted to text instead of the number as displayed by Excel formats. Since a variable name is by definition character any date values in column headers will be imported in that way.
First transpose the data to get the variable's name into the value of an actual variable.
proc transpose data=ds_new out=ds_tall ;
by Report Name Address ;
var '4'n: ;
run;
Then convert the digit string into a date value by converting it to an integer and adjusting for the different base date used to count dates.
data want;
set ds_tall;
date = input(_name_,32.) + '30DEC1899'd ;
format date date9.;
run;
I have an input file, where my dates don't have leading zeros (like 25.3.2016) but I would like to transform them into format DDMMYYYYP10.
Is there any format, informat, function etc. that could do that for me?
I'm using SAS Enterprise Guide 4.3.
There isn't any "transformation" required, really. The only two things you need are:
A proper informat (in your case, the ANYDTDTE10. should do) for SAS to adequately recognize the dates upon reading the data
An output format (you are asking for DDMMYYP10.) to display dates, given they are imported correctly with the informat above.
Illustration:
data dates;
format mydate DDMMYYP10.;
input mydate ANYDTDTE10.;
datalines;
25.3.2016
run;
proc print;run;
Results:
Obs mydate
1 25.03.2016
Of course you'll be needing an INFILE statement rather than a DATALINES if you are reading external data (which I assume is your case), but the results will be the same.
Remember that output formats are only formats. You can change them at will without affecting the underlying data. So the key here is really the informat.
My input is dataset, so this worked for me:
data dates;
set My_data;
format date1 DDMMYYP10.;
date1 = input (date, anydtdte10.);
run;
SAS is designed to store a date as a "SAS Date", which is a numeric variable that is the number of days since Jan 1, 1960. Assuming you have a SAS date (and not a character variable that looks like a date), it should be straight forward to change the format used for this variable. Note that this doesn't actually transform the value, it just changes the format used to display the value when it is printed etc.
36 data want;
37 mydate="1Mar2016"d;
38 put mydate=;
39 format mydate ddmmyyp10.;
40 run;
mydate=01.03.2016
Edit: I reread your question and realized maybe you do not have a SAS dataset as input but instead have a text file? If so, you can read dates like 25.3.2016 using the ddmmyy10 informat. Below uses ddmmyy10 informat to read in the value from text file, and then ddmmyyp10 format to format it with period separators :
115 data want;
116 input mydate ddmmyy10.;
117 put mydate=;
118 format mydate ddmmyyp10.;
119 cards;
mydate=01.03.1960
NOTE: The data set WORK.WANT has 1 observations and 1 variables.
121 ;
122 run;
I have the following Variable called Date in an excel file which I'm reading into SAS:
Date
May2005
June2005
July2005
..
July2015
Both the format and the informat are characters ($8)
I wanted to convert these into a SAS Date variable.
How can I accomplish this task?
I thought about using substr to first create a month and year variable,
then use proc format to convert all the months to numeric (e.g 'jan' = 1).
The use the mdy date function to create a new date. But I wonder if there is a shorter way to accomplish this task?
You can use the ANYDTDTE. informat if you prepend a day to your month+year string.
data want ;
set have ;
actual_date = input('01'||date,anydtdte.);
format actual_date date9.;
run;
Note that the FORMAT or INFORMAT attached to the character variable is meaningless, but having a variable of only length 8 will not allow room to store longer month names. Perhaps the length got set to only 8 because your particular example set of data did not include any longer month names.
If you are running such an old version of SAS that the ANYDTDTE. informat does not exist or does not work with fully spelled out months then you will need to work a little harder. You could transform the string into DATE9 format.
actual_date = input
('01'||substr(date,1,3)||substr(date,length(date)-3)
,DATE9.);
As #Tom hints towards, you have to use an informat that SAS can interpret as a numeric value when reading in character dates. I'm not sure if there is one that reads MONTHYYYYw., (naturally, ANYDTDTE works but I prefer to avoid it). In this case, I would use MONYYw., combined with substr to get the length 3 Month abbreviation and the 2 digit year:
data have;
input Date $13.;
datalines;
January2005
Feburary2005
March2005
April2005
May2005
June2005
July2005
August2005
September2005
October2005
November2005
December2005
;
run;
data want;
set have;
Date2 = input(SUBSTR(Date,1,3)||SUBSTR(Date,length(date)-1,2),MONYY13.);
Format Date2 DATE8.;
run;
proc print data = want; run;
I have a sas data set which has date field which is in the format "04JAN2012" and using format, I am converting it to "2012-01-04" in a separate data step.
The problem arises when I am using a simple where statement in proc SQL which is using a 'where' condition like---- select * from temp where temp.active_date > '2012-01-01'
The error message at this point is "Expression using equals (>) has components that are of different data types."
Please help !
The best way would be to convert your string ('2012-01-01') into a SAS date before doing the filter, eg via macro:
%let date_filter='2012-01-01';
%let mydate=%sysfunc(mdy(
%substr(&date_filter,7,2)
,%substr(&date_filter,10,2)
,%substr(&date_filter,2,4)));
proc sql;
select * from temp where temp.active_date > &mydate;
If you're using FORMAT and not PUT (which converts to character internally), you aren't actually changing anything about the date beyond how it is displayed (and used in some grouping functions). Internally, active_date still is a numeric SAS date.
As such, you simply need to use the correct format of date constant. While you are using PROC SQL, you still are in SAS, which formats date constants differently than SQL Server or Oracle.
'01JAN2012'd is the correct format of date constant for that, so your code should be:
select * from temp where temp.active_date > '01JAN2012'd;
If you are generating this comparison value in some fashion (not writing it into code), you can generate it properly by PUTting (or FORMATting) the value being generated to DATE9. format.