【问题标题】:Proc SQL assignment of missing valuesProc SQL 赋值缺失值
【发布时间】:2017-04-04 16:39:01
【问题描述】:

如果我运行一个产生零行的查询,我仍然希望创建一个 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 中的每一列分配缺失值?

谢谢 丹

【问题讨论】:

    标签: sas proc-sql


    【解决方案1】:

    假设你执行这个:

    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 为指针)。

    【讨论】:

    • 优秀的解决方案。谢谢!
    • 如果您已经知道没有观察结果,则无需使用 IF 0 技巧。只需将 OUTPUT 语句移到 SET 语句之前,您就会得到一个观察结果。
    【解决方案2】:

    这是一种使用SET 语句的NOBS= 选项的简单方法,可确保您的数据集至少有一个观察值。

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

    请注意,如果数据集很大并且您不想重新写入数据,那么您可以使用某种方法有条件地生成数据步骤。例如,您可以测试自动宏变量SQLOBS,如果它为 0,则生成数据步骤。在这种情况下,无需测试 nobs,因为您已经这样做了。您也可以使用自动宏变量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;
    

    【讨论】:

    • 不错的选项调查!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 2019-11-30
    • 2019-11-18
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    相关资源
    最近更新 更多