2016-09-26 70 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