SAS 宏
核心区分:
%eval 放值(做数值运算),%sysfunc 放函数。二者不可互换。%sysfunc 正确用法
SAS
/* ❌ 错误:sysfunc里用了%index + 引号 */
%if %sysfunc(%index(&TLBL, '>=3级')) %then %do;
/* ✅ 正确:sysfunc里调用index,不加%不加引号 */
%if %sysfunc(index(&TLBL, >=3级)) %then %do;
宏变量陷阱速查
| 陷阱 | 后果 | 解决 |
|---|---|---|
| 单引号内放宏变量 | 不解析(单引号阻止宏替换) | 用双引号 |
| 用VAR做变量名 | 和宏变量冲突,诡异bug | 避免 |
| pgmname重复 | 各种随机error | 每个程序唯一 |
| 宏参含英文括号 | 参数解析异常 | 转义处理 |
| 数据集名>32字节 | 直接报错 | 控制在32字节内 |
call symput — 字典映射
SAS
/* 用call symput做值→标签的字典映射 */
proc sql noprint;
select count(distinct USUBJID) into :NOBSL from ADSL;
quit;
%put &NOBSL.;
%if &NOBSL. ^= 0 %then %do;
/* 有数据时的逻辑 */
%end;
%else %do;
/* 空数据时的fallback */
%end;
字符函数速查
| 函数 | 行为 | 场景 |
|---|---|---|
catx(':', a, b) | 用分隔符连接,自动去空格,加分隔符 | 拼接剂量单位、AE描述 |
cats(a, b) | 直接拼接,去两端空格,不加分隔符 | 紧凑拼接 |
cat(a, b) | 直接拼接,保留空格 | 需要保留空格时 |
compress(str, ' ') | 移除指定字符(默认空格) | 清理数据 |
tranwrd(str, 'old', 'new') | 替换子字符串 | 波浪号→unicode转义 |
scan(str, n, '-') | 按分隔符取第n个词 | 解析日期、ISO格式 |
kscan(str, n) | 中日韩字符版scan | 处理中文内容 |
coalescec(v1, v2, v3) | 返回第一个非空字符值 | 自动遍历非空 |
anydigit(str) | 返回第一个数字的位置(0=无数字) | 判断字符串是否含数字 |
正则表达式:提取括号内容
SAS
/* 从"身高(cm)"中提取"cm" */
if prxmatch('/\(.*\)/', PARAM) then do;
UNIT = prxchange('s/.*\((.*)\).*/$1/', -1, PARAM);
COL9 = strip(UNIT);
end;
/* 只对首字母大写(Sentence case) */
NEWVAR = cats(upcase(substr(strip(OLDVAR),1,1)),
lowcase(substr(strip(OLDVAR),2)));
保留三位有效数字
SAS
/* 通用版:基于log10动态计算round精度 */
data WANT;
set HAVE;
X_NUM = input(strip(X), best.);
if not missing(X_NUM) then do;
if X_NUM ^= 0 then
SIG3 = round(X_NUM, 10**(floor(log10(abs(X_NUM))) - 2));
else SIG3 = 0;
SIG3_CHAR = strip(put(SIG3, best.));
end;
run;