Can create a subset based on date - sas

I have the following dataset and code:
DATA survey;
INPUT id order_date ;
DATALINES;
1 11JAN2007
2 12JAN2007
3 14JAN2007
;
PROC PRINT; RUN;
data work;
set survey;
where '11JAN2007'<= order_date <= '13JAN2007';
proc print data=work;
run;
When I run this code it does give the desired output however. It only gives a table with three empty order_date columns.
Any thoughts on what goes wrong here?

This would work:
DATA survey;
informat order_date date9. ;
INPUT id order_date ;
DATALINES;
1 11JAN2007
2 12JAN2007
3 14JAN2007
;
RUN;
PROC PRINT data = survey;
format order_date date9.;
RUN;
data work;
set survey;
where '11JAN2007'd<= order_date <= '13JAN2007'd;
run;
proc print data=work;
format order_date date9. ;
run;
See SAS help for topics date, informat,...

If you want to query based on date, you need to tell SAS that your string is a date. You do this by putting a 'd' after the date string, e.g.
'11JAN2007'd

Related

Convert number to SAS date with a DATE9 format

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;

Classify records based on a date

I have the following dataset:
DATA survey;
informat order_date date9. ;
INPUT id order_date ;
DATALINES;
1 11SEPT20016
2 12AUG2016
3 14JAN2016
;
RUN;
PROC PRINT data = survey;
format order_date date9.;
RUN;
What I would like to do now is classify the records based on their last visit. So what I want to do is:
Set a date (fe, 10SEPT 2016)
Classify all records that have a lastvisit > 30days as 1, Classify all records that have a lastvisit > 60days as 2 etc...
Any thoughts on how I need to program this?
You could build something like this (count the days between the dates, divide them by 30 and ceil them). Alternativly, if you want to use months and not 30 days, you can replace the first intck parameter with 'month' and remove the ceil and /30:
DATA survey;
informat order_date date9. ;
INPUT id order_date ;
DATALINES;
1 11SEP2016
2 12AUG2016
3 14JAN2016
4 09SEP2016
5 10AUG2016
;
RUN;
%let lastvisit=10SEP2016;
data result;
set survey;
days_30=ceil(intck('days', order_date,"&lastvisit"d)/30)-1;
run;
PROC PRINT data = result;
format order_date date9.;
RUN;

Reading in Data into SAS using 'Where' function

For some reason I'm not being able to read in the data properly. I want to be able to read in a large data set but within only specific dates such as Jan 2004 to FEB 2004. My Code is the following:
DATA Work.sales_fact;
SET Work.sales_fact_subset;
WHERE '01JAN2004'd <= Order_Date <= '14FEB2004'd;
RUN;
PROC PRINT;
RUN;
What am I doing incorrectly?
I think you have DATA and SET switched. DATA is what you want to create. SET is where the data is coming from.
DATA Work.sales_fact_subset ;
SET Work.sales_fact;
WHERE '01JAN2004'd <= Order_Date <= '14FEB2004'd;
RUN;
PROC PRINT data=Work.sales_fact_subset;
RUN;
Here is an example of this working..
Please check your dataset.
data want;
set sashelp.rent;
where "01feb1999"d <= date <= "02feb2003"d;
run;
If your table names and date structure is correct, your query is correct. Here is a sample of what I did with the correct result set.
data inputs;
input Date1 date9. ;
Format date1 date9.;
cards;
01JAN2004
02FEB2004
03MAR2004
04JUN2004
05JUL2004
;
DATA inputss;
SET inputs;
WHERE '01JAN2004'd <= Date1 <= '14FEB2004'd;
RUN;
PROC PRINT;
RUN;

How to calculate 'age last birthday' on a given date for a given birthday in SAS PROC SQL step

I want to calculate 'age last birthday' on a specific evaluation date, given a specific date of birth, using a SAS PROC SQL command.
How can I do this and are there any limitations?
Sample Input
DATA INPUTS;
infile cards dlm=',' dsd;
INPUT DOBDt :DATE9. EvalDt :DATE9. expected;
FORMAT DOBDt date9. EvalDt date9.;
CARDS;
11MAY2009,10MAY2015,5
11MAY2009,11MAY2015,6
11MAY2009,12MAY2015,6
28FEB1984,01DEC2015,31
29FEB1984,28FEB2012,27
29FEB1984,29FEB2012,28
29FEB1984,01MAR2012,28
;
RUN;
The goal would be to take the dobDt as an input, evaluate on the EvalDt and produce the answer of expected
This can be done as such :
PROC SQL
PROC SQL;
CREATE TABLE outputs2 AS
select
*
,intck('year',DOBDt,EvalDt,'c') AS actual
,((calculated actual) eq expected) AS check
FROM
inputs
;
QUIT;
actual, the calculated value, matches expected, the desired outcome, for all the examples provided. I am not aware of any limitations to this approach although there are probably some extreme ages that it cannot calculate due to SAS dates having a limited range of values.
As a bonus:
DATA STEP
DATA outputs;
set inputs;
actual = intck('year',DOBDt,EvalDt,'c');
check = (actual eq expected);
RUN;
This is how we used to do it back in the day. Also "age at last birthday" seems pretty clear to me.
DATA INPUTS;
infile cards dlm=',' dsd;
INPUT DOBDt :DATE9. EvalDt :DATE9. expected;
FORMAT DOBDt date9. EvalDt date9.;
age = year(evaldt)-year(dobdt) - (month(evaldt) eq month(dobdt) and day(evaldt) lt day(dobdt)) - (month(evaldt) lt month(dobdt));
CARDS;
11MAY2009,10MAY2015,5
11MAY2009,11MAY2015,6
11MAY2009,12MAY2015,6
28FEB1984,01DEC2015,31
29FEB1984,28FEB2012,27
29FEB1984,29FEB2012,28
29FEB1984,01MAR2012,28
;;;;
RUN;
proc print;
run;

SAS MACRO FROM PROC SQL DATE ERROR

Hello I am trying to put an specific date from a dataset into a macro so i can use it in a DATA step , but i always get 01-JAN-1960 insteed of the date that i want
my code is the next one:
proc sql noprint ;
select WEEK_START
into :WEEK_START
from date_table
WHERE FW= 5;
quit;
%let start=&WEEK_START;
%LET TODAY= TODAY();
I made this so i can see the date that i want:
DATA TEMP;
DATE =&TODAY;
DATE1= &start;
FORMAT DATE DATE1 datE11.;
RUN;
And the result is:
DATE : 06-OCT-2014
DATE1 : 01-JAN-1960
proc sql noprint ;
select today()-1 as WEEK_START
into :WEEK_START
from maps.africa;
quit;
%let start=&WEEK_START;
%LET TODAY= TODAY();
DATA TEMP;
DATE =&TODAY;
DATE1= &start;
FORMAT DATE DATE1 datE11.;
RUN;
When I run this, both populate correctly.
Additionally, the value of Date1 in your example is the date value for the numeric value of 0. It looks like your original data is being populated incorrectly.