SAS 删除由十位索引的多个变量

SAS drop multiple variables indexed by tens

我的问题可能很愚蠢,但我还没有找到答案。 我有一个变量 var 索引:var10, var20... 变量 90。 在我的代码的某个时刻,我想删除所有这些。

我能做到

data want(drop=var10 var20 var30 var40 var50 var60 var70 var80 var90);
    set have;
run;

我想知道是否有更简洁的方法来做到这一点。我知道是否有索引为 10、11、12、13 的变量...我可以使用

(drop=var10-90)

但是因为我没有它们,如果我使用这个指令它仍然可以完成工作,但是有一个警告,这对我来说是不能接受的(我必须创建程序,这些程序将被几乎没有能力的人使用没有编程知识,所以他们会报告这样的警告。

提前致谢

如果你想删除任何共享一个公共前缀的变量,那么你可以按照下面的步骤操作(请注意,没有任何共享相同前缀的变量是你不想删除的! ):

data want(drop=var:);
    set have;
run;

如果var<xx>变量都是10的倍数,即没有其他以var开头的变量,可以使用冒号运算符,作为通配符,例如

  drop var: ; /* drop all variables beginning with 'var' */

或者,您可以动态生成所有变量的列表:

proc sql noprint ;
  select name into :VARLIST separated by ' '
  from dictionary.columns
  where libname = 'WORK'
    and memname = 'HAVE'
    and compress(name,,'ka') = 'VAR'
    and mod(input(compress(name,,'kd'),8.),10) = 0 /* convert var<xx> to xx and check divisible by 10 */
  order by name ;
quit ;

data want (drop=&VARLIST) ;
  set have ;
run ;

您可以保持下拉列表不变,并在数据步骤之前关闭警告:

options dkrocond=nowarn;

通常我会在带有下拉列表的数据步骤之后立即重新打开警告。

我没有理由不列出九个变量中的每一个。在你的程序中压缩文本可能很好,但在这种情况下,你的收获很小,而且你会失去清晰度。

如果您担心 "optimization"(您的标签),那么我肯定会避免在您的程序中添加额外的步骤,尤其是查询字典表的步骤。

如果你想这样做(假设你有 100 多个变量要删除),只需使用一个简单的宏来创建列表:

%macro varlist;
%do i = 10 %to 90 %by 10;
var&i
%end;
%mend varlist;

然后调用宏:

data want(drop=%varlist);
    set have;
run;

我根据原 post 对这篇 post 进行了大量编辑,以反映 Joe 的评论。

另一种可能的方法是使用双破折号,但应谨慎使用。

drop var10--var90;

套用乔的评论:

It drops every variable that occurs between those two variables in the variable list (ie, from left to right as you look at the dataset, or in varnum order in a proc contents output). Any variable between them would be dropped, no matter what they start with.

以下示例显示变量 x 也将被删除,因为它存在于数据集中的变量 v10 和 v30 之间。一个潜在的危险结果,但仍然是一个潜在的解决方案:

data x;
  v10 = 1;
  x = 'a';
  v30 = 1;
  drop v10--v30;
run;