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);