Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 变量的sas循环超过一个月_Loops_Date_Sas - Fatal编程技术网

Loops 变量的sas循环超过一个月

Loops 变量的sas循环超过一个月,loops,date,sas,Loops,Date,Sas,我正在尝试循环一系列的日期,以便在它们之间创建日期。这将以月为单位进行,始终显示相应月份的最后一天。给出了开始和结束日期(第一个日期和最后一个日期),而最后一个日期应始终指上个月的结束 data want ; set have ; do offset=0 to intck('month',first_date,last_date)-1; date=intnx('month',first_date,offset,'e'); output; end; format d

我正在尝试循环一系列的日期,以便在它们之间创建日期。这将以月为单位进行,始终显示相应月份的最后一天。给出了开始和结束日期(第一个日期和最后一个日期),而最后一个日期应始终指上个月的结束

data want ;
  set have ;
  do offset=0 to intck('month',first_date,last_date)-1;
    date=intnx('month',first_date,offset,'e');
    output;
  end;
  format date yymmdd10.;
run;
原始数据集如下所示:

customer id   first_date  last_date 
xy       135  01.01.2000  25.03.2005 
xy       247  19.03.2003  25.03.2005 
ab       387  01.06.2010  30.12.2012 
ab       128  01.05.2010  28.02.2011 
...
我的目标是创建一个如下所示的数据集:

customer id   date
xy       135  31.01.2000
xy       135  28.02.2000
...
xy       135  28.02.2005
xy       247  31.03.2003
xy       247  30.04.2003
...
xy       247  28.02.2005
我发现迭代天数的解决方案非常简单(见下文),但我很难实现每月步骤和月末日期

data want;
set have;
by customer id;
do day = first_date to last_date;
output;
end;
format day date9.;
run;

谢谢你的帮助

首先,让我们获取一些数据:

data have;
  attrib customer length=$10 informat=$10.
        id         informat=best.
        first_date informat=ddmmyy10. format=ddmmyy10.
        last_date  informat=ddmmyy10. format=ddmmyy10.
        ;

  input customer $
        id
        first_date
        last_date 
        ;

datalines;
xy       135  01.01.2000  25.03.2005 
xy       247  19.03.2003  25.03.2005 
ab       387  01.06.2010  30.12.2012 
ab       128  01.05.2010  28.02.2011 
;
run;
intnx()
函数将在这里起到解救作用。我们将创建一个名为date的新变量,然后使用intnx函数返回该日期的月末。只要该日期小于结束日期,我们将继续将其输出到数据集,然后递增到下个月底

data want;
  format date ddmmyy10.;

  set have;

  date = intnx('month',first_date,0,'end');
  do while (date le last_date);
    output;
    date = intnx('month',date,1,'end');
  end;

  drop first_date last_date;
run;

虽然我认为Rob的答案是正确的,但看看如何用你尝试的方式来做可能会有所帮助

从这一点开始:

data want;
 set have;
 by customer id;
 do day = first_date to last_date;
  output;
 end;
 format day date9.;
run;
这会给你太多的行,对吗?所以你需要做的是确定你在这个月的位置。有很多方法可以做到这一点。几个日期函数(如INTNX和INTCK)可以用来告诉你在哪里;但最简单的方法是将
月(日期)
月(日期+1)
进行比较。当他们不一样的时候,你是在一个月的最后一天

data want;
  set have;
  by customer id notsorted;
  do day = first_date to last_date;
    if month(day) ne month(day+1) then output;
  end;
  format day date9.;
run;
(我添加了
notsorted
,因为Rob的示例数据没有排序,我很懒。在您的实际案例中可能不需要。)


我要指出的是,这可能不是您理想的解决方案——Rob的可能是,就数据步数而言——就速度而言。当然,这将每天迭代,而不是每月迭代一次。

如果您有上面创建的数据集(每天一行),另一个选项是使用,如果您有ETS模块。这样的东西很方便

data intermediate;
  set have;
  by customer id notsorted;
  do day = first_date to last_date;
    output;
  end;
  format day date9.;
run;;;
这是你的日常数据。下面是PROC EXPAND语句,要求每月提供数据,并在末尾对齐<代码>id日期标识时间序列变量,并按客户id排序
是normal by语句(哪些变量标识观察值),带有
NOTSORDED
,因此它们之间不必相对有序

proc expand data=intermediate out=want from=day to=month align=end;
  id day;
  by customer id notsorted;
run;

这给出了一个与Rob和我的另一个解决方案稍有不同的解决方案,因为如果不是在月底,它会给出每个解决方案的最后一行(并将最后一行设置为月底)。如果这是需要的,很好,我们的解决方案可以很容易地进行调整,以实现这一点;如果不需要,您必须在以后删除它。

您可以使用日期间隔函数通过简单的迭代
do
循环来完成此操作。从间隔数中减去一,使其在上个月的最后一天结束

data want ;
  set have ;
  do offset=0 to intck('month',first_date,last_date)-1;
    date=intnx('month',first_date,offset,'e');
    output;
  end;
  format date yymmdd10.;
run;

回答得好。我发现将其编写为,
date\u start=intnx('month',first\u date,0,'end')更直观一些(特别是对于习惯于执行x=y到z循环的程序员);do incr=1乘1,而(最后日期);产出;日期=intnx('月份',开始日期,增加日期,'结束');结束你最终得到了同样的结果,这让我更直观。有趣的是,我最近看到了一些答案,人们使用了这种风格,而我以前从未真正看到过。来自compsci的背景,我刚刚在学校学习了3个基本的C型循环(for、while和do…while),我在SAS中使用了相同的循环结构。实际上,这是一个C型循环
for(incr=1;date le last_date;incr++)
将是c等价物。SAS只是组织方式有点不同。这非常有效!谢谢!我需要更熟悉intnx函数!好的,详细的问题!如果最后一天实际上是一个月的最后一天呢?(即
last_date='2014年12月31日;
)@Joe-如果最后一天是一个月的结束,那么我对请求的理解是他们想要上个月的最后一天。因此,对于2014年12月31日的
2014年11月30日的