由多个数据集创建 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;
假设有十个具有相同结构的数据集:日期和价格,特别是它们具有相同的时间段但不同的价格
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;