如果语句条件嵌入在列中
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.
我有一个 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.