基于宏变量的 SAS 子集
Posted
技术标签:
【中文标题】基于宏变量的 SAS 子集【英文标题】:SAS subsetting based on a macro variable 【发布时间】:2015-08-04 18:58:29 【问题描述】:我创建了一个宏变量,它是程序运行不到一个月时的日期时间,格式为 datetime20:
%let startDate = %sysfunc(intnx(dtmonth, %sysfunc(datetime()), -1), datetime20.);
这部分工作正常(如果我现在运行它,它会返回 01JUL2015:00:00:00),但我想做的是在 PROC SQL 语句中根据此日期对数据集进行子集化。基本上我想保留上个月日期发生的所有内容。我的代码是:
proc sql;
create table work.last_month as
select * from work.existing_table
where date >= &startDate.;
quit;
“date”列和“startDate”变量都是'datetime20'类型,但仍然抛出错误:
错误 22-322:语法错误,应为以下之一:;, !, !!, &, *, **, +, -, /, , =, >, >=, AND, EQ, EQT, EXCEPT, GE, GET, GROUP, GT, GTT, HAVING, INTERSECT, LE、LET、LT、LTT、NE、NET、NOT、OR、ORDER、OUTER、UNION、^、^=、|、||、~、~=。
我不知道它为什么会抛出这个错误。我做错了什么?
谢谢!
【问题讨论】:
【参考方案1】:宏处理器是一个代码生成器,因此您的代码正在生成
proc sql;
create table work.last_month as
select * from work.existing_table
where date >= 01JUL2015:00:00:00;
quit;
这不是有效的 SAS 代码。 您可以使用 SAS 日期时间数字而不是将其转换/格式化为日期时间值,或者创建一个日期文字进行比较。 要创建日期文字,请将宏变量括在引号中并以 dt 结尾以指示日期时间值。
proc sql;
create table work.last_month as
select * from work.existing_table
where date >= "01JUL2015:00:00:00"dt;
quit;
要创建 SAS 日期时间数值,请删除 %sysfunc() 中的格式。
%let startDate = %sysfunc(intnx(dtmonth, %sysfunc(datetime()), -1));
proc sql;
create table work.last_month as
select * from work.existing_table
where date >= &startDate.;
quit;
【讨论】:
谢谢。答案非常相似,这种情况下的协议是什么? @Reeza 没关系,我可以删除我的,或者直接离开。我通常认为,如果我的解释更符合某人的口味,留下它并没有什么坏处。 尽管这两种方法都有效,但我还是倾向于从 sysfunc 中删除格式。使用原始日期时间值比使用文字更容易,特别是如果稍后在程序中对值进行进一步操作。很好,你提到了这两种选择。【参考方案2】:您的问题是您正在格式化结果 - 不要那样做。请记住,宏变量只是创建文本,它们不是实际变量 - 它们没有“格式”之类的概念(常规 SAS 变量可以是数字日期值和“漂亮”格式化文本)。
1 %let startDate = %sysfunc(intnx(dtmonth, %sysfunc(datetime()), -1), datetime20.);
2 %put &=startdate.;
STARTDATE=01JUL2015:00:00:00
所以:
proc sql;
create table work.last_month as
select * from work.existing_table
where date >= 01JUL2015:00:00:00;
quit;
这是非法的,因为这不是一个日期时间值,它是一个很好的人类可读的日期时间,SQL/SAS 看着却不知道如何处理。
您可以从%sysfunc
中删除格式位,或在其周围添加"..."dt
以使其成为日期时间常数。
data existing_table;
do date=datetime()-86400*50 to datetime() by 86400;
output;
end;
run;
proc sql;
create table work.last_month as
select * from work.existing_table
where date >= "&startdate."dt;
quit;
【讨论】:
以上是关于基于宏变量的 SAS 子集的主要内容,如果未能解决你的问题,请参考以下文章