缺失值的 Proc SQL 赋值

  • 本文关键字:SQL 赋值 Proc sas proc-sql
  • 更新时间 :
  • 英文 :


如果我运行生成零行的查询,我仍然希望使用一行创建的 SAS 数据集,其中所有列都分配了缺失值。

我找到了一种使用单独的数据步骤来执行此操作的方法:

%let dsid   = %sysfunc (open(myfile));
%let anyobs = %sysfunc (attrn(&dsid,ANY));
%let dsid   = %sysfunc (close(&dsid));
data _null_;
if &anyobs=0 then do;
call execute('data work.myfile; call missing(col1, col2, col3); run;');
end;

这工作正常,但我想知道是否有办法为 proc sql 中的每一列分配缺失?

谢谢 担

假设你执行这个:

proc sql;
create table class as 
select * from sashelp.class 
where age=19;
quit;

然后你可以这样做:

%macro ifMissingRow(data=);
%let dsid   = %sysfunc (open(&data.));
%let anyobs = %sysfunc (attrn(&dsid,ANY));
%let dsid   = %sysfunc (close(&dsid));
%if &anyobs=0 %then %do;
data &data.;
output;
set &data.;
run;
%end;
%mend ifmissingRow;
%ifMissingRow(data=class);

输出在设置之前,以便在 SET 停止数据步骤之前获取行 0 行(指针为 h/t Tom)。

下面是使用SET语句的NOBS=选项的简单方法,以确保数据集至少有一个观测值。

data want ;
if 0=_nobs then output;
set want nobs=_nobs;
run;

请注意,如果数据集很大,并且您不希望重写数据,则可以使用某种方法有条件地生成数据步骤。 例如,您可以测试自动宏变量SQLOBS,如果为 0,则生成数据步骤。 在这种情况下,无需测试nob,因为您已经这样做了。 此外,您还可以使用自动宏变量SYSLAST而不是对数据集名称进行硬编码。 你可以为此使用 CALL EXECUTE,但你也可以只使用IFC()函数。

%sysfunc(dequote(
%sysfunc(ifc(0=&sqlobs,'data &syslast;output;set &syslast;run;',''))
))

也许最好的方法是使用MODIFY语句并有条件地运行OUTPUT语句。您可以测试SQLOBS宏变量。

data &syslast ;
if &sqlobs=0 then output;
modify &syslast ;
stop;
run;

或者您可以使用NOBS=选项修改语句。

data &syslast ;
if 0=_nobs then output;
modify &syslast nobs=_nobs;
stop;
run;

所有 SQL 解决方案

如果您知道至少一个变量名称,则可以使用 和 SQL 插入语句。

insert into &syslast (varname) values (null);

因此,您可以创建一个简单的宏,将数据集名称、观测值数和变量名称作为输入。

%macro ifzeronull(dsn,nobs,avar);
%if &nobs=0 %then %do;
insert into &dsn (&avar) values (null);
%end;
%mend ;

然后,您可以保留在同一 PROC SQL 调用中,并有条件地添加观察结果。

proc sql;
create table want as
select * from sashelp.class
where age=19
;
%ifzeronull(&syslast,&sqlobs,name)
quit;

最新更新