使用包含varnames列表的宏变量删除变量

时间:2015-01-15 16:17:10

标签: sas sas-macro

SAS初学者。我想从输入中删除变量列表。此列表本身作为另一个数据集中的观察结果出现。在做了一些谷歌搜索之后,我找到了关于这个主题的优秀论文。

http://www2.sas.com/proceedings/sugi30/028-30.pdf

所以我使用以下代码在宏变量中创建一个列表:

/*make a list of variables as a macro variable */

data _null_;

length allvars $1000;

retain allvars ' ';

set to_drop end=eof;

allvars = trim(left(allvars))||' '||left(_name_);

if eof then call symput('varlist', allvars);

run;

我现在面临三个问题:

1)当我%PUT &VARLIST时,日志只显示31个变量,而我的列表实际上是2000+变量。

2)我不清楚这句话:trim(left(allvars)) || ' ' || left(_name_);正在做什么。我知道修剪删除了前导空格,左边是对齐左边的字符串,但无法理解完整的语句。

3)然后我尝试使用以下代码从输入中删除它,我收到一条警告消息并且没有发生丢弃:

    data inputds2 (drop = &varlist);
    set inputds;
    run;



WARNING: The variable avg_weighted in the DROP, KEEP, or RENAME list has never been referenced.

NOTE: There were 43662 observations read from the data set WORK.INPUTDS.

NOTE: The data set WORK.INPUTDS2 has 43662 observations and 3465 variables.

实际上我的变量名称如下:avg_weighted_minutes_view_3739 avg_weighted_minutes_view_7963 avg_weighted_minutes_view_(XXXX)最后4位是随机的。这是SAS生成的名称,因为我的标签包含空格。

编辑:尝试使用另一个部分工作的代码 - 它创建了一个更大的列表 - & VARLIST宏变量中的2000多个变量中的大约1000个。

data _null_;

set to_drop;

call symput('varlist',trim(

resolve('&varlist')

)||' '||trim(_name_));

run;

%put &varlist;

1 个答案:

答案 0 :(得分:3)

我将按照提供的顺序回答。

1。)如果您要删除2,000多个变量,则1,000个字符不足以保存变量名称列表,因此列表将被截断。您需要在空数据步骤中为allvars变量分配更多空间,如下所示:

data _null_;
    length allvars $ 10000; /* You may need even more! */
    retain allvars;
    set to_drop end=eof;
    allvars = trim(left(allvars)) || ' ' || left(_name_);
    if eof then call symput('varlist', allvars);
run;

您可能收到了您记下的日志消息,因为当列表长度达到1,000个字符时,其中一个变量名被截断。分配更多空间将有助于此。

2。)trim()函数从字符串中删除尾随空白。 left()左对齐字符串中的字符值,因此任何前导空格都会被推到后面。 ||是SAS中的字符串连接运算符。所以完整的声明是这样做的:

  • 从列表中删除空格,以便" x y "变为"x y"
  • 在末尾添加空白以分隔变量名称,因此"x y"变为"x y "
  • 将下一个变量名添加到字符串中,例如"x y "变为"x y z"。最后一个变量名是左对齐的,因此变量名之间只有一个空格。

3。)您正在获取该日志消息,因为数据集to_drop中的变量是输入数据集中不存在的(如果{不可行则没有意义) {1}}是作为PROC CONTENTS或类似的输出而创建的,或者列表被截断,如我所提到的。要避免在PROC CONTENTS中输出to_drop时出现问题,您可以过滤掉输入数据集中不存在的变量,如下所示:

to_drop

但如果问题是名称被切断,分配更多长度将解决这个问题。


或许更好的方法是使用PROC SQL一步到位。这将确保宏变量proc sql; create table to_drop2 as select distinct a._name_ from to_drop as a inner join dictionary.columns as b on a._name_ = b.name where b.memname = 'INPUTDS'; quit; 尽可能长,直到最大允许长度。

varlist

请注意,如果proc sql noprint; select distinct a._name_ into :varlist separated by ' ' from to_drop as a inner join dictionary.columns as b on a._name_ = b.name where b.memname = 'INPUTDS'; quit; 仅包含dictionary.columns中的变量,则无需加入to_drop