gpt4 book ai didi

SAS - 如何从 SAS 宏返回值?

转载 作者:行者123 更新时间:2023-12-04 00:12:51 25 4
gpt4 key购买 nike

我想从我创建的 SAS 宏返回一个值,但我不确定如何。该宏计算数据集中的观察数。我想要返回的观察次数。

%macro nobs(library_name, table_name);
proc sql noprint;
select nlobs into :nobs
from dictionary.tables
where libname = UPCASE(&library_name)
and memname = UPCASE(&table_name);
quit;

*return nobs macro variable;
&nobs
%mend;

%let num_of_observations = %nobs('work', 'patients');

另外,我想要 &nobs在宏中使用的宏变量是该宏的局部变量,而不是全局变量。我怎样才能做到这一点?

最佳答案

我将回答 Bambi 在评论中提出的核心问题:

My main concern here is how to return a value from a macro.



我将在这里以一种重要的方式与德克争论。他说:

A SAS macro inserts code. It can never return a value, though in some cases you can mimic functions



我不同意。 SAS 宏返回插入到处理流中的文本。退货绝对是一个合适的术语。当文本恰好是单个数字时,可以说它返回一个值。

但是,如果宏除了该值之外只有宏语句,则它只能返回单个值。意思是,每一行都必须以 % 开头。 .任何不以 % 开头的内容将要返回(并且某些以 % 开头的内容也可能会返回)。

所以重要的问题是,我如何返回 只有来自宏的值。

在某些情况下,像这种情况,完全可以只用宏代码。事实上,在许多情况下,这在技术上是可行的——尽管在许多情况下,这比您应该做的工作要多。

jack 汉密尔顿的链接 paper包括一个适合此处的示例。他驳回了这个例子,但这主要是因为他的论文是关于在 NOBS 错误的情况下计算观察结果 - 无论是使用 WHERE 子句,还是在没有更新 NOBS 元数据的情况下修改数据集的某些其他情况。

在您的情况下,您似乎非常乐意信任 NOBS - 所以这个例子就行了。

返回值的宏必须恰好有一个语句,该语句不是宏语法语句,或者是将值返回到处理流中的宏语法语句。 %sysfunc是这样做的语句的示例。诸如 %let 之类的东西, %put , %if等是不返回任何内容(本身)的语法语句;所以你可以拥有尽可能多的那些。

您还必须有一个将值放入处理流的语句:否则您将根本无法从宏中获得任何信息。

这是第 3 页末尾 Jack 宏的精简版,简化为删除了 nlobsf他展示的是错误的:
 %macro check;

%let dsid = %sysfunc(open(sashelp.class, IS));
%if &DSID = 0 %then
%put %sysfunc(sysmsg());

%let nlobs = %sysfunc(attrn(&dsid, NLOBS));

%put &nlobs;

%let rc = %sysfunc(close(&dsid));

%mend;

该宏不是函数风格的宏。它不会向处理流返回任何内容!它对于查看日志很有用,但对于为您提供可用于编程的值没有用处。然而,对于函数风格的宏来说,这是一个好的开始,因为你真正想要的是 &nlobs , 对?
 %macro check;

%let dsid = %sysfunc(open(sashelp.class, IS));
%if &DSID = 0 %then
%put %sysfunc(sysmsg());

%let nlobs = %sysfunc(attrn(&dsid, NLOBS));

&nlobs

%let rc = %sysfunc(close(&dsid));

%mend;

现在这是一个函数风格的宏:它有一个不是宏语法语句的语句, &nlobs.在一条简单的线上。

它实际上比你需要的更多;记得我是怎么说的 %sysfunc向处理流返回一个值?您可以删除 %let该声明的一部分,给你留下
 %sysfunc(attrn(&dsid, NLOBS))

然后该值将直接放置在处理流本身中 - 允许您直接使用它。当然,如果出现问题,调试并不容易,但我相信如果需要,您可以解决这个问题。还要注意语句末尾没有分号——这是因为宏函数不需要分号来执行,而且我们不想返回任何无关的分号。

咱们乖乖加几条 %local s 以获得这个好和安全,并使数据集的名称成为参数,因为大自然憎恶没有参数的宏:
 %macro check(dsetname=);

%local dsid nlobs rc;

%let dsid = %sysfunc(open(&dsetname., IS));
%if &DSID = 0 %then
%put %sysfunc(sysmsg());

%let nlobs = %sysfunc(attrn(&dsid, NLOBS));

&nlobs

%let rc = %sysfunc(close(&dsid));

%mend;

%let classobs= %check(dsetname=sashelp.class);

%put &=classobs;

你有它:一个使用 nlobs 的函数风格的宏函数来找出任何特定数据集中有多少行。

关于SAS - 如何从 SAS 宏返回值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33817518/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com