I have a table where I compare the results week to week.
I have aggregations of old dates using these functions.
%let date_old=%sysfunc(intnx(year,%sysfunc(Today()),-1,s));
%put &=date_old;
proc format;
value vintf low-&date_old = 'OLD' other=[yymmd7.];
run;
/*agregujemy wyniki do daty vintf jako old*/
proc summary data=tablea_new nway;
class policy_vintage;
format policy_vintage vintf.;
var AKTYWNE WYGASLE;
output out=newtabe sum=;
And I would like to do exactly the same, only to aggregate the dates to show the yearly range, i.e. 2021-01-2022-01. Or the current year 2021-01-2021-12. Is the following sample okay? What's the best way to do this?
%let date_future=%sysfunc(intnx(year,%sysfunc(Today()),+12,s));
%put &=date_future;
proc format;
value vintfutr +&date_future= 'FUTURE' other=[yymmd7.];
run;
%let date_old=%sysfunc(intnx(year,%sysfunc(Today()),-1,s));
%let date_future=%sysfunc(intnx(year,%sysfunc(Today()),+1,s));
proc format;
value vintf
low-&date_old = 'OLD'
&date_future-high = 'FUTURE'
other=[yymmd7.]
;
run;
Related
Good afternoon,
I am decent with SAS but I've never written macros.
I have a DB where I need to break out in separate datasets ID's where the date in a field occurs. E.g. All ID's with a date in Jan 2018 would be one dataset, All ID's with a date in Feb 2018 would be another data set, so on and so forth. Field name is ZDate.
I found this which seems to do exactly what I want. However I think my date isn't in the correct format. The date I'm pulling is in a timestamp in snowflake and I'm converting it to a date with to_date. It's showing as formatted date (16FEB2020) in the original vintagedata data set but the subsequent data sets are completely blank.
%macro month;
%local mindate maxdate i date month ;
proc sql noprint;
select min(ZDate),max(ZDate)
into :mindate , :maxdate
from vintagedata
;
quit;
data
%do i=0 %to %sysfunc(intck(month,&mindate,&maxdate));
%let date=%sysfunc(intnx(month,&mindate,&i));
%let month=%sysfunc(putn(&date,monyy7.));
&month
%end;
;
set vintagedata;
%do i=0 %to %sysfunc(intck(month,&mindate,&maxdate));
%let date=%sysfunc(intnx(month,&mindate,&i));
%let month=%sysfunc(putn(&date,monyy7.));
if intnx('month',date,0)=&date then output &month ;
%end;
run;
%mend;
%month;
I have a column with name total transaction. I want to add a date 4 days back from now in its name .
For example if today is 20161220 so I want my variable to be renamed as total_transaction_20161216.
Please suggest me a way out of my problem.
Just create a macro variable that stores the required date format and then use that in a rename statement within proc datasets.
%let datevar = %sysfunc(intnx(day,%sysfunc(today()),-4),yymmddn8.);
%put &=datevar.;
data have;
total_transaction=1;
run;
proc datasets lib=work nolist nodetails;
modify have;
rename total_transaction = total_transaction_&datevar.;
quit;
How can I print (and export to file) monthly and weekly average of value? The data is stored in a library and the form is following:
Obs. Date Value
1 08FEB2016:00:00:00 29.00
2 05FEB2016:00:00:00 29.30
3 04FEB2016:00:00:00 29.93
4 03FEB2016:00:00:00 28.65
5 02FEB2016:00:00:00 28.40
(...)
3078 08MAR2004:00:00:00 32.59
3079 05MAR2004:00:00:00 32.75
3080 04MAR2004:00:00:00 32.05
3081 03MAR2004:00:00:00 31.82
EDIT: I somehow managed to get the monthly data but I'm returning average for each month separately. I would to have it done as one result, namely Month-Average+export it to a file or a data set. And still I have no idea how to deal with weeks.
%macro printAvgM(start,end);
proc summary data=sur1.dane(where=(Date>=&start
and Date<=&end)) nway;
var Value;
output out=want (drop=_:) mean=;
proc print;
run;
%mend printAvgM;
%printAvgM('01jan2003'd,'31jan2003'd);
EDIT2: Here is my code, step by step:
libname sur 'C:\myPath';
run;
proc import datafile="C:\myPath\myData.csv"
out=SUR.DANE
dbms=csv replace;
getnames=yes;
run;
proc sort data=sur.dane out=sur.dane;
by Date;
run;
libname sur1 "C:\myPath\myDB.accdb";
run;
proc datasets;
copy in=sur out=sur1;
select dane;
run;
data sur1.dane2;
set sur1.dane;
date2=datepart(Date);
format date2 WEEKV11.;
run;
The last step results in NOTE: SAS variable labels, formats, and lengths are not written to DBMS tables. and the format of dane2 variable is DATETIME19..
Ok, it's small enough to handle easily then. I would recommend first converting your datetime variable to a date variable using DATEPART() function and then use a format within PROC MEANS. You can look up the WEEKU and WEEKV formats to see if they meet your needs. The code below should be enough to get you started. You could do the monthly without the date conversion, but I couldn't find a weekly format for the datetime variable.
*Fake data generated;
data fd;
start=datetime();
do i=1 to 3000000 by 120;
datetime=start+(i-1)*30;
var=rand('normal', 25, 5);
output;
end;
keep datetime var;
format datetime datetime21.;
run;
*Get date variable;
data fd_date;
set fd;
date_var = datepart(datetime);
date_month = put(date_var, yymon7,);
Date_week = put(date_var, weekv11.);
run;
*Monthly summary;
proc means data=fd_date noprint nway;
class date_var;
var var;
output out=want_monthly mean(var)=avg_var std(var)=std_var;
format date_var monyy7.;
run;
*Weekly summary;
proc means data=fd_date noprint nway;
class date_var;
var var;
output out=want_weekly mean(var)=avg_var std(var)=std_var;
format date_var weekv11.;
run;
Replace date_var with the new monthly and weekly variables. Because these are character variables they won't sort properly.
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.
%macro example
%let begdate = ’01Nov2004’d;
%let enddate = ’30Nov2004’d;
proc sort data=test out=test2;
where date between &begdate and &enddate;
by date;
run;
%mend example;
This code gives me the error: ERROR: Syntax error while parsing WHERE clause.
However, when I simply replace &begdate and &enddate by corresponding values, it works.
I normally run mine like this:
%macro example
%let begdate = 01Nov2004;
%let enddate = 30Nov2004;
proc sort data=test out=test2;
where date between "&begdate"d and "&enddate"d;
by date;
run;
%mend example;
I simply remove any assumptions of a date format and refer to the macro variable in the code as a string. Hope this helps!!