【问题标题】:when to release the record in the input buffer with the @ in sas?何时使用 sas 中的 @ 释放输入缓冲区中的记录?
【发布时间】:2016-01-16 20:29:46
【问题描述】:

以下是简单的SAS程序:

data mydata;
  do group = 'placebo', 'active';
     do subj = 1 to 5;
        input score @;
        output;
     end;
  end;

datalines;
250 222 230 210 199
166 183 123 129 234
;

我正在自学 SAS。所以我想确定这里发生了什么。据我了解,5 个条目的第一行属于安慰剂组,第二行属于活跃组。起初,输入缓冲区包含 5 个数字的第一行,do subj=1 to 5 将它们一个一个打印出来,直到当前数据步迭代结束。然后,数据步骤继续进行第二次迭代。这种理解正确吗?非常感谢您的时间和关注。

附言。我只想确定何时释放当前输入缓冲区。上网查了一下,发现@的用途如下:

保存一个输入记录,用于在 DATA 步的同一迭代中执行下一个 INPUT 语句。此行保持说明符称为尾随@。

因此,如果满足以下两个条件之一,则意味着释放输入缓冲区:

(1):一个新的输入语句在没有任何@ 或@@ 的情况下被满足。 (2):当前数据步迭代结束。

非常感谢任何 cmets。

【问题讨论】:

    标签: sas


    【解决方案1】:

    我喜欢汤姆的回答,但想稍微扩展一下数据步迭代的含义。你写道:

    首先,输入缓冲区包含5个数字的第一行,do subj=1 to 5将它们一个一个打印出来,直到当前数据步迭代结束。然后,数据步骤继续进行第二次迭代。这种理解正确吗?

    DATA 步骤是一个隐含的迭代循环,从顶部(DATA 语句)到底部(通常是 RUN 语句,在这种情况下我认为是 DATALINES 语句)。如果要查看循环的每次迭代发生了什么,可以使用 PUT 语句将值写入日志,也可以将 N 写入日志,这是 DATA 步迭代的计数器数字。因此,您可以将代码更改为:

    do group = 'placebo', 'active';
       do subj = 1 to 5;
          input score @;
          put _n_= score= ;
          output;
       end;
    end;
    

    如果您这样做,您应该会看到所有数据(两行中的所有 10 个值)都在 DATA 步骤的第一次迭代中得到处理。您应该只会在日志中看到 _n_=1。正如@Tom 解释的那样,这是因为在您编写的显式循环中,当 SAS 在第一行找不到要读取的第六个值时,它会向前移动到第二行数据。我想大多数人会认为 NOTE SAS 抛出的关于移动到下一行的错误是警告甚至是错误。

    如果您想对 DATA 步循环进行两次迭代,您可以更改为:

    if _n_=1 then group = 'placebo';
    else if _n_=2 then group= 'active';
    
    do subj = 1 to 5;
      input score @;
      put _n_= score= ;
      output;
    end;
    

    (不是说两次迭代更好,或者上面的代码更好,只是为了说明数据步迭代是什么意思)。

    【讨论】:

    • 好点。那么,SAS 数据步骤仅针对某些输入数据开始第二次迭代?就像只将 SAS 数据集作为输入或类似的东西?或者 SAS 数据步骤何时开始第二次迭代?
    • 数据步骤始终迭代,直到达到使其停止的条件。在这种情况下,它会在第一次迭代时读取所有数据。然后它第二次迭代,当输入语句到达文件末尾时,该步骤停止。如果您在数据步骤的顶部添加 put _ n _=,您应该会看到它在第二次迭代中写入 _ n _ = 2。学习 DATA 步骤的关键是了解迭代、何时停止等。这些都是值得思考的好问题。
    【解决方案2】:

    您的代码应该可以正常工作,但您应该会看到 SAS 在您的 LOG 中转到新行的注释。

    当 GROUP='placebo' 时,内部循环 (DO SUBJ ...) 将读取 5 个数字并将指针留在第一行的末尾。然后外部循环将再次执行 GROUP='active'。当它尝试读取 SUBJ=1 的 SCORE 时,第一行没有任何内容。所以 SAS 将跳到下一行并从那里读取第一个 SCORE。然后从该行读取其他四个值。

    最后,在数据步骤结束时,它将“释放”该行,因此指针将位于第三行的开头(如果有第三行)。

    然后整个数据步骤将再循环一次并设置 GROUP='placebo' 和 SUBJ=1,但是当它尝试读取 SCORE 时,它会读取文件末尾并停止数据步骤。

    请注意,只要将 10 个值隔开任意多行,您的程序就可以正常工作。

    【讨论】:

    • 所以如果@被删除我会收到一条错误消息?
    • 不。如果没有尾随 @,您只会在 GROUP='placebo'、SUBJ=1 和 2 以及 SCORE = 250 和 166 的数据集中获得两个观察结果。当您第三次尝试执行 INPUT 语句时,数据步骤将停止因为您的数据中只有两行。
    • 此外,如果将 do subj = 1 to 5 更改为 do subj = 1 to 2,那么安慰剂组将有 250 222 199 166 129 234,而活动组将有 230 210 183 123?
    • 要做的事情就是玩它。将一些 PUT 语句放在那里,这样您就可以看到变量在不同点的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-04
    • 1970-01-01
    • 2021-12-14
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多