Proc SQL 缺失值赋值
Proc SQL assignment of missing values
如果我 运行 生成零行的查询,我仍然希望创建一个 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 语句。
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;
如果我 运行 生成零行的查询,我仍然希望创建一个 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 语句。
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;