How To store SAS dates in a macro - date

I am trying to create different datasets with the names starting from a date which has data for different dates. When i am trying to run the code it is reading the date as numeric numbers and not as Dates. Here is the code
data dates;
input dates mmddyy8. name : $10. ;
format dates date9.;
cards;
01312015 swati
02282015 kangan
01232015 Gotam
04302015 Hushiyar
05172015 yash
09192015 Kuldeep
08302015 David
05172015 yash
11192015 Uninayal
11192015 Uninayal
12032015 sahil
;
data dates;
set dates;
format new date9.;
new=intnx('month', dates, 0, 'e');
run;
proc sql;
select distinct new into : new1 -: new8 from dates;
quit;
%put &new1.;
%macro swati;
%do i= 1 %to 1;
data data_&&new&i.;
set dates;
if new="&&new&i." then output data_&&new&i.;
run;
%end;
%mend;
%swati;
When I try running this code it gives me the error that says it is reading the dates stored in the macro as numbers. How do i make SAS read the dates as just dates only?

Related

SAS Given a start & end date I need to know the dates of each 30 day period AFTER the first 35 days

I am am given 2 dates, a start date and an end date.
I would like to know the date of the first 35 day period, then each subsequent 30 day period.
I have;
start end
22-Jun-15 22-Oct-15
9-Jan-15 15-May-15
I want;
start end tik1 tik2 tik3 tik4
22-Jun-15 22-Oct-15 27-Jul-15 26-Aug-15 25-Sep-15
9-Jan-15 15-May-15 13-Feb-15 15-Mar-15 14-Apr-15 14-May-15
I am fine with the dates calculations but my real issue is creating a variable and incrementing its name. I decided to include my whole problem because I thought it might be easier to explain in its context.
You can solve the problem via following logic:
1) Determining number of columns to be added.
2) Calculating the values for the columns basis the requirement
data test;
input start end;
informat start date9. end date9.;
format start date9. end date9.;
datalines;
22-Jun-15 22-Oct-15
09-Jan-15 15-May-15
;
run;
/*******Determining number of columns*******/
data noc_cal;
set test;
no_of_col = floor((end-start)/30);
run;
proc sql;
select max(no_of_col) into: number_of_columns from noc_cal;
run;
/*******Making an array where 1st iteration(tik1) is increased by 35days whereas others are incremented by 30days*******/
data test1;
set test;
array tik tik1-tik%sysfunc(COMPRESS(&number_of_columns.));
format tik: date9.;
tik1 = intnx('DAYS',START,35);
do i= 2 to %sysfunc(COMPRESS(&number_of_columns.));
tik[i]= intnx('DAYS',tik[i-1],30);
if tik[i] > end then tik[i]=.;
end;
drop i;
run;
Alternate Way (incase you dont want to use proc sql)
data test;
input start end;
informat start date9. end date9.;
format start date9. end date9.;
datalines;
22-Jun-15 22-Oct-15
09-Jan-15 15-May-15
;
run;
/*******Determining number of columns*******/
data noc_cal;
set test;
no_of_col = floor((end-start)/30);
run;
proc sort data=noc_cal;
by no_of_col;
run;
data _null_;
set noc_cal;
by no_of_col;
if last.no_of_col;
call symputx('number_of_columns',no_of_col);
run;
/*******Making an array where 1st iteration(tik1) is increased by 35days whereas others are incremented by 30days*******/
data test1;
set test;
array tik tik1-tik%sysfunc(COMPRESS(&number_of_columns.));
format tik: date9.;
tik1 = intnx('DAYS',START,35);
do i= 2 to %sysfunc(COMPRESS(&number_of_columns.));
tik[i]= intnx('DAYS',tik[i-1],30);
if tik[i] > end then tik[i]=.;
end;
drop i;
run;
My output:
> **start |end |tik1 | tik2 |tik3 |tik4**
> 22Jun2015 |22Oct2015 |27Jul2015| 26Aug2015|25Sep2015|
> 09Jan2015 |15May2015 |13Feb2015| 15Mar2015|14Apr2015|14May2015
I tend to prefer long vertical structures. I would approach it like:
data want;
set have;
tik=start+35;
do while(tik<=end);
output;
tik=tik+30;
end;
format tik mmddyy10.;
run;
If you really need it wide, you could transpose that dataset in a second step.

use a character date string as a date in data step

I have the following two macro variables:
%let start_date = 29MAY2014;
%let end_date = 15JUL2014;
I would like to create a dataset which is a series of dates between these (inclusive.) I cannot change the input format of the macro variables &start_date and &end_date.
I have tried many variations of the following, but SAS spits out an error for each:
data base_dates;
do date = put("&start_date",date9.) to put("&end_date",date9.);
output;
end;
format date date11.;
run;
Any help in this would be much appreciated
Use them as date literals, enclose in quotes and add a d at the end.
Do date = "&start_date"d to "&end_date"d;
It was simple; input() instead of put()
data base_dates;
do date = input("&start_date",date9.) to input("&end_date",date9.);
output;
end;
format date date11.;
run;

