如果语句条件嵌入在列中

if statement conditions are embedded in a column

我有一个 SAS table,它在 table 的 condition1 列中嵌入了 if 条件。更明确地说,我创建了一个测试数据集:

data test;
infile datalines delimiter=','; 
input x1 x2 flag $ condition1 $ value_cond1_true $ value_cond1_false $ ;
datalines;                      
1,5, ,x1>x2,A,B
6,5, ,x2>x1,D,A
3,2, , ,C,D
;
run;

我想知道是否可以创建一个可以直接在 SAS 代码中输出 if 语句的代码,而不是为每个观察创建一个宏变量 (&cond1_1, &cond1_2, ... &cond1_n)

这是我想要做的(我知道在那种情况下不可能使用 call symput):

data final;
set test;
/* For each observation */
do i=1 to _n_;
/* Creating macro-variables for the if condition */
call symput("cond1",CONDITION1);
call symput("value_cond1_true",VALUE_COND1_TRUE);
call symput("value_cond1_false",VALUE_COND1_FALSE);
/* If the cond1 macro-variable is not empty then do */
if %sysevalf(%superq(cond1)=, boolean) = 0 then do;
    if &cond1. then flag = &value_cond1_true.;
        else flag = &value_cond1_false.;
    end;
/* If the cond1 macro-variable is empty then */
else flag = "X";
end;
run;

Data 无法修改 运行 DATA Step 的语句。

数据步骤中没有 'dynamic expression resolver'。

虽然有一些选择

  • 用数据写源码
    • 必须为每一行执行不同的条件 (n)
  • 使用resolve()动态计算宏系统中的表达式。
    • 必须将变量的值替换为每一行的条件 (n)

编写程序


filename evals temp;

data _null_;
  file evals;
  set test;

  length statement 6;

  put 'if _n_ = ' _n_ ' then do;';

  if missing(condition1) then 
    statement = 'flag="X";'; /* 'call missing(flag);'; */
  else
    statement = 'flag = ifc(' 
    || trim(condition1) || ',' 
    || quote(trim(value_cond1_true )) || ','
    || quote(trim(value_cond1_false ))
    || ');';

  put statement;
  put 'end;';
run;

options source2;

data want;
  set test;
  length flag ;
  %include evals;
  keep x1 x2 flag;
run;

filename evals;

RESOLVE函数

data want;
  set test;

  length flag  cond expr 6;

  cond = condition1;
  cond = transtrn(cond,'x1',cats(x1));
  cond = transtrn(cond,'x2',cats(x2));

  expr = 'ifc(' || trim(cond) || ',' || 
           trim(value_cond1_true) || ',' || 
           trim(value_cond1_false) ||
         ')';

  if not missing (condition1) then 
    flag = resolve ('%sysfunc(' || trim(expr) || ')');
  else
    flag = "X";

  keep x1 x2 flag;
run;

如果您要使用数据编写代码,请利用 PUT 语句的强大功能。

data have;
  infile cards dsd truncover;
  input x1 x2 condition1 $ value_cond1_true $ value_cond1_false $ ;
cards;                      
1,5,x1>x2,A,B
6,5,x2>x1,D,A
3,2,,C,D
;

filename code temp;
data _null_;
  set have;
  file code;
  if condition1 ne ' ';
  put
    'if _n_=' _n_ 'then flag=ifc(' condition1
    ',' value_cond1_true :$quote.
    ',' value_cond1_false :$quote.
    ');'
  ;
run;

data want;
  set have;
  length flag  ;
  flag='X';
  %include code / source2;
run;

结果:

84    data want;
85      set have;
86      length flag  ;
87      flag='X';
88      %include code / source2;
NOTE: %INCLUDE (level 1) file CODE is file ...\#LN00059.
89   +if _n_=1 then flag=ifc(x1>x2 ,"A" ,"B" );
90   +if _n_=2 then flag=ifc(x2>x1 ,"D" ,"A" );
NOTE: %INCLUDE (level 1) ending.
91    run;

NOTE: There were 3 observations read from the data set WORK.HAVE.
NOTE: The data set WORK.WANT has 3 observations and 6 variables.