gpt4 book ai didi

sas - 在具有重复 BY 值的 SET 或 MERGE 中使用多个数据集时,为什么我的变量不会在数据步骤之间重置?

转载 作者:行者123 更新时间:2023-12-04 20:00:35 33 4
gpt4 key购买 nike

set 语句中运行包含两个数据集的数据步骤时,有时变量不会在迭代之间重置为缺失。当您有重复值时(即,当您的 by 变量不保证唯一记录时),merge 也是如此。

例如:

data have1;
do x=1 to 5;
y=1;
output;
end;
run;

data have2;
do x = 6 to 10;
z=x+1;
output;
end;
run;

data want;
set have1 have2;
if missing(y) and mod(z,2)=0 then y=2;
run;

在这里,y 为来自 have2every 记录赋予值 2,而不是仅偶数 z 值。

同样,

data have1;
do x = 1 to 5;
y=1;
output;
end;
run;

data have2;
do x = 1 to 5;
do z = 1 to 4;
output;
end;
end;
run;

data want;
merge have1 have2;
by x;
if mod(z,4)=3 then y=3;
run;

为什么会发生这种情况,如何防止它造成意想不到的后果?

最佳答案

为什么会这样?

正如在 Combining SAS Datsets: Methods 中的 SAS 文档中详细讨论的那样,这是因为在 setmergeupdate 语句上定义的变量在数据步骤(这相当于对传入数据集上的所有变量使用 retain)。

对于第一个例子,这自然地遵循了 retain 概念:y 被保留,所以当它没有被 set< 中的新记录替换时 的值为 y,它保留其最后一个值。 (正如我们稍后将看到的,它被清除一次:当 set 数据集发生变化时,因此它不再具有先前数据集中的早期值)。

但是,这并不能完全解释合并的功能(它是如何来回进行的)。这是由涉及 by 组时的不同行为引起的。

具体来说,变量不会在每个数据步迭代之间设置为缺失;但是,对于每个新的组或数据集,它们设置为缺失。来自文档:

The values of the variables in the program data vector are set to missing each time SAS starts to read a new data set and when the BY group changes.

这就是为什么第二个示例在 z 的前两次迭代中将 y 设置回 1,但在 z 中保持为 3 =4 迭代。

按顺序,用 z 值标记每个迭代:

  • Z=1: by group 的第一条记录,所以一切都设置为缺失。 HAVE1 被读取,HAVE2 被读取。 X=1, Y=1, Z=1 都设置好了。
  • Z=2:读取have2的第二条记录。 y 保留上一次迭代的值 1。
  • Z=3:读取have2的第三条记录。 y 设置为 3。
  • Z=4:读取have2的第四条记录。 y 保留上一次迭代的值 3。

请注意,HAVE1 仅在 z=1 迭代中被读取一次。如果这是一个多对多合并,HAVE1 将针对具有相同 x 值的每个不同行读取一次。

我们如何防止它发生?

您有多种选择来处理这个问题,假设您希望它表现得好像它没有自动保留一样。

  • 添加 by 语句

如前所述,在新的 by 值上,它会自动将所有内容重置为缺失。所以如果你跑了

data want;
set have1 have2;
by x;
if missing(y) and mod(z,2)=0 then y=2;
run;

这会按预期工作(尽管这里给出的结果略有不同)。

  • 自行设置部分或全部变量为 missing

您可以在两个地方执行此操作:

data want;
set have1 have2;
if missing(y) and mod(z,2)=0 then y=2;
output;
call missing(of _all_);
run;

data want;
y=.;
set have1 have2;
if missing(y) and mod(z,2)=0 then y=2;
run;

根据您的需要,一个或另一个可能更适合您的程序(第一个将所有内容设置为缺失,但需要一个额外的语句(输出;),而第二个仅设置 y 到 missing(这是所有需要的)但通过将 y 放在第一位来更改变量顺序。

对于具有重复 by 值的 merge,如果您想保留 y 的值,您可能需要执行以下操作:

data want;
merge have1 have2;
by x;
y_new=y;
if mod(z,4)=3 then y_new=3;
rename y_new=y;
drop y;
run;

它通过使用单独的变量来存储新值来解决问题。如果需要,您也可以将其设置为与上述类似的缺失。

关于sas - 在具有重复 BY 值的 SET 或 MERGE 中使用多个数据集时,为什么我的变量不会在数据步骤之间重置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25251177/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com