Макропеременные внутри шага данных - PullRequest
0 голосов
/ 16 ноября 2018

Мне нужно сохранить значение определенной переменной в шаге данных в макросе, а затем использовать этот макрос в том же шаге данных.я пробовал с SYMPUT, но если я правильно понял, макропеременная, созданная таким образом, не может быть использована внутри одного и того же шага данных (я думаю, она назначается в конце шага данных)

Здесьэто упрощенный пример.У меня есть список полей данных t1,...,t100, представляющих что-то происходящее в определенное время, события, представленные числами, и поле данных t_start, дающее мне время начала процесса, в котором я заинтересован для каждого наблюдения.Я хочу проверить, есть ли у меня все данные, и отказаться от наблюдения в противном случае.Я хочу действовать следующим образом.

DATA WANT;
    SET HAVE;

    CALL SYMPUT('START_TIME', t_start);

    DO I=&START_TIME. TO 100;
        IF t_&I. = . THEN DELETE;
    END;
RUN;

Это не работает, я думаю, по причинам, упомянутым выше.Есть ли обходной путь?

Замечания:

  1. Я упростил ситуацию, реальный случай, на который я смотрю, более сложный (например, переменные не называются t1,...t100, а что-тос немного большей структурой).Если возможно, я хотел бы получить что-то максимально приближенное к подходу, который я привел выше, так как разные решения могут быть неприменимы к моему случаю.Конечно, если это невозможно, тогда любое решение более чем приветствуется!
  2. Я попытался посмотреть на RESOLVE, но, похоже, оно не соответствует тому, что я ищу (или, по крайней мере, я ненедостаточно хорошо понимаю, чтобы заставить его делать то, что я хочу).
  3. В крайнем случае, я мог бы попытаться решить проблему, используя два шага данных, один из которых определял макропеременные, другой использовал его дляпроверьте и удалите нежелательные наблюдения.Я бы предпочел избегать этого решения, если это возможно.

Обновление: Я решил проблему с помощью массивов, как предложено в решениях.

Ответы [ 3 ]

0 голосов
/ 17 ноября 2018

Когда шаг данных выполняется, он был «скомпилирован», и все разрешения макропеременных амперсанда (&) уже разрешены.Выполнение скомпилированного шага не может изменить его исходный код.

Если вы отправили свой код дважды, первый раз будет записано WARNING: Apparent symbolic reference not resolved. Второй раз не будет иметь предупреждения и будет использовать значение, заполненное из предшествующее представление.

Предположим, что ваша запись данных имеет много переменных и две сторожевые переменные, значения которых являются именами переменных, которые отмечают начало и конец некоторыхобработка произойдет.В то время как громоздкая конструкция данных, вы можете использовать массив для обеспечения доступа к варианту набора переменных для обработки.

Например:

data have;
input 
 a  b  c  d  e  f  g  h start $ stop $ ; datalines;
 1  2  3  4  5  6  7  8  d  e
11 12 13 14 15 16 17 18  a  b
 0  1  1  2  3  5  8 11  c  h
 1  1  1  1  1  .  1  1  a  e  wont be deleted because . is at f
 1  2  3  4  .  6  7  8  a  h
run;

data want;
  set have;
  array num a--h;
  do i = 1 to dim(num);
    if vname(num(i)) = start then startindex=i;
    if vname(num(i)) = stop  then stopindex=i;
  end;

  do i = min(startindex,stopindex) to max(startindex,stopindex);
    if missing(num(i)) then delete;
  end;
run;
0 голосов
/ 17 ноября 2018

Вы пытаетесь использовать значение dataset переменных t_start и i, чтобы выяснить, какую переменную нужно проверить.Для этого и нужны массивы.

DATA WANT;
  SET HAVE;
  array t t1-t100;
  DO I=t_start TO 100;
    IF t(i) = . THEN DELETE;
  END;
RUN;

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

0 голосов
/ 17 ноября 2018

Это может быть лучшим подходом с использованием массивов. Учитывая, что вы опубликовали, это работает. Если это не соответствует вашим потребностям, пожалуйста, опубликуйте более подробную информацию о вашей ситуации.

data demo;
array t(10);
do row=1 to 100;
do i=1 to 10;
t(i)=rand('integer', 1, 5);
end;
start = rand('integer', 1, 10);
output;
end;
run;

data test;
set demo;

array t(10);



do i=start to dim(t);
if t(i) < 2 then do;
    delete;
    leave;*exits loop;
end;
end;

run;
...