SAS将结果输出到输入数据集(相同的输入和输出数据集名称)

时间:2015-08-17 08:50:50

标签: sas datastep

我找不到有关此问题的信息,或无法正确指定问题。

让我用代码问这个问题:
这个操作是

吗?
data work.tmp;
    set work.tmp;
    * some changes to data here;
run;

或特别是

proc sort data = work.tmp out = work.tmp;
    by x;
run;

以任何方式危险,或被认为是SAS的不良做法?请注意相同的输入和输出数据集名称,这是我的主要观点。 SAS是否正确处理了这种情况,因此运行此类数据步骤/过程不会产生任何模糊结果?

2 个答案:

答案 0 :(得分:3)

后者,自我排序,相当频繁地完成;因为sort只是重新排列数据集,并且(除非您依赖于其他顺序,或者除非您使用where子句来过滤数据集或重命名/保留/删除选项)不执行任何操作只要tmp处于工作状态(或者用作工作目录的libname),就不会对数据集造成永久性损害。 SAS创建一个临时文件来进行排序,当它成功时,删除旧文件并重命名临时文件;没有实质性的腐败风险。

前者在数据步骤中将数据集设置为自身通常不被视为一种好的做法。这是因为数据步骤经常做一些不可逆转的事情 - 也就是说,如果你运行它一旦它有不同的结果,那么比你再次运行它。因此,您可能不知道您的datastet具有什么状态;虽然排序你可以依赖于知识,因为如果在大多数情况下没有正确排序你会得到一个明显的错误,你可能永远不会知道数据步骤。因此,每个数据步骤通常应该生成一个新的数据集(至少是该线程的新数据集)。有时候有必要这样做,或者至少会浪费很多 - 可能是一个宏有时会做一个很长的数据步骤而有时却没有 - 但通常你可以围绕它进行编程。

但文件系统会混淆的意义上并不危险;类似于sort,SAS只会创建一个临时文件,填充新数据集,然后删除旧数据集并重命名临时文件。

(我暂时不提及像modify那样必须为自己设置数据集的事情,因为这有明显的答案......)

答案 1 :(得分:2)

为什么这不被视为良好做法的一些例子。假设您正在以交互方式工作,并且您拥有以下名为tmp的代码数据集:

data tmp;
  set sashelp.class;
run;

如果您要运行以下代码两次,它将在第一次运行正常,但在第二次运行时,您将收到警告,因为该数据集上不再存在变量age:

data tmp;
  set tmp;
  drop age;
run;

在这种情况下,这是一个非常无害的例子,你很幸运,SAS只是在发出警告。根据数据步骤的作用,它可能很容易产生错误,例如:

data tmp;
  set tmp (rename=(age=blah));
run;

或者更糟糕的是,它可能不会产生错误或警告,并改变预期的结果,如下面的代码:

data tmp;
  set tmp;
  weight = log(weight);
run;

我们的目的是将一个简单的对数变换应用于权重变量以准备建模,但如果我们不小心第二次运行该步骤,我们将计算日志(log(weight))。不会发出任何警告或错误,并且在查看数据集时,任何问题都不会立即显现出来。

IMO,你最好创建迭代数据集,即。 tmp1,tmp2,tmp3等等...用于以某种方式更新数据集的每个进程。空间比花时间调试便宜得多。