使用PROC TRANSPOSE时如何避免列名含空格/制表符?附替代方案
解决SAS PROC TRANSPOSE列名带空格的问题
这个问题我之前也碰到过!本质是你的字符变量ColA在存储时带了 trailing空格(因为你用input ColA $时没指定长度,SAS默认给了8位长度,所以Cat1后面会补5个空格),转置时ID语句直接把这些空格带到列名里了。给你两种实用的解决思路:
一、从源头避免生成带空格的列名
有两种简单的方式可以提前搞定:
- 指定变量长度:在
INPUT语句里给ColA指定刚好匹配实际值的长度,比如最长的Cat3是4个字符,就写ColA $4.,这样存储的ColA就没有多余空格,转置后的列名自然干净:
Data tst; input ColA $4. ColB; datalines; Cat1 1 Cat2 2 Cat3 3 ; run; proc transpose data = tst out= tst_out (drop = _name_); id ColA; run;
- 在TRANSPOSE里直接处理ID变量:如果没法修改输入步骤,SAS 9.2及以上版本支持在
ID语句中使用函数,直接用STRIP()去掉ColA的 trailing空格:
proc transpose data = tst out= tst_out (drop = _name_); id strip(ColA); run;
二、批量移除已生成列名中的空格
如果已经得到了带空格的列,不用逐列手动重命名,利用SAS的字典表可以自动完成批量重命名:
1. 自动生成重命名语句
用PROC SQL查询目标数据集的列名,生成包含所有重命名规则的宏变量:
proc sql noprint; select cats(name, '=', ltrim(name)) /* LTRIM只去掉前置空格,要全清用COMPRESS(name) */ into :rename_list separated by ' ' from dictionary.columns where libname = 'WORK' and memname = 'TST_OUT'; /* 注意库名和数据集名要大写 */ quit;
这里LTRIM(name)专门去掉列名的前置空格,要是想去掉所有空格就换成COMPRESS(name)。
2. 应用重命名规则
用PROC DATASETS来批量修改列名(比DATA步高效,不用复制整个数据集):
proc datasets library=work nolist; modify tst_out; rename &rename_list.; quit;
不管你的数据集有多少列,这两步都能一次性完成所有列名的空格清理。
内容的提问来源于stack exchange,提问作者k.dkhk
相关产品推荐
相关产品推荐

