gpt4 book ai didi

sas - 如何按一定顺序读取两个数据集?

转载 作者:行者123 更新时间:2023-12-04 16:18:18 25 4
gpt4 key购买 nike

假设我有 2 个数据集 A 和 B:

Data A;
input data $;
datalines;
A1
A2
A3
;
run;

Data B;
input data $;
datalines;
B1
B2
B3
;
run;

我想生成一个具有特定顺序的数据集,如下所示:

A1
B1
B2
B3
A2
B1
B2
B3
A3
B1
B2
B3

如何在没有 POINT= 的情况下通过数据步从数据集 A 和 B 做到这一点?

我试过这个方法:

DATA WRONG_ANSWER;
SET A;
OUTPUT;
DO i = 1 to 3;
SET B;
OUTPUT;
END;
RUN;

结果是:

A1
B1
B2
B3
A2

看起来 B 的文件结束指示器终止了这个数据步骤。

我还用 POINT= 尝试了另一种方法,我得到了正确的结果。然而,由于从 B 访问特定 obs 时的大量 I/O 时间,这种方法非常慢:

DATA WRONG_ANSWER;
SET A;
OUTPUT;
DO i = 1 to 3;
SET B POINT=i; //this is the only different from above
OUTPUT;
END;
RUN;

最佳答案

假设一些事情,最快 的方法可能是散列迭代器解决方案。假设:

  • 数据集 B 足够小以适合(一次)内存。
  • 要么您不关心结果数据集中数据集 B 行的顺序,要么您的关键变量按升序或降序排列,或者您可以构造一个关键顺序变量。
  • 数据集 B 可以定义一个键,使其包含唯一的行,或者您可以使用“multidata:yes”(有足够新版本的 SAS 来支持它)。

鉴于这些假设,这是可行的:

data want;
if 0 then set b;
if _n_=1 then do;
declare hash b_hash(dataset:'b', ordered:'a');
b_hash.defineKey('data');
b_hash.defineData('data');
b_hash.defineDone();
declare hiter b_iter;
b_iter = _new_ hiter('b_hash');
end;
set a;
output;
rc = b_iter.first();
do while (rc=0);
output;
rc = b_iter.next();
end;
run;

根据您的用例,您可能希望通过宏系统和/或 dictionary.columns 查询构造 defineData 调用,以避免对列名进行硬编码。

这比点快多了;与基线相比:

data want_point;
set a;
output;
do _n_ = 1 to nobs_b;
set b point=_n_ nobs=nobs_b;
output;
end;
run;
  • 对于大 A,1e7 行和小 B,3 行,它需要大约 10 秒实时/8 秒 CPU 时间(不会比总写入时间长很多),而基线点需要 100 秒实时/12 秒 CPU 时间。
  • 使用较小的 A,point 变得更加高效,但仍然优于哈希(虽然只是轻微的,可能不值得编码难度的差异)。两者都接近 10 秒写入时间来写出 1e4 A/1e3 B 组合(产生与第一个相似大小的文件)。
  • 对于小 A 和大 B(3 行 A,1e7 行 B),散列需要更长的时间,因为它具有昂贵的首次设置成本;哈希解决方案 67 秒(28 秒 CPU)与点 65 秒(17 秒 CPU)。

因此,如果您有一个大型数据集并且要将它与一个小型数据集重复组合,则建议使用 Hash。如果两个数据集的大小相似或重复设置的数据集更大,则点可能与您得到的一样好(假设维护哈希的难度更高)。

关于sas - 如何按一定顺序读取两个数据集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32136921/

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