搜索库以附加具有特定变量的数据集

时间:2016-09-26 06:47:30

标签: sas sas-macro

我在库aa&中有2个数据集。分别是bb。 我的代码首先检查库中的数据集,如果它们中包含特定的列变量。如果数据集具有特定变量,则会附加它们。 但是,当我运行我的宏时,它不会检查库中的数据集。将它们的值附加在test1& test2应该如此,它不执行检查数据集的预期功能,如果它们中包含变量,并返回错误符号参考& ds& list not found&还会在& ds和& list中显示语法错误。

你可以建议任何编辑......

下面是我的代码..

%macro CHK(lib1=,lib2=,varlist=);

%local
list
ds
;

  proc sql noprint;
    select distinct catx(".",libname,memname) into :list separated by " "
      from dictionary.columns
      where libname = %upcase ("&lib1") and %upcase(name) in("&varlist") ;
  quit;
%put &list;

  data test1;
    set &list;
  run;

  proc sql noprint;
    select distinct catx(".",libname,memname) into :ds separated by " "
      from dictionary.columns
      where libname = %upcase ("&lib2") and %upcase(name) in("&varlist") ;
  quit;

 %put &ds;

 data test2;
 set &ds;
 run;

%mend CHK;

%CHK(lib1=aa,lib2=bb,varlist=%str('nam', 'DD', 'ht'));

1 个答案:

答案 0 :(得分:1)

我认为这是一个三步过程:

  1. 获取库中包含变量的数据集列表。
  2. 在可以作为CNTLIN数据集读入PROC FORMAT的结构中创建变量唯一值的数据集,以创建将每个值映射到顺序代码的格式。
  3. 使用格式重新编码变量处理每个数据集。
  4. 以下是一些示例代码:

    %macro Recode(lib=,var=);
    
    %local
      DataList
      i
      data_i
    ;
    
    %*1. Get a list of datasets in the library that have the variable;
    
    proc sql noprint ;
      select distinct catx(".",libname,memname) into :DataList separated by " "
        from dictionary.columns
        where libname = %upcase("&lib") and upcase(name) = %upcase("&var");
    quit;
    
    %put >>&DataList<<;
    
    %*2. Read the unique values of the variable into a dataset
         and then create a format named $recode that maps each unique value
         to a sequential code.
    ;
    
    proc sql;
      create table __cntlin as
      select "$Recode" as fmtname, &var as start, put(monotonic(),z6.) as label 
        from
          (
           %do i=1 %to %sysfunc(countw(&datalist,%str( )));
             %let data_i=%scan(&datalist,&i,%str( ));
             %if &i>1 %then union;
             select &var from &data_i 
           %end; 
          )
      ;
    quit;
    
    proc format cntlin=__cntlin 
                library=work
                fmtlib 
      ;
      select $recode;
    run;
    
    %*3. Use the format to recode the variable in each dataset;
    
    %do i=1 %to %sysfunc(countw(&datalist,%str( )));
      %let data_i=%scan(&datalist,&i,%str( ));
    
      data &data_i._R;
        set &data_i;
        &var._R=put(&var,$recode.);
      run;
    %end;
    
    
    *Cleanup;
    proc catalog cat=work.formats;
      delete Recode.formatc;
    quit;
    proc datasets library=work memtype=data nolist;
      delete __cntlin;
    quit;
    
    %mend Recode;
    
    %Recode(lib=work,var=name)
    

    使用您的样本数据,上面的代码生成两个数据集Test1_R和Test2_R:

    1454  data _null_;
    1455    set Test1_R;
    1456    put @1 Name @10 Name_R;
    1457  run;
    
    sam      000006
    danny    000003
    jacob    000004
    susan    000009
    sandra   000007
    vinny    000010
    alicia   000001
    NOTE: There were 7 observations read from the data set WORK.TEST1_R.
    
    1458
    1459  data _null_;
    1460    set Test2_R;
    1461    put @1 Name @10 Name_R;
    1462  run;
    
    sam      000006
    dann     000002
    jhon     000005
    susan    000009
    sandy    000008
    vinny    000010
    NOTE: There were 6 observations read from the data set WORK.TEST2_R.