在日期之间循环

时间:2018-04-28 11:15:55

标签: sas

我创建了下面的宏来生成基于日期宏的几个数据集。

%macro pull(date);

proc sql;

create table new&date as 

select * from acct

where date=&date.;

quit;

%mend;

因此,如果我想为20170101 20170201 20170301 20170401 20170501创建数据集,我所能做的就是使用下面的宏

%macro pull(20170101)

%macro pull(20170201)

%macro pull(20170301)

%macro pull(20170401)

%macro pull(20170501)

我现在正计划创建两个宏变量

%let begin=20170101;

%let end =20170501;

使用循环创建基于开始和结束的数据集。是否可以这样做。所以我要做的是将开始日期和结束日期作为宏变量,并从acct数据集中提取开始日期和结束日期之间的记录,并在开始日期和结束日期之间为每个月创建单独的数据集

注意数据集包含每年的月度日期。

以下是我正在尝试的代码

%let beg="01jan2000"d;
%let end="01jan2001"d; 
%macro Test;
%do date=&beg. %to &end.;
proc sql;
create table IPw_&date. as  
select *
from sample
where date=&date. quit;
%end;
%mend;
%Test;

2 个答案:

答案 0 :(得分:1)

当必须从不是SAS日期值的值推断出日期信息时,您需要input获取日期值的信息,并put迭代的值以获得所需的非日期表示。

此示例演示

  • INPUTN函数,使用信息YYMMDD8将YYYYMMDD参数解析为日期值。
  • INTNX函数,用于计算日期值的第1个月
  • PUTN功能,使用格式YYMMDDN8将日期值转换为YYYYMMDD表示。
  • %DO%WHILE语句用于迭代
  • INTNX函数,用于将迭代变量推进到下个月的开始

代码

%macro pull(yyyymmdd);
  %local out;

  %let out = pull_&yyyymmdd;

  data &out;
    pull_date = input ("&yyyymmdd", yymmdd8.);
    format pull_date yymmdd10.;
  run;
%mend;

%macro pull_each_month(begin=, end=);
  %local 
    begin_date end_date
    begin_month end_month
    pull_date pull_ymd
  ;

  %put NOTE: &=begin &=end;

  %let begin_date = %sysfunc(inputn(&begin,yymmdd8.));
  %let end_date   = %sysfunc(inputn(&end,yymmdd8.));

  %put NOTE: &=begin_date &=end_date;

  %let begin_month = %sysfunc(intnx(month,&begin_date,0));
  %let end_month   = %sysfunc(intnx(month,&end_date,0));

  %put NOTE: &=begin_month &=end_month;

  %let pull_month = &begin_month;
  %do %while (&pull_month <= &end_month);
    %let pull_ymd = %sysfunc(putn(&pull_month,yymmddn8.));
    %put NOTE: Invoking pull for &=pull_month &=pull_ymd;

    %pull (&pull_ymd)

    %let pull_month = %sysfunc(INTNX(MONTH,&pull_month,1));

  %end;
%mend;

%pull_each_month (
  begin = 20170101
, end   = 20170501
)

%macro pull_each_month(begin=, end=);
  %local 
    begin_date end_date
    begin_month end_month
    pull_date pull_ymd
  ;

  %put NOTE: &=begin &=end;

  %let begin_date = %sysfunc(inputn(&begin,yymmdd8.));
  %let end_date   = %sysfunc(inputn(&end,yymmdd8.));

  %put NOTE: &=begin_date &=end_date;

  %let begin_month = %sysfunc(intnx(month,&begin_date,0));
  %let end_month   = %sysfunc(intnx(month,&end_date,0));

  %put NOTE: &=begin_month &=end_month;

  %let pull_month = &begin_month;
  %do %while (&pull_month <= &end_month);
    %let pull_ymd = %sysfunc(putn(&pull_month,yymmddn8.));
    %put NOTE: Invoking pull for &=pull_month &=pull_ymd;
    %let pull_month = %sysfunc(INTNX(MONTH,&pull_month,1));
  %end;

%mend;

%pull_each_month (
  begin = 20170101
, end   = 20170501
)

答案 1 :(得分:0)

%macro pull(begin,end);
%let i=0;
%let begin=%sysfunc(inputn(&begin,anydtdte9.));
%let end=%sysfunc(inputn(&end,anydtdte9.));
%do %until (&begin=&end);
    %let begin=%sysfunc(intnx(month,&begin,&i));
    %let date=%sysfunc(putn(&begin,yymmddn8.));
    proc sql;
    create table new&date as 
    select * from acct where date=&date.;
    quit;
    %let i=%eval(&i+1);
%end;
%mend;

%pull(20170101,20170501)