SAS IML список объектов

В SAS IML я хотел бы передать переменное число матриц числовых и символьных типов и разных измерений в пользовательский модуль. Это может быть реализовано, например, путем создания списка объектов и передачи списка в модуль. Например, в R такой тип данных называется просто "список". Подобная функциональность реализована в matlab как список ячеек, а также в C++ и Java путем наследования от абстрактного класса. К сожалению, не могу найти это в документации SAS IML.

Как можно создать список произвольных объектов в SAS IML?

Большое спасибо.

Alex


Рик, спасибо за быстрый ответ.

Идея с необязательными аргументами ограничена в долгосрочной перспективе, поскольку мне нужно передать 2 или более аргументов, а не 15 или менее.

Однако вторая идея вдохновила меня на еще одну работу.

Перед вызовом функции у меня есть список имен матриц

names = {A, B, C};

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

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

Спасибо

1 ответ

SAS/IML не поддерживает списки матриц.

Тем не менее, вот две идеи, которые могут помочь вам с вашей задачей. Во-первых, определить ваш модуль, чтобы принимать необязательные аргументы. Вы можете вызвать модуль с произвольным числом матриц, и модуль может определить (с помощью функции ISSKIPPED), сколько матриц вы отправили. См. Статью "Определение функций с необязательными параметрами".) Это то, что я выбрал бы, если бы у меня было 15 или меньше матриц.

Вот как реализовать первую идею:

proc iml;
/* Soln 1: Use optional args; detect which args are skipped */
start MyMod(x1 ,  x2=,  x3=,  x4=,  x5=, 
            x6=,  x7=,  x8=,  x9=,  x10=,
            x11=, x12=, x13=, x14=, x15=);
   /* compute number of args (stop at first empty arg) */
   ArgList = "x1":"x15";
   d = j(1, ncol(ArgList), 0); /* initialize to 0 */
   /* count args  */
   do i = 1 to ncol(ArgList);
      if ^IsSkipped(ArgList[i]) then do;
         var = value( ArgList[i] );
         d[i] = prod(dimension(var));
      end;
   end;
   d = remove(d, loc(d=0)); /* remove empty elements */
   print "The args are " (argList[1:ncol(d)]);
finish;

Протестируйте модуль, передав три аргумента разных размеров:

A = {1 2, 3 4};
B = {1 2 3, 4 5 6};
C = I(4);
run MyMod(A, B, C);

Вторая идея состоит в том, чтобы упаковать ваши числовые матрицы в одну большую матрицу, где строка i_th содержит значения матрицы i_th. Это будет поддерживать произвольно много матриц, но это несколько расточительно с точки зрения памяти. Для начала нужно выяснить максимальное количество элементов в объединении матриц. Затем выделите матрицу, достаточно большую, чтобы вместить все матрицы. Функция VALUE (см. Статью "Косвенное назначение") будет полезна для автоматизации этого шага:

/* Soln 2: If more then 15 args, pack values as row vectors into large 
   numerical matrix. Use missing values to pad small matrices */
names = {A, B, C};
dims = j(nrow(names), 2);
do i = 1 to nrow(names);
   dims[i,] = dimension(value(names[i]));
end;
maxDim = max(dims[,#]);

/* convert each matrix to row vector; pad with missing values */
pack = j(nrow(names), maxDim, .);
do i = 1 to nrow(names);
   v = rowvec(value(names[i]));
   pack[i, 1:ncol(v)] = v;
end;
print pack;

Матрица PACK содержит все числовые данные. (Сделайте что-то подобное для символьных матриц.) Затем вы можете отправить матрицы DIM и PACK в модуль. Модуль может использовать функцию SHAPE для распаковки матриц в их исходные формы. Например, следующий модуль распаковывает исходные матрицы и печатает их:

start unpack(dim, pack);
   do i = 1 to nrow(dim);
      x = shape( pack[i,1:prod(dim[i,])], dim[i,1] );
      print i x;
   end;
finish;

run unpack(dims, pack);
Другие вопросы по тегам