带有多个VAR选项的SAS转置表

时间:2019-06-04 12:05:59

标签: arrays sas transpose

我有一张桌子,看起来像:

ID     NAME    TYPE        DATE_VALUE    STRING_VALUE      NUMBER_VALUE  
1    revenue report_date    01jan2018
1    revenue    name                     Revenue_12m
1    revenue    code                                           1100
1    revenue    sum                                           6000000

我希望它看起来像:

ID     NAME     report_date     name          code       sum
1    revenue     01jan2018    Revenue_12m     1100     6000000

我的代码给出了错误的结果(3行):

proc transpose data=tab1 out=tab2;
by id name;
var number_value string_value date_value;
id type;
run;

2 个答案:

答案 0 :(得分:1)

假设您的类型是少数项目,请考虑使用SQL中的条件聚合:

proc sql;
    create table output as
    select ID, NAME,
           MAX(case when TYPE = 'name' then STRING_VALUE else "" end) AS report_name,
           MAX(case when TYPE = 'report_date' then DATE_VALUE else . end) AS report_date format=date9.,
           MAX(case when TYPE = 'code' then NUMBER_VALUE else . end) AS code,
           MAX(case when TYPE = 'sum' then NUMBER_VALUE else . end) AS sum
    from raw
    group ID, NAME;
quit;

输入

data raw;
    infile datalines delimiter=',' DSD; 
    length NAME $ 7 TYPE $ 11 STRING_VALUE $11 NUMBER_VALUE 7;
    input ID NAME $ TYPE $ STRING_VALUE $ NUMBER_VALUE DATE_VALUE date9.;
    format DATE_VALUE DATE9.;
    datalines;
1,revenue,report_date,,.,01jan2018
1,revenue,name,Revenue_12m,.,.
1,revenue,code,,1100,.
1,revenue,sum,,6000000,.
;

输出

ID    NAME   report_name   report_date  code     sum 
 1 revenue   Revenue_12m     01JAN2018  1100 6000000 

答案 1 :(得分:0)

您可以通过运行PROC TRANSPOSE三次(每种数据类型一次)来解决此问题。 您还需要消除与名为NAME的变量的冲突。

所以首先让我们创建示例数据。

data have;
  input ID $ xNAME $ TYPE :$32. DATE_VALUE :date. STRING_VALUE :$50. NUMBER_VALUE;
  format date_value date9.;
cards;
1 revenue report_date 01jan2018 . .
1 revenue name        . Revenue_12m .
1 revenue code        . . 1100
1 revenue sum         . . 6000000
;

现在我们可以生成三个单独的数据集。

proc transpose data=have out=dates(drop=_name_);
  where not missing(date_value);
  by id xname;
  var date_value;
  id type;
run;
proc transpose data=have out=strings(drop=_name_);
  where not missing(string_value);
  by id xname;
  var string_value;
  id type;
run;
proc transpose data=have out=numbers(drop=_name_);
  where not missing(number_value);
  by id xname;
  var number_value;
  id type;
run;

并将它们结合起来。

data want;
  merge dates strings numbers;
  by id xname;
run;

请注意,此方法不会为始终缺少的TYPE值创建列。您可以更改WHERE语句以列出使用该特定源变量的TYPE值。但是,那么您将需要事先知道TYPE的可能值的列表,在这种情况下,为什么不只是编写数据步骤来进行转换。像这样:

data want;
  length id $8 xname $50 report_date 8 name $50 code sum 8 ;
  format report_date date9.;
  do until(last.xname);
    set have ;
    by id xname ;
    select (type);
      when ('report_date')  report_date=date_value;
      when ('name')  name=string_value;
      when ('code')  code=number_value;
      when ('sum')  sum=number_value;
      otherwise put 'WARNING: Unknown type. ' id= xname= type= ;
    end;
  end;
  drop type date_value string_value number_value;
run;

如果您有关于数据的元数据,则可以使用它来定义变量并生成SELECT语句。