Merge 无proc-SQL的模糊连接
你好 我想把两个日期合并到下一个最近的日期 数据集容量从500Mb到1G,因此Merge 无proc-SQL的模糊连接,merge,sas,fuzzyjoin,Merge,Sas,Fuzzyjoin,你好 我想把两个日期合并到下一个最近的日期 数据集容量从500Mb到1G,因此proc-sql是不可能的 我有两个数据集。第一个(震源组)有观测值,第二个有日期和用于进一步处理的发电编号。像这样: data Fleet CreatedPortalDate 2013/2/19 2013/8/22 2013/8/25 2013/10/01 2013/10/07 data gennum_list date 01/12/20
proc-sql
是不可能的
我有两个数据集。第一个(震源组)有观测值,第二个有日期和用于进一步处理的发电编号。像这样:
data Fleet
CreatedPortalDate
2013/2/19
2013/8/22
2013/8/25
2013/10/01
2013/10/07
data gennum_list
date
01/12/2014
08/12/2014
15/12/2014
22/12/2014
29/12/2014
...
我想要的是这样一个链接表:
data link_table
CreatedPortalDate date
14-12-03 01/12/2014
14-12-06 01/12/2014
14-12-09 08/12/2014
14-12-11 08/12/2014
14-12-14 08/12/2014
逻辑上
Date
我想到的有点笨重,我正在寻找一种有效/更好的方法来实现这一点
data all_comb;
set devFleet(keep=createdportaldate);
do i=1 to n;
set gennum_list(keep=date) point=i nobs=n;
if createdportaldate > date
and createdportaldate - 15 < date then do;/*Assumption, the generations are created weekly.*/
distance= createdportaldate - date;
output;
end;
end;
run;
proc sort data=all_comb; by createdportaldate distance; run;
data link_table;
set _all_comb(drop=distance);
by createdportaldate;
if first.createdportaldate;
run;
数据全部\u梳;
设置devFleet(keep=createdportaldate);
i=1到n;
设置gennum_list(keep=date)point=i nobs=n;
如果createdportaldate>日期
并创建PortalDate-15<日期然后执行/*假设,每周一次创建一代*/
距离=createdportaldate-日期;
产出;
结束;
结束;
跑
proc sort data=所有\u梳;通过创建端口距离;跑
数据链路表;
设置所有梳子(下降=距离);
创建门户网站;
如果first.createdportaldate;
跑
- 如何改进或解决这个问题李>
- 无知的想法:我可以创建散列表来存储
李>distance
- 也许吧?不知怎么的
- 通用格式
- 完成
- 十亿行是从哪里来的?
- 是的,还涉及其他数据,但日期是唯一的链接变量李>
- 分类?
- 是,数据已排序,可以再次排序
- gen num日期总是相隔七天吗?
- 不,这是棘手的部分。否则,我可以使用
和周
(或其他binning)作为唯一标识符李>年
- 不,这是棘手的部分。否则,我可以使用
- 日期值是整数
- 日期值范围有限
- 日期值或接下来14天中的任何一天将用作查找验证程序
- 键是一个日期值,可以用作数组索引
- 巨大是一个相对的术语,今天的巨大是明天的污点
关键数据特性表明直接寻址查找方案是可行的
array gennum_of ( %sysfunc(today()) ) _temporary_;
if last_date then
do index = last_date to date-1;
gennum_of(index) = prev_date;
end;
last_date = date;
并获取一个gennum作为
if portaldate > last_date
then portal_gennum = last_date;
else portal_gennum = gennum_of ( portaldate );
如果由于按帐户ID分组而有许多行,则必须清除并加载每个组的gennum数组。这是sasby
语句的典型应用。
data
步骤中的by
语句旨在一次读取两个或多个按公共变量排序的数据集
常用变量是日期,但在两个数据集中的名称不同。在sql
中,您可以通过要求一个变量与另一个Fleet.CreatedPortalDate=gennum_list.date
相等来解决这个问题,但是by
语句不允许这样的构造,因此我们必须在读取数据集时重命名(至少)其中一个变量。这就是我们在gennum\u列表的选项中的rename
子句中所做的
data all_comb;
merge gennum_list (in = in_gennum rename = (date = CreatedPortalDate))
Fleet (in = in_fleet);
by CreatedPortalDate;
我选择将by
语句与merge
语句相结合,虽然set
也可以完成这项工作,但两个输入数据集的顺序会有所不同
还请注意,我请求sas在_gennum
和_fleet中创建指示变量,以指示哪个输入数据集中存在值。知道这种类型的变量id没有写入结果数据集是很方便的
当然,我们必须从CreatedPortalDate
恢复日期
if in_gennum then date = CreatedPortalDate;
如果您是sas新手,您会惊讶地发现,除非您明确指示sas保留从一次观察到巢穴的日期值,否则上述语句不起作用。(观察是sas对世界其他地区的行话。)
在这里,我们为从Fleet
数据集中读取的每个观测值写出一个观测值
if in_fleet then output;
run;
这种方法的优点是
- 您需要更少的逻辑来正确组合来自两个输入数据集的观察结果(这就是
数据
步骤的目的)
- 您永远不必在内存中保留值数组,因此不会出现溢出问题
- 这种解决方案在数据集的大小(除了排序之外)上的顺序是1(O1),因此我们预先知道,将数据量加倍只会使时间增加一倍。
免责声明:此答案正在构建中
本周晚些时候将对其进行测试请进行编辑,以便显示的日期都是通用格式,如yyyy-mm-dd。您仅在样本数据中列出唯一的日期值。100年只有36500天。十亿行是从哪里来的?是否还涉及帐户id等其他列?显示的示例数据已排序。实际数据是否已排序?gen num日期总是相隔七天吗?@Richard更新了问题。感谢您迄今为止的输入。期待更多。但是,当两个日期(创建日期
和日期
)不匹配时,我不确定这是否有效。或者我遗漏了什么?您可能遗漏了retain
语句的功能。
if in_fleet then output;
run;