强制proc导出为非现有变量创建空白列

时间:2018-01-29 11:40:02

标签: csv sas export sas-macro

背景

我正在运行下面的宏来在循环中导出大量数据集。不幸的是,其中一些数据集有额外的变量。我的目的是以相同的格式导出所有文件,其中不存在的列作为空白提供

数据

这可以用以下数据集来说明。

dataA

varA varB
1    3
2    3
3    3

dataB

varA varB
9    4
9    4
9    4

dataC

varA varB varC
2    5    6
2    5    6
2    5    6

我希望我的CSV文件看起来如下:

dataA.CSV

varA varB varC
1    3    .
2    3    .
3    3    .

dataB.CSV

varA varB varC
9    4    .
9    4    .
9    4    .

dataC.CSV

varA varB varC
2    5    6
2    5    6
2    5    6

%macro export_data(dsnms);
    * Get observations count;
    PROC SQL;
        SELECT COUNT(*) INTO :obscount
            FROM &dsnms;
    QUIT;

    * Export all available files in the loop;
    %Local D;

    %DO D = 1 %TO &obscount;

        * Print progress message;
        sysecho "Progressing through &D of &obscount";

        * Get table name;
        PROC SQL;
            SELECT COMPRESS(MEMNAME) INTO: Table
                FROM &dsnms
                    WHERE rownum=&D;
        QUIT;

        * Extra spaces in file name are removed via cmpres call;
        PROC EXPORT DBMS=CSV DATA=SASLIBWITHSTUFF.&Table
            OUTFILE="/mystuff/%cmpres(&Table).csv";
        RUN;

        * Inform about succesful export;
        sysecho "Created &Table..csv export file.";
    %END;
%mend;

摘要

换句话说,我想修改 proc export 的行为来创建 NonExistingVar ,如果在{{1}中传递了这种情况}。当然,这会失败,因为Kepp =没有 sashelp.class ,但这是我想要模仿的行为。

NonExistingVar

2 个答案:

答案 0 :(得分:2)

如果某个宏变量包含要导出的列的列表,则可以构造包含它们的视图,包括底层数据集中不存在的视图,并导出视图。 E.g。

%let keepcols = sex weight newcol;

data t_view /view = t_view;
  if 0 then set sashelp.class; 
  if _n_ = 1 then call missing(of &keepcols);
  set sashelp.class;
run;

if 0 then set xyz是一个不错的小技巧,它允许您保留列顺序,长度和类型,而无需读取第一个set语句中的任何行。它随后在将变量设置为缺失值时避免了冲突类型 - 我们必须将它们初始化为某些东西,否则它们不会输出。然后,第二个set语句将覆盖实际存在的变量的缺失值。

如果您查询元数据表以确定哪些保留列存在,那么可以提高效率,因此您只需加载那些列,但这对于大多数情况来说应该是合理的。

更长的选项是临时禁用与保持相关的错误和警告,例如:

%let keepcols = sex weight newcol;

%let dkricond = %sysfunc(getoption(dkricond)); /*Save for later*/
option dkricond = nowarn;

data t_view /view = t_view;
  if 0 then set sashelp.class(keep = &keepcols); /*Normally this would trigger an error or warning*/
  retain &keepcols;
  set sashelp.class(keep = &keepcols); 
run;

option dkricond = &dkricond; /*Restore original setting*/

答案 1 :(得分:0)

要使其工作,您需要有一个要输出的变量列表。所以我们假设你有一个带有该列表的宏变量。

%let varlist=varA varB varC ;

由于您正在编写CSV文件,因此您可以直接使用DATA步骤执行此操作,并避免使用PROC EXPORT。在数据步骤中,如果您引用不存在的变量,那么SAS将很乐意为您创建一个空变量。

您可能需要有点创意才能添加标头记录。以下是使用TRANWRD()函数的一种方法,当每个变量名之间只有一个空格时,该函数可以正常工作。请注意,您可以使用COMPBL()来实现这一点。

%let varlist=Name Unknown    Age ;
%let varlist=%sysfunc(compbl(&varlist));

data _null_;
  file "/stuff/proc_test.csv" dsd ;
  if _n_=1 then put "%sysfunc(tranwrd(&varlist,%str( ),%str(,)))" ;
  set sashelp.class ;
  put &varlist ;
run;

结果:

Name,Unknown,Age
Alfred,,14
Alice,,13
Barbara,,13
Carol,,14
Henry,,14
James,,12
Jane,,12
Janet,,15
Jeffrey,,13
John,,12
Joyce,,11
Judy,,14
Louise,,12
Mary,,15
Philip,,16
Robert,,12
Ronald,,15
Thomas,,11
William,,15