sas date format to read yyyymmdd

I have imported a dataset to SAS using Proc import. Now the problem is I can't change the date format in that dataset. In data the date is in YYYYMMDD for sales date, i wanted to change this is as 02Dec2005. Please find the data below. Please find the SAS code for import
DATA:
StoreID SalesDate InvoiceNumber ProductCode qty SalesType Brick
A0110515 20051205 225004 3519671 1 0 1638
proc import out=sample datafile="C:\Users\Vigneshwaran\Desktop\Vignesh\vipin1.txt"
dbms=tab replace;
getnames=yes;
datarow=2;
run;
Thanks and Regards,
V
You have to use a separate step. PROC IMPORT does not allow you to change formats.
PROC DATASETS can be used to change formats (among other things).
proc datasets lib=work nolist;
modify sample;
format SalesDate date9.;
run;
quit;
There can be 2 Solutions based on how your data was imported and what is the attribute of SalesDate column,
/* IF SalesDate is imported as Numeric */
proc datasets lib=work nolist;
modify sample;
format SalesDate date9.;
run;
/* IF SalesDate is imported as Character */
data want;
set sample(rename=(salesdate=sdate));
length SalesDate 8.;
format SalesDate date9.;
SalesDate=input(SDate,yymmdd8.);
drop SDate;
run;
Try this:
salesdate_1 = input(put(salesdate,10.),yymmdd10.);
and then add just your format date9.
I always work with this.
PROC DATASETS can be used to change formats. But PROC IMPORT is going to read 20051205 as an integer number. Interpreted as a DATE value, that would be 20,051,205 days after January 1, 1960. That's more than 20,000 years after 1960. December 5, 2005 is 16775 days after January 1, 1960. So you need to transform the numeric to character then back to numeric.
My suggestion would be to run the PROC IMPORT interactively and save the code. You can then modify the code, adding something like
SaleDate = INPUT(PUT(salesdate,8.),YYMMDD8.) ;
FORMAT SaleDate DATE9. ;
to convert the integer number into a SAS date. If modifying the code isn't possible, either run a data step with the above transformation, or PROC SQL with the same transformation after the IMPORT.
DATA final (RENAME=(saledate=salesdate));
SET sample ;
SaleDate = INPUT(PUT(salesdate,8.),YYMMDD8.) ;
FORMAT SaleDate DATE9. ;
DROP salesdate ;
RUN ;
or
PROC SQL STIMER EXEC ;
CREATE TABLE final AS
SELECT StoreID, INPUT(PUT(salesdate,8.),YYMMDD8.) AS SalesDate,
InvoiceNumber, ProductCode, qty, SalesType, Brick
FROM sample
;
QUIT ;
where the PROC SQL would be followed by DomPazz' PROC DATASETS to change the format to DATE9.

convert numeric date into DATE in SAS Enterprise Guide

I have a date column which dates are showing as numeric, such as "201101", "201203"...
How can I convert these numeric date into format as "Jan2011", "Mar2012" by using SAS enterprise?
Thanks!
You can do it like this:
DATA test;
input date;
CARDS;
201101
201203
;
RUN;
data test2;
set test;
date2 = input(put(date,6.),yymmn6.);
format date2 monyy7.;
run;
Marti Mayo's answer is correct - but just wanted to point out that it only needs the one step:
DATA test;
format date monyy7. ; *<--- Sets the format you want to view (JAN2011) ;
input date :yymmn6.; *<--- Sets the informat of what you read in(201101);
CARDS;
201101
201203
;RUN;

SAS how to change a date format in a where clause

I have some data which has the date stored in the yymmn6. format and others that are stored in the date9. format
I want to do a proc sql statement using the where clause but in order to compare two dates the date9. fields need to be in the yymmd6. format
is there an equivalent of this which can be used in the where clause
proc sql;
select dt format=yymmn6.,
from have;
quit;
i.e.
proc sql;
select *
from have WHERE dt format=yymmn6. = other_date;
quit;
A SAS variable formatted as a date is simply a number (representing days since 01JAN1960).
If other_date is also a SAS date value (regardless of format), you don't need to apply a format to either variable.
If other_date is a string representing a date (e.g. 201501), you can apply the format to dt, or input other_date to a SAS date.
/* Apply format to dt to match other_date */
proc sql ;
select *
from have
where put(dt,yymmn6.) = other_date ;
quit ;
/* Be careful here though as 201501 will input as 2015-01-01 */
proc sql ;
select *
from have
where dt = input(other_date,yymm6.) ;
quit ;