我需要计算这相当于个月的两个日期之间的“最接近的”号码的图。然而,标准SAS功能(INTCK)不面向考虑其日期参数(下面例如代码解析为0,当我需要它舍入到1)。

的DAY

什么是解决这一问题的“最巧妙”的方式?

data _null_;
    x="01APR08"d;
    y="28APR08"d;
    z=intck('MONTH',x,y);
    put z= ;
run;

编辑:响应于Martins的评论

我想圆0个月 - 我不认为边界是相关的。我试图复制(NEAREST_MONTHS)函数来自DCS(Sung盯先知的应用程序)。我现在等待的机会来执行应用程序本身来了解更多关于它如何对待日期内的一些测试(会后的结果回到这里))。

帮助文件包含以下内容: 类别 日期

描述

,则返回到几个月的最接近的数字两个日期之间的差。如果第二个日期比第一个日期晚,则返回0。

语法

NEAREST_MONTHS(Later_Date,Earlier_Date)

返回类型 整数

实施例

NEAREST_MONTHS(DATE1,DATE2) 返回8如果日期1是20/3/1997和date2是23/7/1996

NEAREST_MONTHS(DATE1,DATE2) 返回26,如果日期1是20/3/1997和date2是1995年1月2日

有帮助吗?

解决方案

我写这是我认为计算方式相同的DCS应用程序的功能。它使用了一些功能,是新的SAS 9.2版本,包括日期,连续路线。它也可以向前或向后的时间(即给出了否定的整数,如果earlier_date是后later_date)。我用了15天以上超出区间为分界舍入到下个月,但如果你喜欢,你可以调整这一点。

proc fcmp outlib=work.myfuncs.dates;
   function nearest_months(later_date,earlier_date);
        /* Return missing if inputs are missing */
        if (earlier_date eq . ) OR (later_date eq . ) then
            nearest_month=.;
        else do; 
            /* Use 'cont' argument for continuous dates */
            months=intck('MONTH',earlier_date,later_date,'cont');
            if months < 0 then months=months+1;
            days= later_date - intnx('month', earlier_date,months,'same');

            /* Handle negatives (earlier dates) */
            if months < 0 then do;
                if days < -15 then months=months-1;
                nearest_month=months;
                end;
            else do;
                if days > 15 then months + 1;
                nearest_month=months;
                end;
        end;
        return(nearest_month);
   endsub;
run;
options cmplib=work.myfuncs;


data _null_;
x=nearest_months('20Mar1997'd, '23JUL1996'd);
put x=;
x=nearest_months('20Mar1997'd, '01FEB1995'd);
put x=;
run;

这给出了相同参考:

x=8
x=26

其他提示

您可以使用INTNX,看是否还是围捕下,e.g。


data _null_;
  format x y date9. z 8.;
  x="01APR08"d;
  y="28APR08"d;
  z=intck('MONTH',x,y);

  * wl is x + z months;
  wl=intnx('MONTH',x,z);

  * wu is x + (z+1) months;
  wu=intnx('MONTH',x,z+1);

  * If y is closer to wu, then adjust z by 1;
  if (abs(y-wu) lt abs(y-wl)) then z = z+1;     

  put x y z=;
run;

如果定义了一个月为30天,你会向下舍入为0个月15天以下,和16天或更长时间长达1个月。 这可以通过以下来实现:

data _null_;
  format x y date9. z 8.;
  x="14FEB09"d;
  y="02MAR09"d;

  z=round(intck('DAY',x,y)/31);
  put x y z=;
run;

您也可以采取的方法来算整月(“第一1日至最后一日”)的区间,然后添加任何剩余的天,看看他们总结为0,1或2个月。 像这样:

data _null_;
  format x y date9. z 8.;
  x="01FEB09"d;
  y="31MAR09"d;

  if day(x)=1 then do;
     z=intck('MONTH',x,intnx('MONTH',y,0,'BEGINNING'))
         + round((intck('DAY',intnx('MONTH',y,0,'BEGINNING'),y))/31);
  end;
  else do;
     z=intck('MONTH',intnx('MONTH',x,1,'BEGINNING'),intnx('MONTH',y,0,'BEGINNING'))
         + round((intck('DAY',x,intnx('MONTH',x,1,'BEGINNING'))+intck('DAY',intnx('MONTH',y,0,'BEGINNING'),y))/31);
  end;
  put x y z=;
run;

第一种方法更易于理解和维护,但第二对大的间隔(01FEB06到01FEB09为36个月,但方法1将告诉你这只是35)。

更精确
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top