我正在尝试通过宏循环的迭代来创建单个数据集。我发现proc append不需要定义的BASE即可使用,因此方法应该可行。但是,我遇到了名称长度可变的问题。
我创建了一个简单的,可复制的示例来演示我的问题。当然,这不是创建最终want
数据集的最有效方法,但是此过程在我的代码中模拟了工作流程。
proc sql;
select name from sashelp.class;
select name
into :name_1 - :name_&sqlobs
from sashelp.class;
quit;
%macro forward_loop;
%do i = 1 %to 10;
proc sql;
create table temp as
select
"&&name_&i" as name,
age
from sashelp.class
quit;
proc append base=want data=temp;
run;
%end;
%mend;
%forward_loop;
注意:将WORK.TEMP附加到WORK.WANT。
警告:变量名称在BASE和DATA文件(BASE 6 DATA 7)上具有不同的长度。
错误:由于上面列出的异常,没有附加操作。使用FORCE选项附加这些文件。
注意:添加了0个观察值。
我相信我可以在proc sql步骤中解决此问题,只需指定name
填充到某个标准长度即可。但是,我无法弄清楚该怎么做。
这是正确的方法吗?还是有一种无需在BASE中有任何数据行的情况下创建BASE结构的方法?
答案 0 :(得分:2)
如果您创建结构一致的数据集,那么让PROC APPEND从第一个增量数据集创建基础数据集将可以正常工作。
在您的示例中,您是从字符串文字创建NAME的,而没有告诉SAS变量需要多长时间。因此,默认情况下,将创建与字符串文字一样长的内容。如果您确实在PROC SQL中使用该方法,则将LENGTH属性添加到SELECT语句中的列定义。
"&&name_&i" as name length=8
如果您实际上是在执行数据步骤,则在给变量赋值之前先定义长度。
length name $8;
name = "&&name_&i";
但是最好只在进入循环之前先定义BASE数据集。
data want;
length name $8 age 8 ;
stop;
run;
答案 1 :(得分:1)
只需使用datastep创建一个数据集。 stop
将确保不会撰写任何意见。但是比起您,还必须使用FORCE
将较小的值放入数据集中。
data want;
length name $7;
stop;
run;
以相同方式创建基本数据集,但使用insert into代替proc append。
答案 2 :(得分:1)
很难理解您的示例是否真的是您想做的事情。
在PROC SQL中定义名称的长度。
proc sql noprint;
*select name from sashelp.class;
select name into :name_1- from sashelp.class;
quit;
%put _global_;
%macro forward_loop;
%do i = 1 %to 10;
proc sql;
create table temp_&i as
select
"&&name_&i" as name length=8,
age
from sashelp.class
quit;
%end;
%mend;
options mprint=1;
%forward_loop;
data want;
if 0 then set sashelp.class(keep=name age);
set temp_: open=defer;
run;