Merge 无proc-SQL的模糊连接

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

你好

我想把两个日期合并到下一个最近的日期

数据集容量从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/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天中的任何一天将用作查找验证程序
      • 键是一个日期值,可以用作数组索引
      按如下方式加载Gennum查找一次

      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数组。

      这是sas
      by
      语句的典型应用。
      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;