通过SAS存储过程中的动态列列表获取数据

时间:2014-03-25 20:58:09

标签: sas sas-macro

我的目标是创建SAS存储过程,即返回单个数据集的数据,并根据传递到存储过程的多值输入参数过滤该数据集中的列。

有一种简单的方法吗?

有没有办法做到这一点?

这是我到目前为止所拥有的。我正在使用宏来动态生成KEEP语句来定义要返回的列。我在顶部定义了宏变量,以模仿通过SAS BI Web Services调用时传递到存储过程的内容,所以很遗憾,这些变量必须保持原样。这就是我尝试使用VVALUEX方法将列名字符串转换为变量名称的原因。

注意 - 我是SAS新手

libname fetchlib meta library="lib01" metaserver="123.12.123.123"
password="password" port=1234
repname="myRepo" user="myUserName";

/* This data represents input parameters to stored process and 
 * is removed in the actual stored process*/
%let inccol0=3;
%let inccol='STREET';
%let inccol1='STREET';
%let inccol2='ADDRESS';
%let inccol3='POSTAL';
%let inccol_count=3;

%macro keepInputColumns;
    %if &INCCOL_COUNT = 1 %then
        &inccol;
    %else
        %do k=1 %to (&INCCOL_COUNT);
             var&k = VVALUEX(&&inccol&k);
        %end;
        KEEP
        %do k=1 %to (&INCCOL_COUNT);
             var&k
        %end;
        ;
%mend;

data test1;
    SET fetchlib.Table1;
    %keepInputColumns;
run;

/*I switch this output to _WEBOUT in the actual stored process*/
proc json out='C:\Logs\Log1.txt';
    options firstobs=1 obs=10;
   export test1 /nosastags;
run;

这有一些问题。输出使用var1,var2和var3作为列名,而不是实际的列名。当我将输出更改为_webout并使用BI Web Services运行它时,它也不会被任何列过滤。

2 个答案:

答案 0 :(得分:1)

好的,我想我对你在这里做的事情有所了解。

您可以结合使用KEEP和RENAME来获取变量名称。

KEEP
        %do k=1 %to (&INCCOL_COUNT);
             var&k
        %end;
        ;

这有一个等价的

RENAME
        %do k=1 %to (&INCCOL_COUNT);
             var&k = &&inccol&k.
        %end;
        ;

现在,只要用户不单独保留原始变量,你就可以了。 (如果他们这样做,那么你会遇到冲突和错误)。

如果这种方式不能满足您的需求,而且我没有_webout的解决方案,因为我没有可以使用的服务器,您可以考虑以稍微不同的方式尝试这种方式。

proc format;
  value agef
  11-13 = '11-13'
  14-16 = '14-16';
quit;

ods output report=mydata(drop=_BREAK_);
proc report data=sashelp.class nowd;
format age agef.;
columns name age;
run;
ods output close;

第一部分只是一个proc格式,表明它抓取格式化值而不是基础值。 (我认为这是理想的,好像这不是一件容易的事。)

现在,我认为您可以更方便地将数据放在数据集中,并且可以根据需要将其输出到JSON。在你的例子中,你会做类似

的事情
ods output report=work.mydata(drop=_BREAK_);
proc report data=fetchlib.Table1 nowd;
columns 

    %do k=1 %to (&INCCOL_COUNT);
       &&inccol&k.;
    %end;
;
run;
ods output close;

然后您可以将该数据集发送到JSON或其他任何内容。实际上你甚至可能比这更直接,但我几乎不知道任何有关PROC JSON的事情。

阅读有关JSON的更多信息,您实际上可能有更简单的方法来执行此操作。

export行上,您有各种格式选项。因此,假设我们的数据集只是原始数据集的一部分:

proc json out='C:\Logs\Log1.txt';
    options firstobs=1 obs=10;
   export fetchlib.Table1
   (
    %do k=1 %to (&INCCOL_COUNT);
               &&inccol&k.;
            %end;
    )

  / nosastags FMTCHARACTER  FMTDATETIME  FMTNUMERIC ;
run;

此方法不允许更改变量顺序;如果需要,可以使用中间数据集:

data intermediate/view=intermediate;
set fetchlib.Table1;
retain
       %do k=1 %to (&INCCOL_COUNT);
           &&inccol&k.;
        %end;
;
keep
       %do k=1 %to (&INCCOL_COUNT);
           &&inccol&k.;
        %end;
 ;
run;

然后写出来。我只是猜测你可以在这种情况下使用一个视图。

答案 1 :(得分:0)

事实证明,实现这一点的最简单方法是改变列(即SAS变量)传递到存储过程的方式。虽然Joe的回答很有帮助,但我最后通过将列作为空格分隔的列列表传递给keep语句来解决问题,这大大简化了SAS代码,因为我没有必要处理列的动态列表。

libname fetchlib meta library="lib01" metaserver="123.12.123.123"
password="password" port=1234
repname="myRepo" user="myUserName";"&repository" user="&user";

proc json out=_webout;
   export fetchlib.&tablename(keep=&columns) /nosastags;
run;

&columns设置为以下内容:

  

Column1 Column2 Column3