I have two datatset Input12 and input18. Below is the code.
New12 dataset have variable score_date in format yymmn6.
data new12;
set input12;
run;
Now adding new variable score_date in dataset new18
%let score_date=201807;
data new18;
set input18;
format score_date yymmn6.;
run;
After concatenating the dataset new 12 and new18 the date format is not in yymmn6.
data new;
set new12 new18;
run;
This is giving informat date for new12 and blank for new18 in new
data new;
set new18 new12;
run;
This is giving correct date format for new18 and blank for new12 in new.
Is there any reason for improper format after concatenating.
Instead of relying on the source data sets for a variable's format, place a format statement in your data set stacking (concatenation) DATA step.
Example:
data new;
set
new12
new18
;
format score_date yymmn6.;
If you mean to have your date representation stored in a macro symbol, as I infer from your posted code, you need to input the representation using the appropriate informat in order to get a SAS date value.
score_date = input ("&score_date", yymmn6.);
format score_date yymmn6.;
An alternative is to set the macro symbol to the source code of a SAS date literal.
%let score_date = "01JUL2018"D;
and resolve that later in DATA Step as perhaps
data new18;
score_date = &score_date;
format score_date yymmn6.;
run;
I tried below codes.
%let score_date="01dec2019"d;
data twelvenew;
set twelve;
score_date=&scoredate.;
format score_date yymmn6.;
run;
%let score_date="01jun2019"d;
data eightnew;
set eight;
score_date=&scoredate.;
format score_date yymmn6.;
run;
data final;
set eightnew twelvenew;
run;
I am getting dates only eightnew in final dataset and others are missing.
Is iam missing anything here.
Related
I have an existing process that imports data from a flat file with no headers. There are hundreds of columns. The provider of the file has added several hundred more columns at different points within the existing columns. I have a list of the old and new column names and SAS code that properly sets the data types for the old columns but not the new ones. I'd rather not have to go through my existing import code and manually write column headers and data formats but I'm not sure how to use these parts to get new import code for the new headers.
data raw_file;
infile "flatfile.csv" delimiter="|" missover dsd firstobs=1;
informat oldcol1 best32.;
informat oldcol2 mmddyy10.;
informat oldcolN $60.;
format oldcol1 best32.;
format oldcol2 mmddyy10.;
format oldcolN $60.;
input
oldcol1
oldcol2
oldcolN $;
run;
I have the header information in an Excel file right now.
old K010H K010I K010J K020A
new K010H K010I K010J K010L K010M K010N K020A
Based on your description, I presume you either know or will find out the informats for the new columns also. If that is the case, why don't you auto generate the code to read the file?
Since you have the header information, assuming you can modify it to the following format and save as a CSV:
var infmt
K010H best32.
K010I mmddyy10.
K010J $60.
K010L best32.
K010M mmddyy10.
K010N $60.
K020A best32.
Then something like this would automatically generate the code and read the data for you:
proc import datafile="cols.csv" out=cols replace;
run;
proc sql;
select var into :cols separated by ' ' from cols ;
select infmt into :infmts separated by ' ' from cols ;
quit;
%macro gen_code;
data raw_file;
infile "flatfile.csv" delimiter="|" missover dsd firstobs=1;
%let ii = 1;
%do %while (%scan(&cols, &ii, %str( )) ~= %str());
%let col = %scan(&cols, &ii, %str( ));
%let infmt = %scan(&infmts, &ii, %str( ));
informat &col &infmt ;
%let ii = %eval(&ii + 1);
%end;
input
%let ii = 1;
%do %while (%scan(&cols, &ii, %str( )) NE %str());
%let col = %scan(&cols, &ii, %str( ));
&col
%let ii = %eval(&ii + 1);
%end;
;
run;
%mend;
%gen_code;
In the future, you could make modifications to your header CSV file and the rest will be taken care by the code itself.
If you have a machine readable data dictionary then you can generate the code from that. Otherwise you will need to just edit your data step. While you are at it you can clean it up so that it is easier to maintain.
First thing is to use LENGTH or ATTRIB to define the variables, instead of forcing SAS to guess. Second only attach informats or formats to variables that need them. For example there is no need to attach informats to normal strings or numbers. No need to attach $xx format to character variables. Do you really need to attach BEST32. format to numbers instead of letting SAS go ahead and display the numeric variables without formats attached using the default BEST12. format?
Second if you define the variables in the order they appear then you can use a positional variable list in the INPUT statement. Then you only have to change the INPUT statement if the first or last variable changes.
So for your example you might create a data step like this instead.
data raw_file;
infile "flatfile.csv" dlm="|" truncover dsd firstobs=1;
length
oldcol1 8
oldcol2 8
oldcolN $60
;
informat oldcol2 mmddyy10.;
format oldcol2 mmddyy10.;
input oldcol1 -- oldcolN ;
run;
Then adding new variables is as simple as inserting them into right place in the LENGTH statement and when needed adding them to the INFORMAT and/or FORMAT statements. If you don't know what the variables contain then make them as character strings and look at the resulting values and decide later if you need to define them differently.
I have a SAS field where the datatype is number and format is date9.
It has a value like 30SEP2018.
How do I convert it to a SAS date so I can do date operations?
SAS dates are stored as number starting from 1/1/1960 and it starts form number = 0 and increases by 1 for every day. Your date is stored as number and then you get from proc contents and format is to display in the way you want.
data have;
input date:date9.;
format date date9.;
datalines;
30SEP2018
;
proc contents data=have;
run;
you can calculations on above date and gives you appropriate results as shown below
data want;
set have;
new_date= date+1;
new_date1= date-1;
format new_date new_date1 date9.;
run;
proc print; run;
I have a table in SAS where in one column, the date is stored (e.g. "2005/10").
How do I have to convert this to a SAS data format?
Among many other tries, I tried this code:
data test;
format date YYMMS.;
date = input(ObservationMonth, YYMMS.);
put date=date9.;
run;
You could just use the anydtdte. informat.
data want;
format date yymms.;
text="2005/10";
date=input(text,anydtdte.);
put date;
run;
This informat detects most date formattings and converts the character-stored value to a SAS date.
One way is to use substr() and mdy() to extract the date components:
data _null_;
ObservationMonth ="2005/10";
date =mdy(substr(ObservationMonth,6,2),1,substr(ObservationMonth,1,4));
put date = date9.;
run;
Another option is to use the anydtdte informat (note that results may differ depending on your locale):
data _null_;
ObservationMonth ="2005/10";
date =input(ObservationMonth,anydtdte.);
put date = date9.;
run;
Yet another option is to modify the input to enable use of the YYMMDDw. informat:
data _null_;
ObservationMonth ="2005/10";
date =input(ObservationMonth!!'/01', YYMMDD10.);
put date = date9.;
run;
you're fantastic, guys! Thank you so much, with a "set" statement it works fine!
I have a variable that was entered as 31.01.2002 for all entries, and is a character. I would like to put it in numerical form with date9. .
I have tried the below:
date=input(oldway, 10.);
date=input(oldway, date9.);
put date=ddmmyy10.;
date=input(compress(oldway,'.'),10.);
date = INPUT(compress(oldway),date9.);
format date date9.;
run;
I have also tried combinations of the above and to no avail.
Any ideas for forward motion?
Kind Regards!!
You can't input your date using the date9. informat as your string variable isn't in that format. You can use ddmmyy10., though, and that also takes care of the . characters.
data have;
input old $10.;
cards;
31.01.2014
28.02.2014
01.01.2015
;
run;
data want;
set have;
new = input(old, ddmmyy10.);
format new date9.;
run;
try this:
data _null_;
date ="31.01.2014";
date=compress(date,".");
new_date=input(date,ddmmyy8.);
format new_date date9.;
put new_date;
run;
I'm trying to put a number eg 20141001 into a date9. format eg 01OCT14.
I've tried to use the input function with an input format of yymmddn8. but SAS throws out 'informat could not be found or loaded'
Any ideas how to get around this? (Sample code below)
data _null_;
date=20141001;
output=input(date,yymmddn8.);
format output date9.;
put output=;
run;
You are almost there. Although there is a YYMMDDN format there is not an informat of the same name. Use the YYMMDD informat. The Input function is expecting a character string i.e. the DATE variable. Redefine DATE as a character variable e.g.
data _null_;
date='20141001';
output=input(date,yymmdd8.);
format output date9.;
put output=;
run;
Alternatively you could have used these assignments:
output = input('20141001',yymmdd8.);
or
output = '01oct2014'd;