【问题标题】:Output when using FIRST and LAST使用 FIRST 和 LAST 时的输出
【发布时间】:2015-08-18 15:30:12
【问题描述】:

假设我们有 SAS 代码:

data t1 (keep=KEY COUNT C_AMT2 C_AMT);  
SET t1;
BY key;
RETAIN COUNT C_AMT;

IF FIRST.KEY THEN
    DO;
        COUNT=0;
        C_AMT2=0;
    END;

COUNT+1;
C_AMT=SUM(C_AMT2, C_AMT);

IF LAST.KEY THEN
OUTPUT;

RUN;

如果我要删除“IF LAST.KEY THEN OUTPUT;”,这里会有什么变化。 documentation 表示输出导致 SAS 立即写入数据步,而不是在数据步结束时。因为这里是在数据步骤结束之前,这是否意味着删除它不会造成任何差异?

【问题讨论】:

  • C_AMT2 在 first.KEY 语句中设置为 0 的事实有点奇怪,如果这是一个运行总数,我希望它是 C_AMT。

标签: sas


【解决方案1】:

删除它会导致差异。

然后,假设有多个值,您将对键的每个值都有一个记录。控制输出意味着您只有最后一条记录。

它看起来像是在计算计数和总数,所以还有其他方法可以实现这一点。我将假设您已经隐藏了一些其他代码。

文档中引用此内容的相关部分在您上面的链接中

隐式输出与显式输出

默认情况下,每个 DATA 步在每次迭代结束时都包含一个隐式 OUTPUT 语句,告诉 SAS 将观察结果写入正在创建的数据集或数据集。 在 DATA 步中放置显式 OUTPUT 语句会覆盖自动输出,并且 SAS 仅在执行显式 OUTPUT 语句时才会将观察结果添加到数据集中。一旦您使用 OUTPUT 语句将观察结果写入然而,任何一个数据集,在 DATA 步的末尾都没有隐式的 OUTPUT 语句。在这种情况下,只有在执行显式 OUTPUT 时,DATA 步才会将观察结果写入数据集。您可以单独使用 OUTPUT 语句,也可以将其作为 IF-THEN 或 SELECT 语句的一部分或在 DO 循环处理中使用。

这是一些模拟您的问题的代码:

*Generate random data;
Data have;
do Key=1 to 2;
    do i=1 to 3;
        Amount=floor(rand('normal', 50, 5));
        OUTPUT;
    end;
end;

run;

data t1;
set have;
retain count C_Amt;
by Key;

if first.key then do;
count=0;
C_Amt=0;
end;

Count+1;
c_amt=sum(c_amt, amount);

if last.key then output;
run;

proc print data=t1;
run;

data t1;
set have;
retain count C_Amt;
by Key;

if first.key then do;
count=0;
C_Amt=0;
end;

Count+1;
c_amt=sum(c_amt, amount);

*if last.key then output;
run;

proc print data=t1;
run;

以及对应的输出:

用 last.key 然后输出

                      Obs    Key    i    Amount    count    C_Amt

                       1      1     3      46        3       147
                       2      2     3      44        3       154

并且没有 last.key Obs Key i 金额计数 C_Amt

                       1      1     1      47        1        47
                       2      1     2      54        2       101
                       3      1     3      46        3       147
                       4      2     1      61        1        61
                       5      2     2      49        2       110
                       6      2     3      44        3       154

【讨论】:

    【解决方案2】:

    这里的逗号是错误的:

    (keep=KEY, COUNT, C_AMT2, C_AMT)
    

    无论如何:

    RUN;
    

    通常意味着:

    output;
    return;
    

    但如果 SAS 在您的代码中遇到 output 语句,则末尾的 output(包含在 run 语句中)将被忽略。

    因此,由于您的 output 语句仅有条件地执行 IF LAST.KEY,因此在您的数据集中您将只有观察标记为 last.key,因为您的 RUN; 仅表示 return

    类似:

    data want; set have; output; run;
    

    与非显式输出完全相同:

    data want; set have; output; run;
    

    你可以随意使用输出:

    data want01 want02;
    set have;
    if a then output want01;
    if b then output want02;
    run;
    
    data want01;
    var=var1;
    output;
    var=var2;
    output;
    run;
    

    【讨论】:

    • 我明白了。因此,它对每个键变量求和 c_amt 变量,然后为每个键写入数据集一次。如果我要删除 IF LAST.KEY,那会发生什么? @stat
    • 如果没有使用last.key有条件地执行输出,则每次迭代的一个观察结果将在最终数据集中输出。数据需要;设置有;一些代码;输出;跑;与不显式输出完全相同。
    • @Danzo,为什么不删除它并运行它呢?还是生成样本数据并进行测试?
    • 是的,我同意@Reeza 的观点,测试是了解 SAS 在做什么的最佳方式。
    猜你喜欢
    • 2014-08-21
    • 2020-10-11
    • 2013-03-03
    • 1970-01-01
    • 2011-10-05
    • 2016-12-21
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    相关资源
    最近更新 更多