【问题标题】:join the SAS datases sideways, horizontal横向、横向加入 SAS 数据
【发布时间】:2018-05-20 03:47:03
【问题描述】:

我有如下数据集

ID  A1  A2  A3
A   1.2 1.5 1
A   1.3 1.7 1.3
A   1.4 1.8 1.7
B   1.5 1.8 1.9
B  1.6 1.7 1.0

我正在寻找的结果是

A   1.2 1.5 1 1.3 1.7 1.3 1.4 1.8 1.7

我知道 SAS 变量名不能重复,但是当我尝试使用 Proc SQL 时,使用内连接它会给我更多的行。

【问题讨论】:

  • 您是否提前知道每个 ID 的最大行数是多少?此外,使用 SQL 很难做到这一点,除非您的数据集中还有另一个变量,该变量在每个 ID 的第一行从 1 开始,并且对于具有相同 ID 的每个连续行递增 1。

标签: sql join merge sas


【解决方案1】:

SAS 数据步是这里的最佳选择。设置一个数组依次读取每个值,包括跨行,存入一个新数组,读取最后一个ID后才输出。

唯一的问题是您需要知道一个 ID 可以取值的最大数量,即 nrows x ncols(不仅仅是行数)。在您的示例中,分析器为 9,因为 ID A 有 3 行和 3 列。一种解决方案是将新数组中的元素数量设置为高于您认为需要的数量,这仅意味着数据集末尾会有一些空列。我在下面的代码中将值设置为 10。

data have;
input ID $  A1  A2  A3;
datalines;
A   1.2 1.5 1
A   1.3 1.7 1.3
A   1.4 1.8 1.7
B   1.5 1.8 1.9
B  1.6 1.7 1.0
;
run;

data want;
set have;
by id;
retain newA1-newA10; /* keep values across rows */
array oldvars{*} A: ; /* array of existing variables */
array newvars{*} newA1-newA10; /* array of new variables */
if first.id then do; /* reset counter and array values when ID changes */
    counter=0;
    call missing(of newA1-newA10);
    end;
do i = 1 to dim(oldvars); /* loop through each value and store in new array */
    counter+1;
    newvars{counter} = oldvars{i};
end;
if last.id then output; /* only output after last ID is read */
drop A: counter i; /* drop unwanted variables */
run;

【讨论】:

    【解决方案2】:

    类似于 Longfish,但与 DOW 相似。但是,在 DOW 处理中,您不需要保留数组项,因为宽数组是在隐式 DATA Step 循环的单次迭代中填充的。

    * measure the data;
    data _null_;
      set have end=last_row;
      by ID;
      array A A1-A3;
      retain max_group_size 0;
      if first.ID then group_size = 0;
      group_size + 1; * implicit retain;
      if last.ID then max_group_size = max (max_group_size, group_size);
      if last_row then do;
        call symputx ('wide_count', max_group_size * dim(A));
      end;
    run;
    
    * extrude the data;
    data want(keep=ID AX:);
      do _wide_index = 0 by 0 until (last.id);  /* initialize wide_index and loop over group */
        set have;
        by ID;
    
        array A A1-A3;
        array AX AX1-AX&wide_count; * X is for eXtruded :) ;
    
        do _small_index = 1 to dim (A);
          _wide_index + 1;
          AX [ _wide_index ] = A [ _small_index ];
        end;
      end;
      * implicit output occurs here because there is no explicit output statement elsewhere in the step;
    run;
    

    【讨论】:

      猜你喜欢
      • 2019-08-01
      • 2014-02-27
      • 1970-01-01
      • 1970-01-01
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-23
      相关资源
      最近更新 更多