假设有十个数据集具有相同的结构:日期和价格,特别是它们具有相同的时间段但价格不同
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;
那么,这种策略是否正确?是否有不同的方法来创建面板数据?
答案 0 :(得分:2)
有两种方法可以设置重复测量数据。您可以使用代码将创建的TALL方法。这通常是最灵活的。另一种是宽格式,每个PRICE存储在不同的变量中。这通常不太灵活,但对于某些分析可能更容易。
您可能不需要使用宏代码甚至代码生成来组合10个数据集。您可能会发现只键入10个数据集名称比编写复杂代码以从元数据中提取名称更容易。因此,像这样的数据步骤将允许您在SET语句中列出任意数量的数据集,并使用membername作为区分源数据集的新PANEL变量的值。
data want ;
length dsn $41 panel $32 ;
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 $41 panel $32 ;
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;
答案 1 :(得分:1)
我无法评论SQL代码,但策略是正确的。为每个数据集添加一个名称,然后使用PANELBY语句在名称上面板。
答案 2 :(得分:1)
这是实现您所需要的有效方式。
在.
语法的宏之间需要2 library.data
。第一个.
用于连接。第二个显示为.
。
我假设你想要将所有这些数据集附加在一起。你可以添加
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;