【问题标题】:Define BASE structure when using PROC APPEND with empty BASE使用带有空 BASE 的 PROC APPEND 时定义 BASE 结构
【发布时间】:2019-05-07 21:19:46
【问题描述】:

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

【问题讨论】:

    标签: sas


    【解决方案1】:

    如果您创建结构一致的数据集,那么让 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;
    

    【讨论】:

      【解决方案2】:

      只需使用 datastep 创建一个数据集。 stop 将确保不会写入任何观察。但是,您还必须使用 FORCE 将较小的数据放入数据集中。

      data want;
        length name $7;
        stop;
      run;
      

      以同样的方式创建基础数据集,但使用 insert into 而不是 proc append。

      【讨论】:

      • 哪个资源占用少?大量 proc sql 插入,还是每 x 次迭代都会有大量 proc 附加数据步骤?我的实际宏有一个%while(&continue=1) 步骤,在其中它迭代一组计算,准备想要的表,然后用它来确定我们是否继续。
      • 当要附加的数据集由创建表创建时,我将使用插入代替,这取决于其余代码。当它由其他东西生成时 proc append.
      【解决方案3】:

      很难理解你的例子是否真的是你想做的。

      在 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;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-14
        • 2020-02-12
        • 1970-01-01
        • 1970-01-01
        • 2012-09-13
        • 2020-08-09
        • 1970-01-01
        • 2012-10-12
        相关资源
        最近更新 更多