Конкатенация переменных SAS через шаг данных - PullRequest
2 голосов
/ 29 апреля 2011

Я ищу способ создания строковой переменной, содержащей определенные значения набора данных, проходя через шаг данных.

Пример набора данных work.test:

AddToStringYN    Value
     Y           One
     Y           Two
     N           Three
     Y           Four
     N           Five

Итакв конце переменная будет выглядеть так: OneTwoFour (или даже лучше FourTwoOne).Это выглядит так просто, но я не могу найти способ сделать это.Я также пытался работать с макро-переменными, как это:

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar',"&stringvar" || strip(value));
  end;
Run;

Но это дает:

GLOBAL STRINGVAR Four

Так что я получаю только последнее значение.Я понимаю, что это должно быть из-за моего недопонимания по поводу этой макро-функции, но я не понимаю, почему в переменной есть только последнее значение.Я думал, что это был последний раз, когда симпозиум был вызван, что он был фактически выполнен или что-то в этом роде, но потом, когда я изменил код на:

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar'||strip(value),"&stringvar" || strip(value));
  end;
Run;

Затем я получил их все:

GLOBAL STRINGVARONE  One
GLOBAL STRINGVARTWO  Two
GLOBAL STRINGVARFOUR  Four

Итак, мое последнее предположение состоит в том, что при выполнении шага данных строка 'call symput ...' фактически добавляется в макропроцессор, где "& stringvar" уже заменен, и только после последнего оператора все они выполняются..
Это хорошее предположение или есть другое объяснение?И вернемся к первоначальному вопросу: есть ли простой способ добиться этого (имея нужную переменную)?

Ответы [ 2 ]

5 голосов
/ 29 апреля 2011

Ниже приводится мой ответ на ваш идентичный вопрос на RunSubmit.com .Я думаю, что вы и @Fabio, возможно, чрезмерно разрабатываете решение, ему вообще не нужен итеративный пошаговый код данных ...

Во-первых, простой способ сделать то, что вы пытаетесь сделать, этонапример:

proc sql;
  select Value into :StringVar separated by ''
    from work.test
    where AddToStringYN='Y'
    ;
quit;

Здесь вы можете воспользоваться интерфейсом SQL с SAS / MACRO, используя синтаксис select into.Вы могли бы даже добавить предложение order by, чтобы получить конкретный заказ, который вы ищете.

Во-вторых, поскольку вы натолкнулись на что-то о том, как работает макрос SAS, и вам интересно это понять:в вашем первом примере первое, что делает компилятор перед выполнением вашего кода, это разрешает значение &stringvar, которое на данный момент пусто.Таким образом, после компиляции, с замененным этим токеном, ваш код выглядит следующим образом: SAS ...

%let stringvar=;
Data _null_;
  set work.test;
  if AddToStringYN = "Y" then do;
    call symput('stringvar',"" || strip(value));
  end;
Run;

... затем SAS запускает и запускает этот код (который является допустимым кодом, но объединяетпустая строка для начала чего-либо).И из-за способа работы шага данных каждая итерация шага данных фактически заменяет значение StringVar, поэтому в конце шага данных остается последнее значение, которое было прочитано.

2 голосов
/ 29 апреля 2011

Greetings Кажется, достаточно просто, вот мое решение:

data a;
set test end=eof;
length cat $100.;
retain cat;
if AddToStringYN = "Y" then do;
   cat=trim(left(cat))||trim(left(value));
end;
if eof then do;
   call symput("VAR",cat);
   output;
end;
run;

%put VAR=&VAR;

в этом примере у вас есть конкатенация вашей переменной в наборе данных A в столбце "CAT", и у вас есть макропеременный VAR стот же список

...