【问题标题】:Conditionally replace column values with column name in SAS dataset有条件地将列值替换为 SAS 数据集中的列名
【发布时间】:2014-04-27 07:28:32
【问题描述】:

我有一个 SAS 数据集如下:

Key    A    B    C    D    E
001    1    .    1    .    1
002    .    1    .    1    .

除了保留现有的变量,我想用变量名替换变量值,如果变量 A 的值为 1,那么新变量的值应该为 A,否则为空。

目前我正在对值进行硬编码,有人有更好的解决方案吗?

【问题讨论】:

    标签: sas sas-macro


    【解决方案1】:

    以下应该可以解决问题(第一个 dstep 设置示例):-

    data test_data;
      length key A B C D E 3;
      format key z3.;  **  Force leading zeroes for KEY;
      key=001; A=1; B=.; C=1; D=.; E=1; output;
      key=002; A=.; B=1; C=.; D=1; E=.; output;
    proc sort;
      by key;
    run;
    
    data results(drop = _: i);
      set test_data(rename=(A=_A B=_B C=_C D=_D E=_E));
    
      array from_vars[*] _:;
      array to_vars[*] $1 A B C D E;
    
      do i=1 to dim(from_vars);
        to_vars[i] = ifc( from_vars[i], substr(vname(from_vars[i]),2), '');
      end;
    run;
    

    这看起来有点尴尬,因为我们必须重命名原始(假定为数字)变量,然后创建可以保存值“A”、“B”等的同名字符变量。

    如果您的“真实”数据有更多变量,重命名可能会很费力,因此您可能会发现双 proc 转置更有用:-

    proc transpose data = test_data out = test_data_tran;
      by key;
    proc transpose data = test_data_tran out = results2(drop = _:);
      by key;
      var _name_;
      id _name_;
      where col1;
    run;
    

    但是,您的变量在输出数据集上的顺序错误,并且长度为 8 美元而不是 1 美元,这可能会浪费空间。如果任何一点都很重要(它们通常很重要)并且两者都可以通过在后续数据步骤中使用length 语句来纠正:-

    option varlenchk = nowarn;
      data results2;
        length A B C D E $1;
        set results2;
      run;
    option varlenchk = warn;
    

    这会以正确的顺序组织变量并最小化它们的长度。尽管如此,您现在仍在对变量名称进行硬编码,这意味着您还不如坚持使用原始数组方法。

    【讨论】:

    • +1,很好的完整答案。您可以使用dictionary.columns 驱动其中任何一个硬编码位的宏变量实现,以避免硬编码。
    猜你喜欢
    • 1970-01-01
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2018-11-02
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多