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

SAS将结果输出到输入数据集(输入和输出数据集名称相同),sas,datastep,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是否正确地处理了这种情况,因此运行这种数

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

让我用代码提问:
这是手术吗

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

后一种方法是非常频繁地自行排序;由于sort只是重新排列数据集,并且(除非您根据不同的顺序,或者除非您使用
where
子句来过滤数据集或重命名/保留/删除选项)不会对数据集造成任何永久性的损害,只要
tmp
起作用,这并不被视为坏做法(或打算用作工作目录的libname)。SAS创建一个临时文件进行排序,成功后删除旧文件并重命名临时文件;没有实质性的损坏风险

前者,在数据步骤中将数据集设置为自身,通常被认为是不好的做法。这是因为数据步骤通常会做一些不可逆的事情-即,如果运行一次,结果与再次运行不同。因此,您可能不知道数据集的状态;而使用排序时,您可以依赖于知道because如果大部分时间没有正确排序,就会出现一个明显的错误,数据步骤您可能永远都不知道。因此,每个数据步骤通常都应该生成一个新的数据集(至少是该线程的新数据集)。有时有必要这样做,或者不这样做至少会造成很大的浪费—可能是一个宏,有时执行长数据步,有时不执行—但通常您可以围绕它进行编程

不过,从某种意义上讲,文件系统会变得混乱并不危险;与排序类似,SAS只需创建一个临时文件,填充新数据集,然后删除旧数据集并重命名临时文件


(我不提像
modify
这样的东西,它必须为自己设置一个数据集,因为这有一个明显的答案…

一些例子说明了为什么这不是一个好的做法。假设您以交互方式工作,您有以下名为
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))。不会给出任何警告或错误,并且查看数据集时,不会立即发现任何错误


依我看,你最好创建迭代数据集,例如tmp1、tmp2、tmp3等等……对于以某种方式更新数据集的每个进程来说。空间比花时间调试要便宜得多。

如果空间允许,生成数据集在数据集被覆盖的地方可能会很有用。可能也值得一提的是不要放
如果未指定新数据集,则在
proc sort
中使用where
子句(除非您确实希望同时对行进行排序和删除!)我不认为生成数据集是解决上述问题的一个有用的方法;我在使用数据集名称时遇到的问题主要是不知道数据集之前或之后是否有数据集。世代并不能真正地帮助这一点(多)。谢谢你一个非常好的答案。乔。我可以问一下“只要数据集在工作目录中”。?SAS会不会创建tmp数据集,然后重命名它(就像你说的那样)在非工作目录中?在非工作目录上执行这样的操作是否有害?@Matek哦,不,这两种方式都会起作用-除了自动清除和未指定libname时的默认值之外,工作没有特殊意义。但我通常不会在永久位置对libname进行排序,因为它不应该是n必要的:在发布之前对其进行排序(例如,您可以指定
out=perm.dsname
),或者如果您正在使用它,则对传入的数据进行排序。一旦发布了永久数据集,就应该将其单独放置—这样其他用户就可以期望它是一致的,而不是仅仅因为您希望以不同的顺序进行排序而更改其排序顺序。明白了:)谢谢你这些说教式的解释。