【问题标题】:if statement conditions are embedded in a columnif 语句条件嵌入列中
【发布时间】:2020-12-02 12:43:24
【问题描述】:

我有一个 SAS 表,该表的条件 1 列中嵌入了 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;

【问题讨论】:

  • 先弄清楚您要生成什么代码,然后我们可以向您展示如何从您的输入数据中生成该代码。显示您希望为示例输入运行的代码。显示您希望从该代码中得到什么输出。
  • 为什么有一个案例(第3行)缺少condition1
  • @Richard 可能是缺少条件 1,因此您只需将“X”作为标志。这就是我对最后一个 else 语句的意思。

标签: if-statement sas sas-macro


【解决方案1】:

Data 不能修改正在运行的 DATA Step 的语句。

数据步骤中没有“动态表达式解析器”。

虽然有一些选择

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

编写程序


filename evals temp;

data _null_;
  file evals;
  set test;

  length statement $256;

  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 $8;
  %include evals;
  keep x1 x2 flag;
run;

filename evals;

RESOLVE函数

data want;
  set test;

  length flag $8 cond expr $256;

  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;

【讨论】:

  • 这正是我正在寻找的。您甚至提供了多种选择。非常感谢@Richard
【解决方案2】:

如果您要使用数据编写代码,请利用 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 $8 ;
  flag='X';
  %include code / source2;
run;

结果:

84    data want;
85      set have;
86      length flag $8 ;
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.

【讨论】:

    猜你喜欢
    • 2017-02-15
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    相关资源
    最近更新 更多