Есть ли способ передать список под макрокодом? - PullRequest
0 голосов
/ 24 января 2019

У меня есть данные опроса клиентов, такие как:

data feedback;
    length customer score comment $50.;
    input customer $ score  comment & $;
    datalines;
A 3 The is no parking
A 5 The food is expensive
B . I like the food
C 5 It tastes good
C . blank                  
C 3 I like the drink
D 4 The dessert is tasty
D 2 I don't like the service
;
run;

Существует такой макрос-код:

%macro subset( cust=);

    proc print data= feedback;
        where customer = "&cust";
    run;

%mend;

Я пытаюсь написать программу, которая вызывает подмножество%для каждого клиента значение в данных обратной связи.Обратите внимание, что мы не знаем, сколько уникальных ценностей клиента содержится в наборе данных.Кроме того, мы не можем изменить код% subset.

Я пытался добиться этого, используя proc sql для создания уникального списка клиентов для передачи в код макроса, но я думаю, что вы не можете передать список в коде макроса.Есть способ сделать это?я новичок в макросе

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Сначала исправьте код SAS.Чтобы проверить, находится ли значение в списке с помощью оператора IN, а не оператора =.

where customer in ('A' 'B')

Затем вы можете передать этот список в свой макрос и использовать его в своем коде.

%macro subset(custlist);
proc print data= feedback;
  where customer in (&custlist);
run;
%mend;
%subset(custlist='A' 'B')

Обратите внимание на несколько вещей:

  1. Используйте кавычки вокруг значений, поскольку переменная является символом.
  2. Используйте пробелы между значениями.Оператор IN в SAS принимает в качестве разделителя в списке либо пробелы, либо запятую (или обе).Трудно передавать списки с разделителями-запятыми при вызове макроса, поскольку запятая используется для разделения параметров.
  3. Вы можете определить макропараметр как позиционный и по-прежнему вызывать его по имени в вызове макроса.

Если список находится в наборе данных, вы можете легко сгенерировать список значений в макропеременную с помощью PROC SQL.Просто убедитесь, что результирующий список не слишком длинный для макропеременной (максимум 64 Кбайт).

proc sql noprint;
  select distinct quote(trim(customer))
    into :custlist separated by ' '
    from my_subset
  ;
quit;
%subset(&custlist)
0 голосов
/ 24 января 2019

Мне нравится быть проще. Взгляните на следующее:

data feedback;
length customer score comment $50.;
input customer $ score  comment & $;
datalines;
A 3 The is no parking
A 5 The food is expensive
B . I like the food
C 5 It tastes good
C . blank                  
C 3 I like the drink
D 4 The dessert is tasty
D 2 I don't like the service
;
run;

%macro subset( cust=);
    proc print data= feedback;
       where customer = "&cust";
    run;
%mend subset;

%macro test;
   /* first get the count of distinct customers */
   proc sql noprint;
      select count(distinct customer) into : cnt
         from feedback;quit;

   /* do this to remove leading spaces */
   %let cnt = &cnt;

   /* now get each of the customer names into macro variables
   proc sql noprint;
       select distinct customer into: cust1 - :cust&cnt
            from feedback;quit;

/* use a loop to call other macro program, notice the use of &&cust&i */
%do i = 1 %to &cnt;
   %subset(cust=&&cust&i);
%end;
%mend test;
%test;

конечно, если вы хотите использовать короткие и сладкие слова (просто убедитесь, что ваши данные отсортированы по клиенту):

data _null_;
set feedback;
by customer;
if(first.customer)then call execute('%subset(cust='||customer||')');    
run;
...