1
%let months_back = %sysget(months_back);

data;
        m = intnx('month', "&sysdate9"d, -&months_back - 2, 'begin');
        m = intnx('day', put(m, date9.), 26, 'same');
        m2back = put(m, yymmddd10.);
        put m2back;
run;

注意:字符值已在以下给出的位置转换为数值:(行):(列)。5:19 注意:无效的数字数据 '01OCT2012' ,位于第 5 行第 19 列。

我真的不知道为什么会出错。日期字符串是数字数据吗?

4

2 回答 2

4

PUT(m, date9.) 是这里的罪魁祸首。INTNX 的第二个参数必须是数字(即日期),PUT 函数总是返回一个字符值,在本例中为“01OCT2012”。只需完全取出 PUT 功能,代码就可以工作了。

m = intnx('day', m, 26, 'same');
于 2012-12-04T13:09:42.547 回答
1

SAS 将日期存储为数字 - 实际上并没有真正独立的类型。SAS 日期是自 1960 年 1 月 1 日以来的天数,因此今天略高于 19000 天。日期格式与任何日期计算完全无关 - 它仅用于人类可读性。

你说的那一点:

"&sysdate9"d

实际上将字符串“01JAN2012”转换为数值(18304)。

实际上,有一种更快的方法可以完成您正在尝试做的事情。因为天对应于 SAS 中的整数,所以要增加一天,您只需将值加一即可。

例如:

%let months_back=5;
data _null_;
        m = intnx('month', today(), -&months_back - 2, 'begin');
        m2 = intnx('day', m, 26, 'same');
        m3 = intnx('month',"&sysdate9"d, -&months_back - 2)+26;
        m2back = put(m2, yymmdd10.);
        put m= date9. m2= yymmdd10. m3= yymmdd10.;
run;

M3 通过使用 MONTH 间隔,然后添加 26 一步完成整个计算。 INTNX('day'...) 基本上没有意义,除非使用该函数有其他价值(例如使用移位索引)。

您还可以在此处的 PUT(log) 语句中看到格式的使用 - 您不必将其放入字符值然后将其放入日志以获取格式化值,只需放入 (var) (format .); - 并以这种方式尽可能多地串在一起。

此外,“&sysdate9.”d 不是获取当前日期的最佳方式。&系统日期。仅在 SAS 启动时定义,因此如果您的会话运行了 3 天,您将不会在当天(尽管这可能是需要的?)。相反,TODAY() 函数获取当前日期,无论您的 SAS 会话运行了多长时间,都是最新的。

最后 -data _null_;如果您不想要数据集,我建议您(如果您确实想要,请命名结果数据集)。 data _null_不创建数据集。数据; 只需创建越来越多的数据集(data1、data2、...),这些数据集会迅速填满您的工作空间,让您很难分辨出您在做什么。

于 2012-12-04T16:07:43.073 回答