How to convert characteristic date time into numberic ones in SAS? - sas

I have a column called month as
month
JAN
FEB
...
DEC
I'd like to know how to convert them into 1,2,3,...,12 in SAS. Thanks a lot.

Use informat to convert it to number and use month() to get the month.
data have;
input month :$3. ##;
datalines;
JAN FEB DEC
;
data want;
set have;
x=month(input(month||'21',??monyy.));
run;

Concatenate the month with a year, make use of the MONYY. informat, use the MONTH. format and finally output as a numeric value using another input().
data have;
input month :$3. ##;
datalines;
JAN FEB DEC
;
data want;
set have;
month_num=input(put(input(catt(month, year(today())), monyy.), month.), 2.);
put month month_num;
run;
Results:
JAN 1
FEB 2
DEC 12

Related

Looking to create a cumulative column in SAS

Example Dataset:
record_id admin_dt_1
1 June 7th 2022
2 August 25th 2022
3 August 23rd 2022
4 July 8th 2022
5 August 5th 2022
I would like my output to show in the first column September 1st...2nd...so on to 30th which I have done but I would like the second column to show the number of people eligible for each day in September. Eligible means anyone after 28 days from their admin_dt_1. I also want the column to be cumulative it should look something like this: Since there are 5 data points it should add up to 5 in the frequency column.
Date Frequency eligible
September 1st 3
September 30th 5
data dose2eligible;
set request;
/*create September 1st to September 30th date*/
do date= '01sep2022'd to '30sep2022'd;
output;
end;
format
date date9.;
run;
proc freq data=dose2eligible; table date; run;
You were very close. Count the number of days between admin_dt_1 and date, then create a 1/0 flag using the shortcut var = (boolean comparision):
eligible = (admin_dt_1 - date > 28);
data dose2eligible;
set request;
/*create September 1st to September 30th date*/
do date= '01sep2022'd to '30sep2022'd;
eligible = (admin_dt_1 - date > 28);
output;
end;
format date date9.;
run;
You can then count the number of eligible people on each date:
proc sql;
select date
, sum(eligible) as total_eligible
from dose2eligible
group by date;
quit;

I want to extract month data from a datetime format column in SAS

I have a data in format 01 Jan 19.00.00 (datetime), and I want to extract the month name only from it.
Tried the below code but getting output in numbers i.e. 1 2 3 and so on. I want the output either in Jan Feb mar format or January February march format.
data want;
set detail;
month = month(datepart(BEGIN_DATE_TIME));
run;
You can use the MONNAME format.
data test;
dt = datetime();
monname = put(datepart(dt),MONNAME.);
put monname=;
run;
If you want "OCT" not "OCTOBER" you can add a 3 to the format (MONNAME3.).
If you are using the value in a report the better approach might be to use a date value formatted with MONNAME.
The values of a date formatted variable will be ordered properly when the variable is used in a CLASS or BY statement. If you had instead computed a new variable as the month name, the default ordering of values would be alphabetical.
data want;
set have;
begin_date = datepart(BEGIN_DATE_TIME);
format begin_date MONNAME3.;
run;

SAS Line graphs from Data in a row rather than column

I've searched but none of the information shows how to plot a line graph from data that is given in a row, rather than column.
I have data in this form:
Firstname Lastname Sep Oct Nov Dec Jan Feb March April May June July
There are 100 rows of data with individual people. I have to plot each graph for each individual starting from Sep To July. My output will be 100 individual graphs. I know how to plot if the data is in column, but that is not what i am given. Changing the data is going to be too much work. I do not have any sas codes for rows:
**Proc sgplot data=data1;
series x=??? ( i need mths from Sep to July here)
Series y= ?? (will be the marks from the Sep to July)
Run;**
Here is how the output should look:
Your table needs to be in a flat format, e.g.:
FirstName LastName Date
John Smith 01JAN2018
Jane Doe 01JAN2018
This can be done with PROC TRANSPOSE. It is best to align your dates to a specific year/date. This will maintain the correct date order. Assume that your data is for 2018.
Create sample data
data have;
length name $10.;
array months[*] Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec;
retain goal 75;
do name = 'Mark', 'Jane', 'Jake', 'John', 'Jack', 'Jill', 'Bill', 'Jerry', 'Joseph';
do i = 1 to dim(months);
months[i] = round(100*rand('uniform') );
end;
output;
end;
drop i;
run;
Solution
proc sort data=have;
by name goal;
run;
proc transpose data=have
out=have_transposed;
by name goal;
var Jan--Dec;
run;
data want;
set have_transposed;
Month = input(cats('01', _NAME_, 2018), DATE9.);
rename COL1 = Score;
format month monname3.;
drop _NAME_;
run;
proc sgplot data=want;
by name;
series x=month y=goal / name='goal' lineattrs=(color=salmon thickness=2);
series x=month y=score / name='series' lineattrs=(thickness=2);
scatter x=month y=score / markerattrs=(symbol=circlefilled) name='points';
keylegend 'series' 'goal';
run;

