在将PROC APPEND与空BASE一起使用时定义BASE结构

时间:2019-05-07 09:59:17

标签: sas

我正在尝试通过宏循环的迭代来创建单个数据集。我发现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结构的方法?

3 个答案:

答案 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;