2

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

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

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 是否正确处理这种情况,因此运行这种数据步骤/过程不会产生模棱两可的结果?

4

2 回答 2

3

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

前者,在数据步骤中将数据集设置为自身,通常不被认为是一种好的做法。那是因为数据步骤通常会做一些不可逆的事情——即,如果你运行一次它会得到与再次运行它不同的结果。因此,您可能不知道您的数据集处于什么状态;虽然使用排序,但您可以依靠知道,因为如果大多数时间没有正确排序,您会得到一个明显的错误,而您可能永远不会知道数据步骤。因此,每个数据步骤通常应该产生一个新的数据集(至少,对于该线程来说是新的)。有时有必要这样做,或者至少不这样做会非常浪费 - 也许是一个有时会执行长数据步骤而有时不会执行的宏 - 但通常您可以围绕它进行编程。

不过,从文件系统混淆的意义上说,这并不危险。与 类似sort,SAS 将简单地创建一个临时文件,填充新数据集,然后删除旧数据集并重命名临时文件。

(我暂且不提诸如必须modify为自己设置数据集之类的事情,因为这有一个明显的答案……)

于 2015-08-17T14:32:05.897 回答
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;

或者更糟糕的是,它可能不会产生 ERROR 或 WARNING,并像下面的代码一样改变预期的结果:

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

我们的目的是对权重变量应用一个简单的对数转换,为建模做准备,但如果我们不小心再次运行该步骤,我们正在计算对数(log(weight))。不会给出警告或错误,并且查看数据集不会立即发现任何错误。

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

于 2015-08-17T17:07:15.147 回答