SAS 不评估 %PUT 的内容

SAS does not evaluate the content of %PUT

我在任何 DATA 步骤之外使用这个位。

%let sth = 20191111;
%let sthelse=SUBSTR(INPUT(&sth.,12.),1,4);
%put &sthelse.;

它不会产生我期望的“2019”,而是

SUBSTR(INPUT(20191111,12.),1,4)

这里出了什么问题?

SUBSTR 是数据步函数。 尝试将其用于宏函数:

%let sth = 20191111;
%let sthelse=%sysfunc(SUBSTR(%sysfunc(INPUTn(&sth.,12.)),1,4));
%put &sthelse.;

没有名为substr和input的宏函数,这个函数是"data step functions"。您应该使用 %sysfunc 语句。宏变量存储为文本,因此您不应该在其上使用 input 函数。

%let sth = 20191111;
%let sthelse=%sysfunc(SUBSTR(&sth.,1,4));
%put &=sthelse.;

STHELSE=2019

更新(感谢 @Tom):

有宏功能%substr,可以用%SUBSTR(&sth.,1,4)代替%sysfunc(SUBSTR(&sth.,1,4))

您不了解宏预处理器的工作原理。它只是一个文本替换工具。它查找两个触发字符 %& 以查看它需要在哪里工作。您可以在声明中看到两者都在起作用:

%let sthelse=SUBSTR(INPUT(&sth.,12.),1,4);

所以 % 将触发宏处理器,它会将 %let 识别为宏语句。然后 & 触发器将导致它将 &sth. 视为要替换的宏变量引用。所以它取代了那个,你最终得到这个声明。

%let sthelse=SUBSTR(INPUT(20191111,12.),1,4);

由于没有更多的宏触发器,SAS 很乐意将该文本存储到宏变量 sthelse

您似乎也对数字和字符串的工作原理感到困惑。如果你写这段代码:

data x;
  x=INPUT("20191111",12.);
run;

您会要求 SAS 将字符串 20191111 转换为数字 20,191,111。所以 X 将是一个数值变量。因此,它的效果与您 运行 这条语句的效果相同。

  x=20191111;

现在,如果您要求 SAS 通过执行以下操作尝试对该 NUMERIC 值使用 SUBSTR() 函数:

 y=substr(x,1,4);

SAS需要先将X转换成字符串。它会很乐意为你做那件事,但它会使用 BEST12。格式进行转换。所以你的数字 20,191,111 将变成字符串

    20191111  

因此它将有 4 个前导空格。然后,如果您使用前四个字符,您将得到四个空格。

您是否打算 运行 此代码?

%let sth = 20191111;
%let sthelse=%substr(&sth,1,4);

这将使用 MACRO 函数 %SUBSTR() 来获取您提供的字符串的前四个字符。因为你给了它字符串 20191111 (对于宏处理器来说一切都是字符串,不需要引号)结果将是字符串 2019.

使用宏函数%SUBSTR提取其参数的一部分。请记住,宏值只是字符值(不要与数据步骤字符变量和值混淆)并且没有明确的数值,即使宏值由所有数字组成也是如此。

%let sth = 20191111;
%let first4 = %substr(&sth,1,4);