2016-09-26 2 views
-1

У меня есть 2 набора данных в библиотеке aa & bb соответственно. Мой код сначала проверяет наборы данных в библиотеке, если они имеют в них определенные переменные столбца. Если наборы данных имеют конкретные переменные, они добавляются. Но когда я запускаю свой макрос, он не проверяет наборы данных в библиотеке & добавляет свои значения в test1 & test2, как и следовало ожидать, он не выполняет намеченную функцию проверки набора данных, если у них есть переменные в них, и возвращает error символическая ссылка для & 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 на: 'где libname =% upcase (" & lib1 ") и upcase (name) in (% upcase (& varlist));' – Quentin

ответ

1

Я вижу это как трехступенчатый процесс:

  1. Получить список наборов данных в библиотеке, которые имеют переменную.
  2. Создайте набор уникальных значений переменной в структуре, которая может быть прочитана в PROC FORMAT в виде набора данных CNTLIN, чтобы создать формат, который отображает каждое значение в последовательный код.
  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 имеет значение null. Оператор% put в конце раздела 1 должен показывать значение. – Quentin

+0

Вне макроса добавьте 'libname mylib" d: \ datafolder ";', чтобы создать библиотеку, которая работает в каталоге, в котором есть ваши наборы данных. – Quentin

Смежные вопросы