Sas 日期之间的循环

Sas 日期之间的循环,sas,Sas,我创建了下面的宏,以根据date宏生成一些数据集 %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 pu

我创建了下面的宏,以根据date宏生成一些数据集

%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;

当必须从非SAS日期值的值中推断日期信息时,您需要
输入信息以获得日期值,并
输入迭代的值以获得所需的非日期表示形式

这个例子演示了

  • INPUTN函数使用informat YYMMDD8将YYYYMMDD参数解析为日期值
  • INTNX函数用于计算日期月份的第一个值
  • PUTN函数,用于使用YYMMDDN8格式将日期值转换为YYYYMMDD表示形式
  • %执行%WHILE语句进行迭代
  • INTNX函数将迭代变量提前到下个月初
代码

%macro pull(yyyyymmdd);
%本地输出;
%放出=拉出&yyyymmdd;
数据输出;
pull_date=输入(“&yyyymmdd”,yymmd8”);
格式拉取日期yymmdd10。;
跑
%修补;
%每个月的宏拉动(开始=,结束=);
%本地的
开始日期结束日期
开始月份结束月份
拉动日期拉动ymd
;
%注意:&=开始&=结束;
%让开始日期=%sysfunc(输入(&begin,yymmdd8.);
%让end_date=%sysfunc(inputn(&end,yymdd8.));
%请注意:&=开始日期&=结束日期;
%让begin_month=%sysfunc(intnx(month,&begin_date,0));
%设end_month=%sysfunc(intnx(month,&end_date,0));
%注意:&=开始月份&=结束月份;
%让pull\u month=&开始\u month;

%做%while(&pull\u month)您尝试过什么?您知道区间函数,如
INTNX
?您知道SAS日期值和SAS日期格式吗?您真的需要单独的数据集吗?为什么不直接使用
where date between&date1和&date2
。您可能对SAS宏附录感兴趣,它有一个演示宏列表,一个它显示了如何循环浏览日期。请参阅此处的示例代码列表,其中包括完整的解释。谢谢richard。但是,我们是否有可能不用%macro和%mend就可以执行此操作?您不能使用宏逻辑(
%do
%if
)宏外部。感谢chen提供的代码。但我不想使用%macro和%mend。我只想声明两个宏变量%let beg=“01jan2000”d;%let end=“01jan2001”d;并使用这些值生成数据集,而不是给它%pull(),所以我不想通过%pull(2017010120170501)手动输入日期。它需要从%let宏中选择
%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
)
%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)