由多个数据集创建 SAS 面板

SAS-Creating Panel by several datasets

假设有十个具有相同结构的数据集:日期和价格,特别是它们具有相同的时间段但不同的价格

 date       price
 20140604    5
 20140605    7
 20140607    9

我想将它们结合起来创建一个面板数据集。由于每个数据集中都没有名称,我尝试在每个数据中添加一个新变量 name ,然后将它们组合起来。

以下代码用于将name变量添加到每个数据集

%macro name(sourcelib=,from=,going=); 
proc sql noprint;  /*read datasets in a library*/
  create table mytables as
  select *
  from dictionary.tables
  where libname = &sourcelib
  order by memname ;

  select count(memname) 
  into:obs 
  from mytables;

  %let obs=&obs.;

  select memname
  into : memname1-:memname&obs.
  from mytables;
quit;

  %do i=1 %to &obs.;

  data 
  &going.&&memname&i;
  set
  &from.&&memname&i;
 name=&&memname&i;
  run;
%end;
%mend;

那么,这个策略正确吗?是否有不同的方法来创建面板数据?

我无法评论 SQL 代码,但该策略是正确的。为每个数据集添加一个名称,然后使用 PANELBY 语句对名称进行面板。

这是实现您的目标的有效方法。

library.data 语法的宏之间需要 2 个 .。第一个 . 用于连接。第二个显示为 ..

我假设您希望将所有这些数据集附加在一起。您可以添加

data &going..want;
set
  %do i=1 %to &obs;
      &from..&&memname&i
  %end;
;
run;

您可以像这样组合添加名称的循环和数据步骤:

data &going..want;
set
  %do i=1 %to &obs;
      &from..&&memname&i (in=d&i)
  %end;
;
%do i=1 %to &obs;
   if d&i then
      name = &&memname&i;
%end;
run;

实际上有两种方法可以设置重复测量数据。您可以使用您的代码将创建的 TALL 方法。这通常是最灵活的。另一种是宽格式,每个 PRICE 都存储在不同的变量中。这通常不太灵活,但对于某些分析来说可能更容易。

您可能不需要使用宏代码甚至代码生成来合并 10 个数据集。您可能会发现,仅键入 10 个数据集的名称比编写复杂的代码从元数据中提取名称要容易得多。因此,像这样的数据步骤将允许您在 SET 语句中列出任意数量的数据集,并使用成员名称作为区分源数据集的新 PANEL 变量的值。

data want ;
  length dsn  panel  ;
  set in1.panel1 in1.panela in1.panelb indsname=dsn ;
  panel = scan(dsn,-1,'.') ;
run;

如果您的数据集名称遵循可用作 SET 语句中的成员列表的模式,则代码更容易编写。因此,您可以获得一个带有数字后缀的名称列表。

  set in1.panel1-in1.panel10 indsname=dsn ;

或者全部以特定前缀开头的名称。

  set in1.panel:  indsname=dsn ;

如果不同的面板用于相同的日期,那么宽格式可能更容易?然后,您可以按 DATE 合并数据集并重命名各个 PRICE 变量。即生成如下所示的数据步骤:

data want ;
   merge in1.panel1 (rename=(price=price1))
         in1.panel2 (rename=(price=price2))
         ...
   ;
   by date;
run;

或者将 BY 语句添加到构成 TALL 数据集的数据集,然后将其转置为 WIDE 格式可能会更容易。

data tall;
  length dsn  panel  ;
  set in1.panel1 in1.panela in1.panelb indsname=dsn ;
  by date ;
  panel = scan(dsn,-1,'.') ;
run;
proc transpose data=tall out=want ;
  by date;
  id panel;
  var price ;
run;