宏定义处理特殊字符 ->_SAS宏语言

SAS宏语言主要用于实现代码的重复利用、完成复杂的逻辑判断和条件控制,使得代码更为简短清晰,程序更加灵活及易于维护。

宏工具的功能非常强大,使用宏工具来完成以下任务。

  1. 使用宏变量实现文本替代;
  2. 使用宏产生程序语句;
  3. 使用宏循环及条件判断语句完成程序交互。

SAS宏语言实际是上一种文本语言,在宏语言中所有变量的值都只能是字符。宏语言的特征之一就是带有符号”&“和”%“,前者一般与宏变量一起使用,后者一般常与宏一起使用。

举例:
data orsales2001;
set sashelp.orsales;
if year=2002;
run;
proc print data =orsales2001;
title "orsales2001";
footnote1 "created 23:21 19/7/2019";
footnote2 "on the WIN system Using SAS 9.4";
run;

0f9e2ceaaa262689af17eca52e1c14d2.png

1c75a357df3a69303a16b1761ab540de.png

以上代码虽然实现目标,但是不易维护,主要体现在以下两个方面:

年份需要用户手动输入(if year=2002);

上述代码中2001出现3次,假设想要看到其他年份的数据,只能在程序中将所有出现年份2001都做替换。

使用宏语言改写上述代码:

%let year=2001;
data orsales&year;
set sashelp.orsales;
if year=&year;
run;
proc print data =orsales&year;
title "orsaless&year";
footnote1 "created &systime &sysdate &sysdate9";
footnote2 "on the &sysscp system Using &sysver";
run;

369e1e01cd0249bc62c0aab337291712.png
  1. 定义宏变量year,赋值2001;
  2. 脚注footnote利用&systime、&sysdate、&sysdate9、&sysver等系统宏变量,自动生成时间,避免手工输入。
  3. 例中,在引号内引用宏变量的值时必须用双引号。因为宏处理器只能在双引号内进行替代。

以下所用数据集:ResDat.class

a1eaa0250ff5ffceda93b3ddc78e8e29.png

ResDat.stk000002

bea4b23a7d472761e62cba56dbc46677.png
  • 引用宏变量
  • 宏变量的定义方法主要有以下3种方法:
  1. 使用%let语句;
  2. 在DATA步种定义宏变量;
  3. 在sql语言中定义宏变量。

直接调用方法:&宏变量。注意:单引号内的宏变量不会被解析,双引号才会被解析。
间接调用方法:通过多个“&”符号来实现。

宏处理器对多个“&”的处理规则是:从左到右进行扫描,若宏变量前仅含有一个“&”,则解析该宏变量,否则将相邻两个&替换成一个&,重复上述扫描过程。

例1 引用宏变量A
%let a=ResDat.class;
data a;
set &a ;
run;
/*上段程序等价于:
data a;
set ResDat.class;
run;
在带有引号的文本中引用宏变量时,需要将这个文本字符串用双引号括起来。
*/

037d627857e3efbea1e2c9642fd042f1.png
  • 宏处理器只能在双引号内进行替代。
例16.2:宏处理器只能在双引号内进行替代
%let a=january;
data;
put  "This is the time series plot for &A";
run;

3650a164eb4b90008a805b47b24f41f8.png
  • 多次引用宏变量
/*例16.3 多次引用宏变量。*/
%let a=ResDat.class;
data male;
set &a ;
if sex='M';
proc print;
title "subset of &a";
data female;
set &a ;
if sex&#
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码定义了一个 ABS(a) 和一个结构体 slid_reg_t,以及一个用于更新线性移位寄存器的函数 slid_update。下面对代码进行详细解析: 1. 定义 #define ABS(a) (0 - (a)) > 0 ? (-(a)) : (a) 该定义了一个对传入的参数取绝对值的操作,如果传入的参数 a 小于 0,则取其相反数作为返回值。 2. 静态常量 #define DYNAMIC_PRECISION 30 该定义了一个静态常量 DYNAMIC_PRECISION,其初始值为 30,用于过滤高频噪声。 3. 结构体定义 typedef struct slid_reg{ axis_info_t new_sample; axis_info_t old_sample; }slid_reg_t; 该结构体定义了一个线性移位寄存器 slid_reg_t,其中包含两个 axis_info_t 类型的变量 new_sample 和 old_sample,用于存储当前样本和旧样本的信息。 4. 函数定义 static char slid_update(slid_reg_t *slid, axis_info_t *cur_sample) { char res = 0; if (ABS((cur_sample->x - slid->new_sample.x)) > DYNAMIC_PRECISION) { slid->old_sample.x = slid->new_sample.x; slid->new_sample.x = cur_sample->x; res = 1; } else { slid->old_sample.x = slid->new_sample.x; } if (ABS((cur_sample->y - slid->new_sample.y)) > DYNAMIC_PRECISION) { slid->old_sample.y = slid->new_sample.y; slid->new_sample.y = cur_sample->y; res = 1; } else { slid->old_sample.y = slid->new_sample.y; } if (ABS((cur_sample->z - slid->new_sample.z)) > DYNAMIC_PRECISION) { slid->old_sample.z = slid->new_sample.z; slid->new_sample.z = cur_sample->z; res = 1; } else { slid->old_sample.z = slid->new_sample.z; } return res; } 该函数用于更新线性移位寄存器 slid 中的样本信息。首先定义了一个 char 类型的变量 res,并初始化为 0,用于记录是否更新了样本信息。然后分别对 x、y、z 三个轴上的样本信息进行判断,如果当前样本与新样本之间的差值大于 DYNAMIC_PRECISION,则将旧样本更新为新样本,将新样本更新为当前样本,并将 res 设为 1;否则只更新旧样本。最后返回 res。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值