0

在 SAS IML 中,我想将可变数量的数字和字符类型以及不同维度的 matices 传递给用户定义的模块。这可以通过例如创建对象列表并将列表传递给模块来实现。例如,在 R 中,这种数据类型仅称为“列表”。类似的功能在 matlab 中作为单元列表实现,在 C++ 和 Java 中通过从抽象类继承来实现。不幸的是,在 SAS IML 文档中找不到这个。

如何在 SAS IML 中创建任意对象列表?

非常感谢。

亚历克斯


瑞克,谢谢你的快速回复。

具有可选参数的想法长期受到限制,因为我需要传递 2 个或更多参数,而不是 15 个或更少。

然而,第二个想法启发了我另一种解决方法。

在调用函数之前,我有矩阵名称列表

names = {A, B, C};

在一个循环中,我将根据名称创建临时数据集,然后将名称传递给函数。在函数内部,我将可以访问所有数据集。调用该函数后,我将循环删除它们。

希望这不会在计算上很昂贵,否则将不得不求助于您的一个想法。

谢谢

4

1 回答 1

0

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);
于 2014-12-16T14:37:45.050 回答