在宏 SAS 中使用 max 函数
Using max function in macro SAS
我试图在宏中找到四个变量 Value_A Value_B Value_C Value_D
的最大值。我以为我可以做到 %sysfunc(max(value_&i.))
,但这是行不通的。我的完整代码是:
%let i = (A B C D);
%macro maxvalue;
data want;
set have;
%do j = 1 %to %sysfunc(countw(&list.));
%let i = %scan(&list.,&j.);
value_&i.= Sale_&i. - int_&i.
Max_Value = %sysfunc(max(value_&i.));
%end;
run;
%mend maxvalue;
%maxvalue;
我应该指定我只需要每个观察值的四个变量中的最大值。感谢您的帮助!
除了打字错误 - %let i=(A B C D);
应该是 %let list=(A B C D)
- 你 a) 过于复杂,b) 混淆了宏语法和数据步语法。虽然您可以使用宏来执行此操作,但没有必要。
鉴于所讨论的变量都以类似的方式作为前缀(尽管如果它们带有数字后缀会更好,例如 Value1、Value2),使用数组和适当的函数要容易得多:
data want ;
set have ;
array sale{*} Sale_A Sale_B Sale_C Sale_D ;
array int{*} Int_A Int_B Int_C Int_D ;
array value{*} Value_A Value_B Value_C Value_D ;
/* Iterate over array */
do i = 1 to dim(sale) ;
value{i} = sum(sale{i},-int{i}) ;
end ;
max_value = max(of value{*}) ;
run ;
为什么不直接将变量从 SALE_1 重命名为 SALE_4?然后你可以用一个简单的变量列表 SALE_1-SALE_4
.
来引用它们
如果您打算在类似命名的变量列表上使用非数字后缀,那么您真正需要的可能是一个简单的函数样式宏,以根据基本名称和后缀值列表生成变量名称列表.
%macro generate_names(base,list);
&base%sysfunc(tranwrd(%sysfunc(compbl(&list)),%str( ),%str( &base)))
%mend generate_names;
然后更容易生成用于 ARRAY 语句的变量列表
%let suffixes=A B C D;
array sale %generate_names(Sale_,&suffixes);
array int %generate_names(Int_,&suffixes);
array value %generate_names(Value_,&suffixes);
和其他语句。
max_value = max(of %generate_names(Value_,&suffixes)) ;
如前所述,您过于复杂了,但是您可以通过在 max_value
分配中包含另一个 for 循环来使用宏逻辑来实现您想要做的事情。此方法涉及您取四个变量中的最大值和一个缺失值,这应该会产生所需的结果:
%let list = A B C D;
%macro maxvalue;
data want;
set have;
%do j = 1 %to %sysfunc(countw(&list.));
%let i = %scan(&list.,&j.);
value_&i.= Sale_&i. - int_&i.
%end;
max_value = max(
%do x = 1 %to %sysfunc(countw(&list.));
%let y = %scan(&list.,&x.);
value_&y.,
%end; .
);
run;
%mend maxvalue;
%maxvalue;
我试图在宏中找到四个变量 Value_A Value_B Value_C Value_D
的最大值。我以为我可以做到 %sysfunc(max(value_&i.))
,但这是行不通的。我的完整代码是:
%let i = (A B C D);
%macro maxvalue;
data want;
set have;
%do j = 1 %to %sysfunc(countw(&list.));
%let i = %scan(&list.,&j.);
value_&i.= Sale_&i. - int_&i.
Max_Value = %sysfunc(max(value_&i.));
%end;
run;
%mend maxvalue;
%maxvalue;
我应该指定我只需要每个观察值的四个变量中的最大值。感谢您的帮助!
除了打字错误 - %let i=(A B C D);
应该是 %let list=(A B C D)
- 你 a) 过于复杂,b) 混淆了宏语法和数据步语法。虽然您可以使用宏来执行此操作,但没有必要。
鉴于所讨论的变量都以类似的方式作为前缀(尽管如果它们带有数字后缀会更好,例如 Value1、Value2),使用数组和适当的函数要容易得多:
data want ; set have ; array sale{*} Sale_A Sale_B Sale_C Sale_D ; array int{*} Int_A Int_B Int_C Int_D ; array value{*} Value_A Value_B Value_C Value_D ; /* Iterate over array */ do i = 1 to dim(sale) ; value{i} = sum(sale{i},-int{i}) ; end ; max_value = max(of value{*}) ; run ;
为什么不直接将变量从 SALE_1 重命名为 SALE_4?然后你可以用一个简单的变量列表 SALE_1-SALE_4
.
如果您打算在类似命名的变量列表上使用非数字后缀,那么您真正需要的可能是一个简单的函数样式宏,以根据基本名称和后缀值列表生成变量名称列表.
%macro generate_names(base,list);
&base%sysfunc(tranwrd(%sysfunc(compbl(&list)),%str( ),%str( &base)))
%mend generate_names;
然后更容易生成用于 ARRAY 语句的变量列表
%let suffixes=A B C D;
array sale %generate_names(Sale_,&suffixes);
array int %generate_names(Int_,&suffixes);
array value %generate_names(Value_,&suffixes);
和其他语句。
max_value = max(of %generate_names(Value_,&suffixes)) ;
如前所述,您过于复杂了,但是您可以通过在 max_value
分配中包含另一个 for 循环来使用宏逻辑来实现您想要做的事情。此方法涉及您取四个变量中的最大值和一个缺失值,这应该会产生所需的结果:
%let list = A B C D;
%macro maxvalue;
data want;
set have;
%do j = 1 %to %sysfunc(countw(&list.));
%let i = %scan(&list.,&j.);
value_&i.= Sale_&i. - int_&i.
%end;
max_value = max(
%do x = 1 %to %sysfunc(countw(&list.));
%let y = %scan(&list.,&x.);
value_&y.,
%end; .
);
run;
%mend maxvalue;
%maxvalue;