【问题标题】:Merge Specifying Column Order合并指定列顺序
【发布时间】:2014-03-25 20:00:07
【问题描述】:

我有两个类似的 SAS 数据集:

DATAONE            DATATWO  
-----------        ------------------  
ID  A  C  E        ID  B  D  F  
1   x  x  x        1   x  x  x     
2   x  x  x        2   x  x  x    
3   x  x  x        3   x  x  x

它们的行长相等,并且每列中的 ID 具有相同的排序值。最初,为了合并数据,我使用以下简单的一对一合并语句:

data COMBINED;
    merge DATAONE DATATWO;
run;

这会产生如下输出:

COMBINED           
--------------------      
ID  A  C  E  B  D  F  
1   x  x  x  x  x  x 
2   x  x  x  x  x  x
3   x  x  x  x  x  x

这包含我想要的所有数据,但列的顺序错误。我理想的输出会像这样重新组织列:

COMBINEDTWO           
--------------------      
ID  A  B  C  D  E  F  
1   x  x  x  x  x  x 
2   x  x  x  x  x  x
3   x  x  x  x  x  x

但是,我不确定如何像这样重新组织列。检查 SAS 网站有一个叫做 match-merge 的东西,但这似乎只是用于正确合并行(以防缺少行或其他东西)。任何能帮助我指出正确方向的帮助将不胜感激。

注意:我几乎是 SAS 的初学者,只使用了几天,所以如果这是一个非常简单的问题并且我在搜索时错过了答案,我深表歉意。

【问题讨论】:

    标签: sas


    【解决方案1】:

    首先,您可能想要进行匹配合并:

    data COMBINED;
        merge DATAONE DATATWO;
        by id;
    run;
    

    如果 a) 一个数据集没有按照您认为的方式排序,或者 b) 一个数据集缺少一个或多个 ID,则 1 对 1 合并可能会出现问题。匹配合并确保 ID 匹配。它确实需要在合并之前对数据集进行正确排序。

    其次,您不能直接自动重新排序变量名称。您需要以某种方式构建一个正确排序的变量名称列表,具体取决于您希望如何对它们进行排序。

    一种方法是构造一个列表并在 RETAIN 语句中使用它。这个语句实际上做了一些别的事情,但它用于重新排序变量很方便。

    data COMBINED;
        retain ID A B C D E F;
        merge DATAONE DATATWO;
        by id;
    run;
    

    没关系,但最好将其从数据步骤中移出并放在某个位置以便您可以更轻松地对其进行编辑,尤其是当您需要在多个地方使用它时。一种处理方法是将其放入宏变量中:

    %let varorder = A B C D E F;
    

    那么你可以这样使用它:

    data COMBINED;
        retain ID &varorder.;
        merge DATAONE DATATWO;
        by id;
    run;
    

    请注意,我将 ID 排除在外,因为无论如何这可能都需要放在前面。稍后会很重要。

    现在,这可能适用于您的简短示例,但对于较大的数据集可能不切实际。从数据集中获取该订单怎么样?

    proc contents data=dataone out=var_dataone(keep=name);
    run;
    proc contents data=datatwo out=var_datatwo(keep=name);
    run;
    
    data vars;
    set var_dataone var_datatwo;
    by name;
    if name='ID' then delete;
    run;
    

    好的,现在我们有一个数据集,其中包含我们的姓名,顺序正确。所以我们可以通过几种不同的方式将其拉入一个宏变量中;这是一个。

    proc sql;
     select name into :varorder separated by ' ' 
       from vars
       order by name;
    quit;
    

    现在我们已经根据数据集的内容构造了&varorder。它是按字母顺序排列的;如果您希望以其他顺序对其进行排序,则可以按照自己的喜好对其进行重新排序。如果您想尝试按照数据集上的顺序保留它,您可以使用内容输出中的varnum(将其添加到keep 语句中)。

    【讨论】:

    • 这完美地解决了我的问题,并提供了大量其他有用的信息,这些信息超出了我的问题的原始范围。非常感谢!
    • 没问题。请注意,retain 确实会影响变量在数据步骤中的操作期间的行为,如果它们不是从合并或设置语句中引入的,即,如果您在该合并语句期间创建新变量;如果它在retain 语句中,它的行为会与普通的新变量略有不同(具体来说,如果没有另外设置,它将保持其值逐行)。
    【解决方案2】:

    Joe 的答案是您想要的答案,但顺便说一句,您可以使用 SQL 对数据集中的列重新排序。以您的数据集为例:

    proc sql;
     create table COMBINED_REORDER as
     select ID, A, B, C, D, E, F 
     from COMBINED
    quit;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-15
      • 2021-10-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多