如何为 sas 数据步骤中的每个观察执行一段宏?

发布于 2024-11-14 18:30:50 字数 435 浏览 2 评论 0原文

假设我允许用户使用通用用户界面编写自己的变量计算宏:

%macro calculate(var_name, var_value);
%* Some user-defined calculation;
%mend calculate;

然后在数据步骤中,我可以使用用户定义的宏计算一个新变量:

data dataset;
    set dataset;
    new_var = %calculate('variable1', variable1); * This doesn't work. It just shows my indication.
run;

其中variable1是数据集中的变量。这里,我想传入变量名和变量的实际值。计算完成后,将值放入new_var中。

我怎样才能实现这个目标?

Suppose I allow user to write his own variable calculation macro using a common user interface:

%macro calculate(var_name, var_value);
%* Some user-defined calculation;
%mend calculate;

Then in a data step, I can calculate a new variable using the user-defined macro:

data dataset;
    set dataset;
    new_var = %calculate('variable1', variable1); * This doesn't work. It just shows my indication.
run;

Where variable1 is a variable in dataset. Here, I want to pass in the variable name and the actual value of the variable. After the calculation, put the value in new_var.

How can I achieve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

千鲤 2024-11-21 18:30:50

是否需要通过宏来实现这一点?这听起来像是 < 的情况code>PROC FCMP 将是最有用的,因为它允许您定义自己的函数或子例程(fcmp =“函数编译器”),这些函数或子例程可以在数据步骤中使用就像一个内置函数。

这是一个简单的例子:

proc fcmp outlib=sasuser.funcs.math;
  function calc(var);
     newvar=log(var); /*user defined stuff here - can be simple or complex*/
     return(newvar);
  endsub;
run;

option cmplib=sasuser.funcs; /*tell SAS where to look for functions*/
data _null_;
  set sashelp.class;
  newvar=calc(height); /*call your new function */
  put newvar=;
run;

Is it required that you achieve this with macros? This sounds like a situation where PROC FCMP would be most useful as it allows you to define your own functions or subroutines (fcmp="function compiler") that can used in a data step just like a built-in function.

Here is a simple example:

proc fcmp outlib=sasuser.funcs.math;
  function calc(var);
     newvar=log(var); /*user defined stuff here - can be simple or complex*/
     return(newvar);
  endsub;
run;

option cmplib=sasuser.funcs; /*tell SAS where to look for functions*/
data _null_;
  set sashelp.class;
  newvar=calc(height); /*call your new function */
  put newvar=;
run;
梦毁影碎の 2024-11-21 18:30:50

您可以完成这项工作,但您可能错误地编写了宏。您必须记住,SAS 宏本质上是文本预处理器:它们输入您编写的代码并输出代码以馈送到 SAS [1]。

因此,这是一个简单的“加法”宏:

%macro calculate (var_name, var_value);
  &var_name + &var_value;
%mend;

data one;
  input a@@;
  b = %calculate(a, 3);
  c = %calculate(a, a);
cards;
1 3 -2 4
;
run;

proc print data=one;
run;

宏工具将用宏生成的代码替换 %calculate 位,SAS 实际上会看到以下内容:

%macro calculate (var_name, var_value);
  &var_name + &var_value;
%mend;

data one;
  input a@@;
  b = a + 3;
  c = a + a;
cards;
1 3 -2 4
;
run;

proc print data=one;
run;

您可以在带有 options mprint 语句的日志文件

不幸的是,这不会涵盖所有潜在的计算。您可能需要查找PROC FCMP以获取生成可在 DATA 步骤中使用的自定义函数/子例程的方法。

[1] 我知道事情比这更复杂,但你可以这样思考。

You can make this work, but you are probably writing the macro incorrectly. You have to remember that SAS macros are essentially text preprocessors: they input the code you have written and output code to feed to SAS [1].

So here is a simple "addition" macro:

%macro calculate (var_name, var_value);
  &var_name + &var_value;
%mend;

data one;
  input a@@;
  b = %calculate(a, 3);
  c = %calculate(a, a);
cards;
1 3 -2 4
;
run;

proc print data=one;
run;

The macro facility will replace the %calculate bits with the code generated by the macro, and SAS will actually see the following:

%macro calculate (var_name, var_value);
  &var_name + &var_value;
%mend;

data one;
  input a@@;
  b = a + 3;
  c = a + a;
cards;
1 3 -2 4
;
run;

proc print data=one;
run;

You can see it for yourself on the log file with the options mprint statement

Unfortunately, this will not cover all potential calculations. You might want to look up PROC FCMP for a way to generate custom functions/subroutines usable in the DATA step.

[1] I know it is more complicated than that, but you can get far thinking like this.

旧人哭 2024-11-21 18:30:50

我知道这是一篇较旧的文章,但我认为值得一提。

这是一个允许像函数一样使用宏例程的解决方案。这是在 SAS resolve() 函数的帮助下完成的。 “%then”后面的内容(在本例中是文本,但也可以是数字)对应于我们在“实际函数”的 return() 部分中放入的内容。

%macro compare(v1, v2);
  %if &v1 > &v2 %then v1 is greater than v2;
  %else v2 is greater than v1;
%mend;

data check (drop = macroCall);
  input v1 v2;
  macroCall = cats('%compare(', v1, ',', v2, ')');
  result = resolve(macrocall);
  datalines;
1 2
2 1
;

结果:

v1  v2  result
1   2   v2 is greater than v1
2   1   v1 is greater than v2

I know this is an older post, but I think it's worth mentionning this.

Here's a solution that allows using a macro routine as we would a function. This is accomplished with the help of the SAS resolve() function. Whatever follows "%then" (in this case it's text but it could be a number) corresponds to what we would put in the return() part of a "real function".

%macro compare(v1, v2);
  %if &v1 > &v2 %then v1 is greater than v2;
  %else v2 is greater than v1;
%mend;

data check (drop = macroCall);
  input v1 v2;
  macroCall = cats('%compare(', v1, ',', v2, ')');
  result = resolve(macrocall);
  datalines;
1 2
2 1
;

Results:

v1  v2  result
1   2   v2 is greater than v1
2   1   v1 is greater than v2
耳钉梦 2024-11-21 18:30:50

这是一个常见的混淆点。问题是 SAS 在处理任何常规代码之前处理程序中的所有宏代码。因此,当它调用 %calculate('variable1', variable1); 时,它还无法访问数据集中的数据。

也就是说,如果我有一个示例来说明您所说的 %*Some user-defined Calculation; 的含义,那么会更容易帮助您找到解决方案。

This is a common point of confusion. The problem is that SAS processes all macro code in your program BEFORE any of the regular code. So when it calls %calculate('variable1', variable1);, it doesn't yet have access to the data in the data set.

That said, it would be easier to help you come up with a solution if I had an example of what you might mean by %*Some user-defined calculation;.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文