(SAS) Передача функции в качестве аргумента функции (или макросу) - PullRequest
0 голосов
/ 31 августа 2018

На современном языке (например, python) вы можете сделать что-то вроде

def do_a_thing(foo,bar):
    thing = (... do a thing to foo(bar) ...)
    return thing

Как можно это сделать (или что-то похожее) в SAS? В моем конкретном приложении я определил несколько функций, и мне нужно сделать одно и то же для всех них, поэтому я подумал, что было бы неплохо иметь функцию, которая принимает функцию в качестве аргумента, а затем выполняет эту функцию к этой функции, а затем примените ее при необходимости. «Очевидное» решение не работает, например, proc fcmp делает это:

function do_a_thing(foo,bar);
    thing = (... do a thing to foo(bar) ...)
return(thing);
endsub;

Сбой, потому что SAS не знает ни о какой функции, называемой foo, и выдает ошибку.

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

Ответы [ 3 ]

0 голосов
/ 31 августа 2018

Покажите свой код относительно , определен набор функций .

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

Если вы пытаетесь кодировать функцию общего назначения, вызываемую из шага DATA, SQL,% SYSFUNC или DS2, то и Proc FCMP, и DS2 могут создавать пользовательские функции (UDF). Метод (или функция) -name для вызова (или отправки, или APPLY), скорее всего, должен быть передан в виде строки в указанный UDF.

Вы также захотите взглянуть на DOSUB и DOSUBL

Подробности

Функция DOSUBL обеспечивает немедленное выполнение кода SAS после передачи текстовой строки. Макропеременные, которые создаются или обновляются во время выполнения переданного кода, экспортируются обратно в вызывающую среду.

DOSUBL возвращает нулевое значение, если код SAS был в состоянии выполнить, и возвращает ненулевое значение, если код SAS не был в состоянии выполнить.

Что касается современного ... SAS SCL давным-давно CALL APPLY - к сожалению, SCL так и не попал в продукт Foundation и не вышел за пределы SAS.

0 голосов
/ 31 августа 2018

Вы действительно не показали пример, где это может потребоваться (или даже полезно).

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

%macro do_a_thing(function,arglist);
  &function(&arglist)
%mend;

Тогда вы можете использовать его в программе

data want ;
  set have ;
  mean = %do_a_thing(mean,of _numeric_);
  std = %do_a_thing(std,of _numeric_);
run;

Для более сложных вещей у вас будет больше проблем. Функция new-ish DOSUBL () может помочь в том, что они могут позволить вам выполнить несколько шагов в отдельном пространстве выполнения. Но в большинстве случаев стоимость производительности может быть слишком высокой, чтобы ее оправдать.

0 голосов
/ 31 августа 2018

На самом деле ничего не знаю о SAS, но, в общем, вам нужен какой-то способ сделать разницу между вызовом функции и передачей параметра.

Поиск в Google по названию этого вопроса привел меня сюда, возможно, это могло бы помочь вам:

https://communities.sas.com/t5/SAS-Procedures/how-to-pass-a-parameter-with-macro-variables-into-macro/td-p/330627#messageview_4

...