SAS-使用宏修改多个数据集的代码改进

时间:2016-10-21 13:40:52

标签: loops macros sas

我试图在工作库下修改所有数据集(数据集的名称遵循某些命令,如data_AXPM061203900_20120104,data_AXPM061203900_20120105,data_AXPA061204100_20120103,data_AXPA061204100_20120104)。例如,我想删除名为" ask_price"的变量下的所有缺失值。在所有数据集中。

enter image description here

我正在使用以下内容来实现这一目标。

 proc sql ;
      create table data.mytables as
      select *
      from dictionary.tables
      where libname = 'WORK' 
      order by memname ;
    quit ;


%macro test;
  proc sql ;
    select count(memname) into: obs from data.mytables;

  %let obs=&obs.;

    select catx("_", "data", substr(memname, 6, 13), substr(memname,20,27))
    into :setname1-:setname&obs.
    from data.mytables;
quit;


%do i=1 %to &obs.;

data  &&setname&i;
set  &&setname&i;

if bid_price= '.' then delete;
%end;

%mend test;

%test;

有人建议" 这可能是您可以拥有的效率最低(在编程方面)设置。每次你甚至访问这些数据时,你需要经历所有循环,检查,从文件名等获取数据,这既是资源无意义,又容易出错。"但是,他没有给我一个详细的解决方案。在这种情况下,有人可以给我更多指导吗?

2 个答案:

答案 0 :(得分:0)

请注意,删除现有数据集中的观察结果可能是一个坏主意,因为如果有任何错误,那么您将丢失原始数据。但是,让我们假设你已经在整个过程的其他部分处理了这个问题。

因此,如果您想在缺少变量bid_price时从大量现有数据集中删除观测值,那么您可以使用PROC SQL。您需要首先生成数据集列表。然后,您需要为每个数据集生成单独的DELETE语句以删除观察结果。

此代码将代码生成为宏变量。因此它将受到宏变量(64K)的最大长度的限制,它可以处理多少个数据集。

proc sql noprint ;
  create table dslist as
    select distinct 
        libname
      , memname 
    from dictionary.columns 
    where libname='WORK'
      and memname like 'DATA_APX%'
      and upcase(name)='BID_PRICE'
  ;
  %let code=;
  select catx(' ','delete * from',catx('.',libname,memname)
                 ,'where missing(bid_price)')
    into :code separated by ';'
    from dslist
  ;
  &code;
quit;

答案 1 :(得分:0)

原始代码的另一个问题:     如果bid_price ='。'然后删除; bid_price是一个数值,您将其与字符值进行比较(引号中的句点使其成为字符值)。如果您打算使用那种类型的代码,那么它应该是这样的:    如果bid_price =。然后删除; 但是,我更喜欢使用“missing”函数,它适用于字符和数字:    如果遗漏(bid_price)则删除;

在SAS中几乎总有几种方法可以完成给定的任务。