4

我有一个这样的数据集(但有几百个变量):

id  q1  g7  q3  b2  zz  gl  az  tre
1   1   2   1   1   1   2   1   1
2   2   3   3   2   2   2   1   1
3   1   2   3   3   2   1   3   3
4   3   1   2   2   3   2   1   1
5   2   1   2   2   1   2   3   3
6   3   1   1   2   2   1   3   3

我想保留 ID、b2 和 tre,但将其他所有内容设置为缺失。在这么小的数据集中,我可以轻松使用call missing (q1, g7, q3, zz, gl, az)- 但在具有更多变量的集合中,我实际上想说call missing (of _ALL_ *except ID, b2, tre*)

显然,SAS 无法读懂我的想法。我已经考虑过涉及另一个数据步骤或 proc sql 的解决方法,我将原始变量复制到新的 ds 并将它们合并回 post,但我正在尝试找到一个更优雅的解决方案。

4

3 回答 3

8

该技术使用未执行的集合语句(仅编译时函数)来定义原始数据集中的所有变量。保持顺序和所有变量属性类型、标签、格式等。基本上将所有变量设置为缺失。将执行的下一个 SET 语句仅引入不应设置为缺失的变量。它没有明确地将变量设置为缺失,但达到了相同的结果。

   data nomiss;
       input id  q1  g7  q3  b2  zz  gl  az  tre;
       cards;
    1   1   2   1   1   1   2   1   1
    2   2   3   3   2   2   2   1   1
    3   1   2   3   3   2   1   3   3
    4   3   1   2   2   3   2   1   1
    5   2   1   2   2   1   2   3   3
    6   3   1   1   2   2   1   3   3
    ;;;;
       run;
    proc print;
       run;
    data manymiss;
       if 0 then set nomiss;
       set nomiss(keep=id b2 tre:);
       run;
    proc print;
       run;

在此处输入图像描述

于 2016-02-02T21:26:24.863 回答
2

另一个相当简单的选项是使用宏和基本的代码编写技术将它们设置为缺失。

例如,假设我们有一个宏:

%call_missing(var=);
  call missing(&var.);
%mend call_missing;

现在我们可以编写一个查询dictionary.columns来识别我们想要设置为缺失的变量:

proc sql;
  select name 
    from dictionary.columns
    where libname='WORK' and memname='HAVE'
    and not (name in ('ID','B2','TRE'));  *note UPCASE for all these;
quit;

现在,我们可以结合这两件事来获得一个包含我们想要的代码的宏变量,并使用它:

proc sql;
  select cats('%call_missing(var=',name ,')')
    into :misslist separated by ' '
    from dictionary.columns
    where libname='WORK' and memname='HAVE'
    and not (name in ('ID','B2','TRE'));  *note UPCASE for all these;
quit;

data want;
  set have;
  &misslist.;
run;

这样做的好处是它不关心变量类型,也不关心顺序。它的缺点是它的代码有点多,但它不应该特别长。

于 2016-02-02T21:18:19.570 回答
1

如果变量都是相同类型(数字或字符),那么您可以使用数组。

data want ;
  set have;
  array _all_ _numeric_ ;
  do over _all_;
     if upcase(vname(_all_)) not in ('ID','B2') then _all_=.;
  end;
run;

如果您不关心顺序,那么只需删除变量并使用 0 个观察值重新添加它们。

data want;
   set have (keep=ID B2 TRE:) have (obs=0 drop=ID B2 TRE:);
run;
于 2016-02-02T20:29:30.337 回答