how to read 20 march 2011 date in sas

I am trying to read 20 march 2011 date using worddatx32. format but it cant read it gives an error was not found or could not be loaded.
I also try anydtdte32. but it give . in output
how can I read 20 march 2011 date in data lines
data sample;
infile datalines truncover dsd;
input JDate : worddatx32.;
format JDate date9.;
datalines;
20 march 2011
;
run;
WORDDATX. is a FORMAT and you need an INFORMAT. Try using ANYDTDTE. as the informat.
data test ;
input xx anydtdte32. ;
format xx date9.;
put xx= #15 _infile_;
cards;
20 march 2016
20MAR2016
;
Also if you are going to use the : modifier then SAS will stop at the space and only read the 20. Add the & modifier and it will stop when it sees two or more spaces. Of if you are using delimited input then just use an INFORMAT statement.
data test ;
infile cards dsd truncover ;
input xx ;
informat xx anydtdte. ;
format xx date9.;
put xx= #15 _infile_;
cards;
20 march 2016
20MAR2016
;
NOTE: The ANYDTDTE. informat does not support this format before SAS version 9.4
If you cannot use the informat then read the value as three fields and convert it yourself.
input d $ m $ y $ ;
date = input(cats(d,substr(m,1,3),y),date9.);
Not sure why Tom's solution doesn't work on your machine... Here's another possibility:
data mydates;
infile datalines dsd truncover delimiter=" ";
informat day 8.
month $3.
year 8.;
format mydate date9.;
input day month year;
mydate = input(cats(day, month, year),date9.);
datalines;
20 march 2016
18 december 16
;

Modify SAS dataset

I have a SAS dataset that looks like this:
id | Date | ...
1 17 Jun
1 19 Jun
2 17 Jun
2 19 Jun
2 21 Jun
3 12 May
each id represents a unique person.
I want to keep only 1 row for each unique person, however, still keep the date in dataset.
TO achieve this, I need to transform the table into format such as:
id | Date1 | Date2 | Date 3
1 17 Jun 19 Jun
2 17 Jun 19 Jun 21 Jun
3 12 May
If only 1 date has been assigned to that person, then keep the date2 and date3 as missing value.
The full dataset I'm using contains thousands of observations with over 180 different days. However, a unique person will at most be assigned to 5 different days.
Any help appreciated
PROC SUMMARY has functionality to do this, using the IDGROUP statement. The code below will transpose the data and create 5 date columns (specified by out[5]), in date order (specified by min(date)). If you want more information on how this works then check the IDGROUP statement in the PROC MEANS / SUMMARY documentation.
data have;
input id Date :date9.;
format date date9.;
datalines;
1 17Jun2012
1 19Jun2012
2 17Jun2012
2 19Jun2012
2 21Jun2012
3 12May2012
;
run;
proc summary data=have nway;
class id;
output out=want (drop=_:)
idgroup(min(date) out[5] (date)=);
run;
Using Proc Transpose, then using a Data Step (and borrowing Keith's data).
Both ways need the data sorted by ID.
data have;
input id Date :date9.;
format date date9.;
datalines;
1 17Jun2012
1 19Jun2012
2 17Jun2012
2 19Jun2012
2 21Jun2012
3 12May2012
4 01JAN2013
4 02JAN2013
4 03JAN2013
4 04JAN2013
4 05JAN2013
;
run;
proc sort data=have;
by id;
run;
Proc transpose data=have out=transpose(drop=_name_) prefix=DATE;
by id;
run;
data ds(drop=cnt date);
retain date1 date2 date3 date4 date5;
format date1 date2 date3 date4 date5 mmddyy10.;
set have;
by id;
if first.id then cnt=1;
select(cnt);
when(1) date1=date;
when(2) date2=date;
when(3) date3=date;
when(4) date4=date;
when(5) date5=date;
otherwise;
end;
cnt+1;
if last.id then do;
output;
call missing(of date1-date5);
end;
run;