2016-09-26 60 views
-1

我在库aa & bb中分别有2个数据集。 我的代码首先检查库中的数据集,如果它们中有特定的列变量。如果数据集具有特定的变量,那么它们被追加。 但是,当我运行我的宏它不检查库中的数据集&在test1 & test2中附加它们的值,它不会执行检查数据集的预期功能,如果它们中有变量,并返回错误符号参考& ds &未找到列表&也在& ds和&列表中显示语法错误。搜索库来追加具有特定变量的数据集

可你提出任何修改...

下面

是我的代码..

%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')); 
+0

请编辑您的问题,包括从投料到产出您发布的示例以及您尝试的代码。 – Quentin

+0

你已经编辑了这个问题,我觉得现在真的是一个新问题。我不明白这个问题。建议您恢复以前的版本,然后添加一个新问题。 – Quentin

+0

再次,这是一个不同于你最初问的问题。这应该是一个新问题。你应该恢复我已经回答的原始问题,并将其作为一个新问题。也就是说,尝试将WHERE语句更改为:'%upcase(&varlist)'中的where libname =%upcase(“&lib1”)和upcase(名称);' – Quentin

回答

1

我把它看成是三个步骤:

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

下面是一些示例代码:

%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. 
+0

可能可以通过更改循环来完成。因此,例如,在第3部分中,不是遍历所有找到的数据集列表,而是循环显示用户提供的输入数据集和输出数据集列表作为参数。 – Quentin

+0

lib =参数应该以库名称的形式传递。在宏的外部,使用libname语句创建一个指向具有数据集的目录的libref。正如所写的,我猜测&datalist是空的。第1部分末尾的%put语句应显示该值。 – Quentin

+0

在宏的外部添加'libname mylib“d:\ datafolder”;'创建一个库,将其添加到包含您的数据集的目录中。 – Quentin