Как динамически выбирать индексированную переменную назначения в SAS?

Я пытаюсь создать пользовательское преобразование в SAS DI. Это преобразование будет «воздействовать» на столбцы в наборе входных данных, создавая желаемый результат. Для простоты предположим, что преобразование будет использовать input_col1 для вычисления output_col1, input_col2 для вычисления output_col2 и так далее до некоторого заданного количества столбцов для обработки (скажем, 2).

В разделе Параметры кода пользовательского преобразования пользователи могут указать (через подсказки) имена столбцов, над которыми нужно действовать; например, пользователь может указать, что input_col1 должен ссылаться на столбец с именем «order_datetime» во входном наборе данных, и либо сделать аналогичную спецификацию для input_col2, либо оставить это приглашение пустым.

Вот код, который я использую для создания вывода для пользовательского преобразования:

data cust_trans;
    set &_INPUT0;

    i=1;
    do while(i<3);
        call symputx('index',i);
        result = myfunc("&&input_col&index");
        output_col&index = result; /*what is proper syntax here?*/
        i = i+1;
    end;
run;

Здесь myfunc относится к пользовательской функции, которую я создал с помощью proc fcmp, которая отлично работает.

Пользовательское преобразование работает нормально, если я не пытаюсь учитывать переменное количество входных столбцов для действия (т.е. если я использую "&&input_col&i" вместо "&&input_col&index" и просто использую столбец result в выходной таблице).

Однако у меня есть две проблемы с попыткой сделать подход более динамичным:

  • #P7# <блочная цитата> #P8#
  • Я не знаю, как сделать так, чтобы присваивание желаемому выходному столбцу происходило динамически; т. е. в зависимости от итерации цикла do я хотел бы присвоить выходное значение соответствующему выходному столбцу.

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

Любая помощь приветствуется!


person Rookatu    schedule 06.07.2017    source источник


Ответы (1)


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

Таким образом, вы либо должны

%do i = 1 %to .. ;

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

data cust_trans;
    set &_INPUT0;
    array in[2] &input_col1 &input_col2;  *or however you determine the input columns;
    array output_col[2]; *automatically names the results;
    do i = 1 to dim(in);
        result = myfunc(in[i]); *You quote the input - I cannot see what your function is doing, but it is probably wrong to do so;
        output_col[i] = result; /*what is proper syntax here?*/
    end;
run;

Это то, как вы обычно это делаете. Я не знаю, что делает myfunc, и я также не знаю, почему вы заключаете в кавычки "&&input_col&index.", когда передаете его ему, но это был бы странный способ работы, если только вы не хотите, чтобы имя входного столбца было текстовым (и не не хочу знать, какие данные находятся в этой переменной). Если да, то передайте vname(in[i]), который передает имя переменной в виде символа.

person Joe    schedule 06.07.2017
comment
Спасибо @Joe за очень быстрый и подробный ответ. Это исправило мою проблему. Что касается вашего вопроса о передаче имен в процедуру, это отчасти артефакт создания минимального рабочего примера для вопроса и отчасти из-за того, что процедура действительно запрашивает имена таблиц и столбцов. Не важно. Опять же, очень признателен! - person Rookatu; 06.07.2017