是否可以从包含要测试的变量列表的数据集中创建 SAS 代码?

Is it possible to create a SAS code from a dataset with a list of variables to test?

我有这样的数据集 LIST

ID  VARIABLE_TO_TEST
AAA PIPPO
AAA PLUTO
AAA PAPERINO
BBB PLUTO
BBB PAPERINO
CCC PIPPO

和另一个数据集 HAVE 是这样的:

ID  PIPPO PLUTO PAPERINO
AAA xxx   yyy   NULL
BBB NULL  xxx   yyyy
CCC zzz   NULL  NULL

数据集 LIST 包含要测试的变量列表。
如果给定 IDLIST 中的变量缺失,则应创建值为 1 的新对应标志。
如果没有丢失,则标志的值应为 0。
如果给定 IDLIST 中不存在变量,则应缺少相应的标志。
变数很多
ID很多。

可以在代码中转换 LIST

If ID = "AAA" then do;
 IF missing(PIPPO) then FLAG_PIPPO = 1; else FLAG_PIPPO = 0;
 IF missing(PLUTO) then FLAG_PLUTO = 1; else FLAG_PLUTO = 0;
 IF missing(PAPERINO) then FLAG_PAPERINO = 1; else FLAG_PAPERINO = 0;
end; 
If ID = "BBB" then do;
 IF missing(PLUTO) then FLAG_PLUTO = 1; else FLAG_PLUTO = 0;
 IF missing(PAPERINO) then FLAG_PAPERINO = 1; else FLAG_PAPERINO = 0;
end; 
If ID = "CCC" then do;
 IF missing(PIPPO) then FLAG_PIPPO = 1; else FLAG_PIPPO = 0;
end;

in other获取数据集WANT,像这样:

ID  PIPPO PLUTO PAPERINO FLAG_PIPPO FLAG_PLUTO FLAG_PAPERINO
AAA xxx   yyy   NULL     0          0          1
BBB xyz   NULL  yyyy     NULL       1          0
CCC zzz   NULL  xxxx     0          NULL       NULL

?

您可以使用散列 table 并转置结果...

data list ;
  input ID .
        VARIABLE_TO_TEST .
        ;
datalines ;
AAA PIPPO
AAA PLUTO
AAA PAPERINO
BBB PLUTO
BBB PAPERINO
CCC PIPPO
;
run ;

data have ;
  infile cards dlm='|' missover ;
  input ID . (PIPPO PLUTO PAPERINO) (:.) ;
datalines ;
AAA|xxx|yyy| 
BBB| |xxx|yyyy
CCC|zzz| | 
;
run ;

data want1 ;
  set have ;
  /* load the lookup list into hash table, multidata:y as >1 record per ID [hash key] */
  if 0 then set list ;
  if _n_ = 1 then do ;
    declare hash lst(dataset:'list',multidata:'y') ;
    lst.definekey('ID') ;
    lst.definedata('VARIABLE_TO_TEST') ;
    lst.definedone() ;
  end ;

  call missing(VARIABLE_TO_TEST) ;
  /* loop over all the variables to test for this ID */
  do while(lst.do_over(key:ID) = 0) ; 
    /* vvaluex() to dynamically resolve VARIABLE_TO_TEST value > variable > value */
    var_value = vvaluex(VARIABLE_TO_TEST) ;
    flag = missing(var_value) ; 
    var_flag = cats('FLAG_',VARIABLE_TO_TEST) ;
    output ;
  end ;
run ;

proc transpose data=want1 out=want2 (drop=_NAME_) ;
  by ID ;
  id var_flag ;
  var flag ;
run ;

data want ;
  merge have want2 ;
  by ID ;
  drop var_value flag var_flag VARIABLE_TO_TEST ;  
run ;

使用该数据集生成该代码非常容易。只需使用一个数据步骤来编写代码。您可以使用 MISSING() 函数已经 returns 1 或 0.

的事实来简化代码

让我们制作一个变量列表来测试每个 ID。

data list ;
  input ID $ VAR :. ;
cards;
AAA PIPPO
AAA PLUTO
AAA PAPERINO
BBB PLUTO
BBB PAPERINO
CCC PIPPO
;

现在我们可以使用该数据生成代码:

filename code temp;
data _null_;
  set list ;
  by id;
  file code ;
  if first.id then put 'IF ID=' id :$quote. 'THEN DO;' ;
  put '  FLAG_' var '=MISSING(' var ');' ;
  if last.id then put 'END;' ;
run;

结果:

IF ID="AAA" THEN DO;
  FLAG_PIPPO =MISSING(PIPPO );
  FLAG_PLUTO =MISSING(PLUTO );
  FLAG_PAPERINO =MISSING(PAPERINO );
END;
IF ID="BBB" THEN DO;
  FLAG_PLUTO =MISSING(PLUTO );
  FLAG_PAPERINO =MISSING(PAPERINO );
END;
IF ID="CCC" THEN DO;
  FLAG_PIPPO =MISSING(PIPPO );
END;

现在只需在数据步骤中使用该代码即可。

data want;
  set have;
%include code / source2;
run;