试图将数据集中的值连接到SAS中的数组

时间:2018-12-15 07:50:44

标签: arrays sas

我正在尝试添加一个数据步骤,该步骤从work.orders_fin_qtr_tot数据集创建work.orders_fin_tot数据集。此新数据集应包含季度销售额和利润的新变量。使用两个数组创建新变量:QtrSales1-QtrSales4QtrProfit1-QtrProfit4。这些代表该季度的总销售额和总利润(1-4)。使用下订单的年份的四分之一编号来索引正确的变量,以将TotalSales或TotalProfit添加到新的适当变量中。

添加一个Proc步骤,以显示work.orders_fin_qtr_tot数据集的前10个观测值。

我的问题是我似乎无法使两个diff数组融合在一起而没有空格

proc sort data=work.orders_fin_tot_qtr;
    by workqtr;
run;
data work.orders_fin_tot_qtr;
   set work.orders_fin_tot_qtr;

    array QtrSales{4} quarter1-quarter4 ;
    do i = 1 by 1 until (last.order_id);
    if workqtr=i then QtrSales{i}=totalsales;
    end;
    drop totalsales totalprofit _TYPE_  _FREQ_;
run;
proc print data=work.orders_fin_tot_qtr;
run;

1 个答案:

答案 0 :(得分:0)

语法last.order_id仅在DATA步骤中有BY语句时才适用-如果不存在,则为最后。引用总是丢失,循环永远不会结束;所以您已经编写了一个无限循环!

该步骤具有drop totalsales totalprofit _TYPE_ _FREQ_。这些带下划线的变量表示传入的数据集可能是使用Proc SUMMARY创建的。

您的orders_fin_tot数据集应具有order_id quarter列(有效值1,2,3,4)和totalsales。如果数据是多年数据,则应该有一个名为year的列。

缺少的BY和当前的last.id表示您正在将数据从分类矢量重整,该矢量从一列向下移动到一个跨行的位置-这称为枢轴或转置。您在问题中显示的do构造是不正确的,但与SAS圈中称为DOW循环的技术类似-该技术的特殊之处在于SETBY在循环内 进行编码。

尝试将代码调整为以下模式

data want;
  do _n_ = 1 by 1 until (last.order_id);
    SET work.orders_fin_tot;   * <--- presumed to have data 'down' a column for each quarter of an order_id;
    BY order_id;   * <--- ensures data is sorted and makes automatic flag variable LAST.ORDER_ID available for the until test;
    array QtrSales quarter1-quarter4 ;  * <--- define array for step and creates four variables in the program data vector (PDV);

    * this is where the pivot magic happens;
    * the (presumed) quarter value (1,2,3,4) from data going down the input column becomes an
    * index into an array connected to variables going across the PDV (the output row); 
    QtrSales{quarter} = totalsales;
  end;
run;

请注意,循环内部或外部没有OUTPUT语句。循环完成后,代码流到达数据步骤的底部并执行隐式OUTPUT(因为在该步骤的其他位置没有显式的OUTPUT)。

此外,对于代码中指定的任何数据集,您可以使用数据集选项OBS=选择要使用的观测编号。

proc print data=MyData(obs=10);

OBS是一个棘手的选项名称,因为它实际上表示要使用的最后观察编号FIRSTOBS是另一个数据集选项,用于指定要使用的行号,如果不存在,则默认为1。因此,上述等同于

proc print data=MyData(firstobs=1 obs=10);

OBS =应该在概念上被认为是LASTOBS =;没有实际的选项名称LASTOBS。以下内容将记录ERROR:,因为OBS

proc print data=MyData(firstobs=10 obs=50);