Optmodel使用2个关键列Optmodel

时间:2016-05-28 10:17:45

标签: sas

我有一个矢量X,它来自3套[Origin,Destination,Product]有一个值,我想创建一个表,其中包含作为关键列的Origin和destination,然后为每个产品创建一个列,说明要运输多少

类似于:

Origin Dest。 ProductA ProductB ...

一个......... AB ....... 10 ...... 0

一个......... AC ....... 5 ....... 4

我在optmodel中尝试这样的事情:

create data Ctrl3.Transport
    from  [Origin Destination] = {FAB, CITIES}
    {k in PRODUCT} <col('Product_'||k) = X[Origin, Destination, k]>; run;

但sas似乎不喜欢它

1 个答案:

答案 0 :(得分:0)

TLDR;

修复方法是使用{fi in FAB, ci in CITIES}代替{FAB,CITIES}。 然后使用fici代替OriginDestination。 以下代码中的注释进一步解释。代码后的更多细节。

代码示例

proc optmodel;
    set FAB                   init /RDU/;
    set CITIES                init /BCN MEL/;
    set PRODUCT               init /Planes Trains Automobiles/;
    num x{FAB,CITIES,PRODUCT} init [ /* BCN */ 3 4 5   /* MEL */ 6 7 8];
    put x[*]=; /* just to verify the declarations */

    /* This is the most efficient solution. 
       In the columns, you use fi and ci, not Origin and Destination */
    create data work.transport
        from  [Origin Destination] = {fi in FAB, ci in CITIES}
        {k in PRODUCT} <col('Product_'||k) = X[fi, ci, k]>
    ;
    /* This works because the key-set is a set expression, which confusingly,
       is not the same as an index set expression.
       The difference is important: this version creates a redundant set
       of arity 2. */
    create data work.works_but_is_inneficient
        from  [Origin Destination] = ({FAB, CITIES})
        {k in PRODUCT} <col('Product_'||k) = X[Origin, Destination, k]>
    ;    
    /* This is the original approach. 
       It fails because when the key-set is a index set expression,
       OPTMODEL looks there for dummy parameters. 
    create data work.op
        from  [Origin Destination] = {FAB, CITIES}
        {k in PRODUCT} <col('Product_'||k) = X[Origin, Destination, k]>
    ; */   
quit;

详细

为提高效率,OPTMODEL有两种类似的表达方式,有时甚至会让高级用户感到困惑:

  • 设置表达式,它会评估一些代码并返回一个集合
  • 索引集表达式,返回一组表达式。

您可以将虚拟变量与索引集表达式相关联。 在 create data 语句中,当OPTMODEL看到索引集表达式时, 它使用那些虚拟变量而不是方括号中的名称。 由于在OP中没有这样的虚拟变量,因此会出现错误。