【问题标题】:How to use proc compare to update dataset如何使用 proc compare 来更新数据集
【发布时间】:2014-10-17 08:18:52
【问题描述】:

我想使用proc compare 每天更新数据集。

work.HAVE1

Date        Key Var1 Var2 
01Aug2013   K1   a    2
01Aug2013   K2   a    3
02Aug2013   K1   b    4

work.HAVE2

Date        Key Var1 Var2 
01Aug2013   K1   a    3
01Aug2013   K2   a    3
02Aug2013   K1   b    4
03Aug2013   K2   c    1

DateKey是唯一确定一条记录。 如何使用上面的两个表来构造如下

work.WANT

Date        Key Var1 Var2 
01Aug2013   K1   a    3
01Aug2013   K2   a    3
02Aug2013   K1   b    4
03Aug2013   K2   c    1

我不想删除以前的数据然后重新构建它。我想通过在底部追加新记录来modify 它并调整VAR1VAR2 中的值。 我正在为proc compare 苦苦挣扎,但它并没有返回我想要的。

【问题讨论】:

    标签: compare sas


    【解决方案1】:
    proc compare base=work.HAVE1 compare=work.HAVE2 out=WORK.DIFF outnoequal outcomp;
    id Date Key;
    run;
    

    这将在单个数据集 WORK.DIFF 中为您提供新的和更改的(不相等的记录)。你必须自己区分新的和改变的。

    但是,您想要实现的实际上是 MERGE - 插入新的,覆盖现有的,尽管可能由于性能原因等。您不想重新创建完整的表。

    data work.WANT;
        merge work.HAVE1 work.HAVE2;
        by Date Key;
    run;
    

    编辑1:

    /* outdiff option will produce records with _type_ = 'DIF' for matched keys */
    proc compare base=work.HAVE1 compare=work.HAVE2 out=WORK.RESULT outnoequal outcomp outdiff;
    id Date Key;
    run;
    
    
    data WORK.DIFF_KEYS;  /* keys of changed records */
        set WORK.RESULT;
        where _type_ = 'DIF';
        keep Date Key;
    run;
    
    /* split NEW and CHANGED */
    data
        WORK.NEW
        WORK.CHANGED
    ;
     merge
          WORK.RESULT (where=( _type_ ne 'DIF'));
            WORK.DIFF_KEYS (in = d)
        ;
      by Date Key;
      if d then output WORK.CHANGED;
      else output WORK.NEW;
    run;
    

    编辑2:

    现在您可以将APPEND WORK.NEW 用于目标表。

    对于 WORK.CHANGED - 使用 MODIFYUPDATE 语句更新记录。 根据更改的大小,您还可以考虑PROC SQL; DELETE 删除旧记录,PROC APPEND 添加新值。

    【讨论】:

    • 忘了说。 Have1 实际上是在服务器上,而 Have2 是本地的。 Merge 可能需要更多处理大型数据集的时间?
    • @GMTG 如果您能够保留HAVE1 的“本地”副本,或者至少保留HAVE1 的那些可能更改的部分,这会更好。如果您无法在本地驱动器上保留主数据集的副本,这可能不会对您有太大好处(因为无论如何您最终都会进行大量网络传输)。
    • @vasja 对于new,我可以附加它。对于changed,我还需要一个merge(类似于if a and if not b)?
    • @Joe 为什么在存在先前数据的本地副本时效果更好?如果是这样,最终我需要将所有数据传递到服务器。
    • 它工作得更好,因为它节省了网络传输。如果have1 有一个本地副本,那么唯一需要传输的数据就是差异(您必须更新have1 两次,一次更新本地,一次更新网络,但希望这并不昂贵)。如果have1 仅在网络上,那么您必须将所有have1 拉回,比较,然后推送更新,最终推送大部分或全部相同的数据,就像完全替换网络副本一样。跨度>
    【解决方案2】:

    所有 PROC COMPARE 都会告诉您 2 个数据集之间的差异。要实现您的目标,您需要在数据步骤中使用 UPDATE 语句。这样,HAVE1 中的值将使用日期和键匹配的 HAVE2 进行更新,或者如果没有匹配项则插入新记录。

    data have1;
    input Date :date9. Key $ Var1 $ Var2;
    format date date9.;
    datalines;
    01Aug2013   K1   a    2
    01Aug2013   K2   a    3
    02Aug2013   K1   b    4
    ;
    run;
    
    data have2;
    input Date :date9. Key $ Var1 $ Var2;
    format date date9.;
    datalines;
    01Aug2013   K1   a    3
    01Aug2013   K2   a    3
    02Aug2013   K1   b    4
    03Aug2013   K2   c    1
    ;
    run;
    
    data want;
    update have1 have2;
    by date key;
    run;
    

    【讨论】:

    • have1 在网络上。 have2 是本地的。对大数据使用这样的数据步骤会导致无法接受的性能?
    • Keith,这与之前的问题有关;这里的重点是能够以最少的网络传输执行​​更新(因此 proc 比较以识别要更新的记录)。
    • 在这种情况下,如何在 HAVE1 上创建索引,然后使用 MODIFY 将其更新为 HAVE2?我现在没时间写代码,但是看看这篇文章,特别是 MODIFY with KEY= Option 和 SET 语句。 www2.sas.com/proceedings/sugi31/264-31.pdf
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多