如何更简单地转置数据集

时间:2020-10-28 08:07:10

标签: sas dataset transpose

我想使数据集如下所示。我知道了,但是程序很长。 我认为它将变得更加简单。如果您有个好主意,请给我一些建议。 enter image description here

这是数据。

data test;
input ID $ NO DAT1 $ TIM1 $ DAT2 $ TIM2 $;
cards;
1   1   2020/8/4    8:30    2020/8/5    8:30
1   2   2020/8/18   8:30    2020/8/19   8:30
1   3   2020/9/1    8:30    2020/9/2    8:30
1   4   2020/9/15   8:30    2020/9/16   8:30
2   1   2020/8/4    8:34    2020/8/5    8:34
2   2   2020/8/18   8:34    2020/8/19   8:34
2   3   2020/9/1    8:34    2020/9/2    8:34
2   4   2020/9/15   8:34    2020/9/16   8:34
3   1   2020/8/4    8:46    2020/8/5    8:46
3   2   2020/8/18   8:46    2020/8/19   8:46
3   3   2020/9/1    8:46    2020/9/2    8:46
3   4   2020/9/15   8:46    2020/9/16   8:46
;
run;

这是我的程序。

 data
 t1(keep = ID A1 A2 A3 A4)
 t2(keep = ID B1 B2 B3 B4)
 t3(keep = ID C1 C2 C3 C4)
 t4(keep = ID D1 D2 D3 D4);
 set test;
 if NO = 1 then do;
 A1 = DAT1;
 A2 = TIM1;
 A3 = DAT2;
 A4 = TIM2;
 end;
 *--- cut (NO = 2, 3, 4 are same as NO = 1)--- ;
 end;
 if NO = 1 then output t1;
 if NO = 2 then output t2;
 if NO = 3 then output t3;
 if NO = 4 then output t4;
run;

proc sort data = t1;by ID; run;
proc sort data = t2;by ID; run;
proc sort data = t3;by ID; run;
proc sort data = t4;by ID; run;
data test2;
 merge t1 t2 t3 t4;
 by ID;
run;

2 个答案:

答案 0 :(得分:2)

由于结果看起来像报告,因此请使用报告工具。

proc report data=test ;
  column id no,(dat1 tim1 dat2 tim2 n) ;
  define id / group width=5;
  define no / across ' ' ;
  define n / noprint;
run;

答案 1 :(得分:0)

通常是从高到大的数据转换

  • 粗略地将数据放入元数据(列名或标签)或丢失引用上下文,或者
  • 用于人类消费的报告布局

假设“像下面这样的数据集”是准确的,并且您希望以这种方式来旋转数据。

方法1-具有重命名功能的自合并子集

您应该看到NO字段是一个序列号,在合并数据集时可以用作BY变量。

将此示例代码视为可以可以作为宏的源代码生成的模板:

NO更改为seq以便更清楚

data want;
  merge
    have (where=(seq=1) rename=(dat1=A1 tim1=B1 dat2=C1 tim2=D1)
    have (where=(seq=2) rename=(dat1=A2 tim1=B2 dat2=C2 tim2=D2)
    have (where=(seq=3) rename=(dat1=A3 tim1=B3 dat2=C3 tim2=D3)
    have (where=(seq=4) rename=(dat1=A4 tim1=B4 dat2=C4 tim2=D4)
  ;
  by id;
run;

对于以上述模式组织的未知数据集,代码生成要求应该很明显;确定最大序列并指定要旋转的变量的名称(作为宏参数,名称在其中发生循环)。

方法2-多个转置

警告,所有枢轴化的列均为字符类型,并包含原始值的格式化结果。

proc transpose data=have(rename=(dat1=A tim1=B dat2=C tim2=D)) out=stage1;
  by id seq;
  var a b c d;
run;
  
proc transpose data=stage1 out=want;
  by id;
  var col1;
  id _name_ seq;
run;

方法3-使用数组和DOW循环

* presume SEQ is indeed a unit monotonic sequence value;
data want (keep=id a1--d4);
  do until (last.id);
    array wide A1-A4 B1-B4 C1-C4 D1-D4;
    wide [ (seq-1)*4 + 1 ] = dat1;
    wide [ (seq-1)*4 + 2 ] = tim1;
    wide [ (seq-1)*4 + 3 ] = dat2;
    wide [ (seq-1)*4 + 4 ] = tim2;
  end;
  
  keep id A1--D4;

*  format A1 A3 B1 B3 C1 C3 D1 D3 your-date-format;
*  format A2 A4 ................. your-time-format;

方法4-将数据值更改为datetime

我会将此留给尊敬的人

相关问题