合并列侧向SAS

时间:2018-01-29 11:48:57

标签: sas

我正在尝试将列侧向合并,这导致了许多对多,因为BY值具有Duplicates。

来源:

ID A1 A2 A3
1  x1
1  x2
1     x3
1  x4
1        x5
1        x6

想要:

ID A1 A2 A3
1  x1 x3 x5
1  x2    x6
1  x4

我将列分成3个不同的数据集,并使用带有BY ID的合并语句,但是这并没有为我提供所需的输出数据集。

4 个答案:

答案 0 :(得分:3)

因此,您希望利用SAS如何进行多对多合并,以便您可以将A2的第一个非缺失值与第一个非缺失值A3配对,等等。

但是您需要添加代码以防止正常保留较短列表的最后一个值。发生这种情况是因为SAS不会从较短的数据集中读取任何内容,因此保留从上次观察中读取的值。

使用OUTPUT语句编写观察结果,然后使用CALL MISSING()清空列变量。然后在下一次迭代中,将读取仍在提供观察的输入数据集。

data want ;
  merge have (keep=id a1 where=(not missing(a1)))
        have (keep=id a2 where=(not missing(a2)))
        have (keep=id a3 where=(not missing(a3)))
  ;
  by id;
  output;
  call missing(of A1-A3);
run;

答案 1 :(得分:1)

可以通过在预处理(列拆分)期间添加其他关键项来促进合并。

此示例假定合并仅包含非缺失值。

data have;
input ID A1-A3;
format _numeric_ 2.;
datalines;
1  1  .  .
1  2  .  .
1  3  .  .
1  .  4  .
1  .  .  5
1  .  .  6
;

宏对于生成将要合并的视图很有用。变量seq稍后在merge期间作为by语句中的合成关键项变得非常重要。

* for use with data set named have;
%macro make_view_no_missings (column=);
  data &column / view=&column;
    set have; 
    by id; 
    if first.id then seq = 0;
    if not missing (&column);  * use if instead of where (to ensure original row ordering);
    seq + 1;
    keep id seq &column; 
  run;
%mend;

使用宏创建列条纹的视图。

options mprint;

%make_view_no_missings (column=a1);
%make_view_no_missings (column=a2);
%make_view_no_missings (column=a3);

使用原始密钥(id)加seq

合并条纹
data want;
  merge a1-a3;
  by id seq;
  drop seq;
run;

需要更复杂的预处理来处理剥离缺失值的前导和尾随运行的组列的要求,同时保持内部缺失的运行。

答案 2 :(得分:1)

您应该使用唯一键

进行合并

如果您只对ID进行合并,则SAS会假定一对多关系。 要强制SAS将一个观察值与一个观察值相关联,您应该在by语句中添加一个变量以获取唯一键。

data target;
    merge Source1 Source2 Source3;
    by ID case;
    drop case;
run;

这个额外的变量可以是一个简单的计数器

data Source1 / view=Source1;
    set Source;
    where not missing (A1);
    case = _N_;
    keep ID A1 case;
run;
data Source2 / view=Source2;
    set Source;
    where not missing (A2);
    case = _N_;
    keep ID A2 case;
run;
data Source3 / view=Source3;
    set Source;
    where not missing (A3);
    case = _N_;
    keep ID A3 case;
run;

要完全理解为什么会这样,你应该知道_N_是一个自动变量,设置为观察数。它是在应用where语句后分配的。 (_注意你不能在这里使用if语句,因为这仅在将观察号分配给 N 之后应用。)_

我用

创建了源代码
data source;
    input 
        @1 ID 2.
        @4 A1 $2.
        @7 A2 $2.
        @10 A3 $2.;
datalines;
1  x1
1  x2
1     x3
1  x4
1        x5
1        x6
;
run;

答案 3 :(得分:0)

此代码根据列号创建一行并对其进行合并。我们将它放在决赛桌上。应该是直截了当的。如果您有任何问题,请告诉我。

data ds1;
   length A1 $ 2;
   input ID A1 $;
    n = _N_;
   datalines;
1 x1
1 x2
1 x4
;
data ds2;
   length A2 $ 2;
   input ID A2 $;
    n = _N_;
   datalines;
1 x3
;
data ds3;
   length A3 $ 2;
   input ID A3 $;
    n = _N_;
   datalines;
1 x5
1 x6
;

data Final;
    merge ds1 ds2 ds3;
    by n;
    keep ID A1 A2 A3;
run;