【发布时间】:2021-12-19 10:48:18
【问题描述】:
我希望在我的数据步骤中调用一个宏来确定我正在创建的新变量应该接收什么值。
我知道我不一定需要一个宏,我可以在数据步骤中包含代码。问题是我正在处理的问题非常复杂,并且有超过 5 个类似的 if-else 语句。然而,本质上唯一改变的是宏函数内部的内容。
因此需要宏。下面是代码和错误日志。 我相信问题不应该出在宏中,我已经对其进行了测试并且它成功地工作了。但是,由于某种原因,在引用变量和局部宏变量的数据步骤中调用它时不会。
我读到这是因为应该使用 %sysfunc 或 %execute call 之类的东西,但我不能将 sysfunc 与自定义宏一起使用,并且 execute call 也不起作用,或者至少我无法做到工作,因为我想将该宏的值分配给临时局部变量。
I.E.类似 %let temp = execute call(CalculatePayment(args)) 但这不起作用。
%let preliminary_1 = 288;
%let preliminary_2 = 115;
%let preliminary_3 = 58;
data __temp__;
set sashelp.cars;
run;
%macro CalculatePayment(initialPayment, paymentLimit);
%let temp = %sysfunc(min(&initialPayment,&paymentLimit));
%let candidate = %eval(&temp. - 27);
%if( &candidate >= 0) %then %let rValue = &temp;
%else %let rValue = 0;
&rValue
%mend;
data _temp_;
set __temp__;
if weight <= 100 then do;
preliminary = 0;
end;
else if (find(Model,"2")) then do;
%let fstCase = %CalculatePayment(weight,&preliminary_1);
%let seCase = %CalculatePayment(weight,&preliminary_1);
preliminary = %eval(&fstCase. + &seCase.);
end;
/*
else if (find(Model,"g") & find(Model,"1")) then do;
%let fstCase = %CalculatePayment(weight,&preliminary_1);
%let seCase = %CalculatePayment(0.2 * weight,&preliminary_2);
%let thirCase = %CalculatePayment(0.8 * weight,&preliminary_3);
preliminary = %eval(&fstCase. + &seCase. + &thirCase.);
end;
*MORE SIMILAR IF-STATEMENTS BELOW with the values to the macro changing;
*/
else do; preliminary = 0;
end;
run;
注意这里是错误日志的小sn-p。我没有把它完全放在这里,因为你可以通过运行代码来重现相同的日志。
错误日志:
54 %let fstCase = %CalculatePayment(weight,&preliminary_1);
ERROR: Argument 1 to function MIN referenced by the %SYSFUNC or %QSYSFUNC macro function is not a number.
ERROR: Invalid arguments detected in %SYSCALL, %SYSFUNC, or %QSYSFUNC argument list. Execution of %SYSCALL statement or %SYSFUNC
or %QSYSFUNC function reference is terminated.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was:
. - 27
ERROR: The macro CALCULATEPAYMENT will stop executing.
55 %let seCase = %CalculatePayment(weight,&preliminary_1);
ERROR: Argument 1 to function MIN referenced by the %SYSFUNC or %QSYSFUNC macro function is not a number.
ERROR: Invalid arguments detected in %SYSCALL, %SYSFUNC, or %QSYSFUNC argument list. Execution of %SYSCALL statement or %SYSFUNC
or %QSYSFUNC function reference is terminated.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was:
. - 27
ERROR: The macro CALCULATEPAYMENT will stop executing.
56 preliminary = %eval(&fstCase. + &seCase.);
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was:
+
56 preliminary = %eval(&fstCase. + &seCase.);
_
22
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant,
a missing value, INPUT, PUT.
【问题讨论】:
-
PROC FCMP 允许您创建用户定义的函数,这是不是宏的选项?