【问题标题】:Horizontally combine three SAS datasets with renaming of columns通过重命名列水平组合三个 SAS 数据集
【发布时间】:2017-02-28 18:55:06
【问题描述】:

我正在使用 SAS Enterprise guide 并希望将三个单独的数据集合并为一个数据集。所有数据集都有一列具有相同的长度、数据类型和列标题:

我的数据如下(三个表,每个 1 列):

data1         data2        data3

apples        apples       apples
100           200          300
55            77           80
3422          32432        1234 

我希望我的输出数据如下所示(一张表,3 列)。列标题应更改为我选择的名称:

output_data

green_apples  red_apples   yellow_apples
100           200          300
55            77           80
3422          32432        1234 

我搞砸了 SAS 合并语句和 proc_sql,但据我所见,我总是需要添加一些通用标识符(用于 BY 语句或类似的东西)。

有没有一种快速的方法来做我想做的事?

感谢您的帮助。

【问题讨论】:

    标签: sas proc-sql


    【解决方案1】:
    data want;
      merge a(rename=apples=green_apples) 
            b(rename=apples=red_apples) 
            c(rename=apples=yellow_apples)
      ;
    run;
    

    按照您的说法,将数据集合并在一起,不使用by 语句。有一个选项 (options mergenoby=ERROR|WARN|NOWARN) 可能会使此语句错误或产生警告(因为这通常是错误的),但您可以将其转为 NOWARN 以避免这种情况。

    在不创建人工行标识符的情况下,没有一种在 SQL 中执行此操作的好方法。

    【讨论】:

    • 这是有道理的,但它不允许我重命名列标题。
    • 另外,您可能想提及这是一次性的事情,还是您想以可重现的模块化方式做的事情。存在更复杂的解决方案,它们更适合您需要灵活的事情,但对于一次性的情况来说过于矫枉过正。
    • 这只是一次性的事情,所以这是完美的。非常感谢!
    【解决方案2】:

    与您发布的内容完全匹配的一种快速而肮脏的解决方案是:

    data output_data;
        set data1 (rename=(apples = green_apples));
        set data2 (rename=(apples = red_apples));
        set data3 (rename=(apples = yellow_apples));
    run;
    

    请记住,此解决方案将受到最小数据集中观察数量的限制。

    但是,您似乎希望按照它们在数据集中出现的顺序来匹配记录?如果是这样,描述顺序的标识符字段将很有帮助(例如,如果数据集具有不同的观察计数)。一种方法是使用_N_ 自动变量:

    /*
        Changing observation counts
    */
    data data1;
        id = _N_;
        input apples 8.;
        cards;
    100
    55
    3422
    ;
    run;
    
    data data2;
        id = _N_;
        input apples 8.;
        cards;
    200
    77
    32432
    1
    2
    ;
    run;
    
    data data3;
        id = _N_;
        input apples 8.;
        cards;
    300
    80
    1234 
    5
    ;
    run;
    
    data output_data;
        merge data1 (in=d1 rename=(apples = green_apples))
              data2 (in=d2 rename=(apples = red_apples))
              data3 (in=d3 rename=(apples = yellow_apples));
        by id;
        if d1 or d2 or d3;
    run;
    

    在这里,数据集选项 (in=d1... 创建一个临时变量 d1 并将其设置为 1,如果来自 data1 的记录与来自 data2data3 的记录匹配 id

    【讨论】:

    • if d1 or d2 or d3 毫无意义,这是默认设置。 (一条记录如何出现在 output_data 数据集中,而不是来自三个数据集之一?)
    • set 选项是一种可能的解决方案,但您绝对应该提到它与合并之间的主要区别 - SAS 如何处理不同大小的数据集。
    • 好点。 if 声明和 in 选项旨在显示 SAS 的想法,并且根据问题,OP 似乎需要一些背景知识。此外,set 解决方案将受到列出的 first 数据集中的观察数量的限制。
    • 我建议将其放在答案中,而不是在 cmets 中。
    • 其实 - 你有一个问题,我误读了你的评论。观察次数不受 first 数据集的限制。它受 smallest 数据集的限制。 (因此,如果 d1 和 d2 有 100 而 d3 有 50,那么您将得到 50。)当任何 set 语句未能检索到一行时,数据步骤结束。
    猜你喜欢
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-07
    • 2021-09-01
    • 2019-03-16
    • 2018-10-12
    相关资源
    最近更新 更多