我试图通过重命名列的名称(因为它们来自其来源)来遵守对32个字符的限制。问题是,通过使用数据步骤(如下),我收到“错误23-322:变量名称长于32个字符”的错误。
这就是我要使用的:
data mydata;
set mydata;
rename Thisisthelongcolumnnamefromthesourcetable = ShorterName;
run;
我听说使用ds2可以解决此问题,但是使用ds2进行的每次尝试都给了我类似的错误。由于我无法直接控制源数据,因此有没有针对此限制的解决方法?
此外,似乎SAS会自动截断列的名称,但是“标签名称”仍为实际长度。有没有办法通过引用列名来更改列名?
谢谢您的帮助!
答案 0 :(得分:1)
可以编写一个“内联宏”来为您生成重命名选项。 “内联宏”是一种不会发出导致执行步骤边界的SAS代码的宏-该宏将执行处理并发出SAS代码片段,该片段可用作其他SAS语句的一部分。
考虑带有签名的宏
%renameByLabel(data=, byvarname=allow, rename=(label-1=newname-1 label-2=newname-2)).
该宏将打开数据集,检查每个变量的名称和标签,并尝试将它们与label=name
参数中列出的rename=
对之一进行匹配。
使用此类宏可用于处理此代码所需的重命名操作
data have;
x12345=1; label x12345="This is x";
___y__scrap = "ABC"; label ___y__scrap="This is y";
ageold = 7; label ageold="Old age";
run;
data want;
set have (%renameByLabel(data=have,rename=("This is x"=x "This is y"=y ageold=age)));
run;
Macro无法访问当前执行程序标记化流,因此无法知道当前语句将要处理的数据集。宏要求使用data=
明确声明要处理的数据集(即使内联调用结果是set
语句的一部分)
示例宏
%macro renameByLabel(data=, byvarname=allow, rename=) / parmbuff;
%local allow ds nvar ri i rename varlabel varname L pair lhs rhs result pairename;
%let allow = %upcase(%superq(byvarname));
%let ds = %sysfunc(open(&data));
%if &ds %then %do;
%if %index(&ds,%str(%()) %then
%put WARNING: &SYSMACRONAME does not like KEEP= or DROP= options;
%let nvar = %sysfunc(attrn(&ds, nvar));
%let L = %length(%superq(rename));
%if "%substr(%superq(rename),&L,1)" = ")" %then %let rename=%substr(%superq(rename),1,%eval(&L-1));
%let L = %length(%superq(rename));
%if "%substr(%superq(rename),1,1)" = "(" %then %let rename=%substr(%superq(rename),2,%eval(&L-1));
%let L = %length(&rename);
%do ri = 1 %to &L;
%let pair = %scan(%superq(rename),&ri,%str( ),Q);
%if %length (&pair) %then %do;
%let lhs = %scan(%superq(pair),1,=,Q);
%let rhs = %scan(%superq(pair),2,=,Q);
%let pairename =;
%do i = 1 %to &nvar;
%let varname = %sysfunc(varname(&ds,&i));
%let varlabel = %sysfunc(varlabel(&ds,&i));
%if %superq(varlabel) = %superq(lhs) or
"%superq(varlabel)" = %superq(lhs)
%then %do;
%let pairename = &varname=&rhs;
%let i = &nvar;
%end;
%if &allow=ALLOW %then %do;
%if &varname = %superq(lhs) or
"&varname" = %superq(lhs)
%then %do;
%let pairename = &varname=&rhs;
%end;
%end;
%end;
%let result = &result &pairename;
%end;
%else
%let ri = &L;
%end;
%let ds = %sysfunc(close(&ds));
%* emit the generated rename option in-line;
rename=(&result)
%put NOTE: Generated rename option is %superq(result);
%end;
%else
%put ERROR: Could not open data=%superq(data);
%mend;
宏测试
* test 1;
%put %renameByLabel (data=sashelp.class, varname=Allow, rename=("Name"=NewName Age=NewAge));
* ===log===;
* NOTE: Generated rename option is rename=(Name=NewName Age=NewAge);
* test 2;
data have;
x12345=1; label x12345="This is x";
___y__scrap = "ABC"; label ___y__scrap="This is y";
ageold = 7; label ageold="Old age";
run;
data want;
set have (%renameByLabel(data=have,rename=("This is x"=x "This is y"=y ageold=age)));
run;
* ===log===;
* NOTE: Generated rename option is rename=(x12345=x ___y__scrap=y ageold=age)
在旁边
需要进行一些小的更改才能使宏仅发出重命名对,因此可以将其用作数据集rename=()
选项的一部分,或用作rename
语句的一部分。
您可以将宏重写为Proc DS2函数,例如说myRenameByLabel
,然后用%sysfunc(myRenameByLabel(…))
调用该函数。有时,在DS2语句中处理异常的引用和取消引用情况会更容易。
答案 1 :(得分:0)
您尝试过以下吗?
data mydata;
set mydata (rename=(Thisisthelongcolumnnamefromthesourcetable = ShorterName));
run;
SAS正在SET语句中进行变量命名。由于您直到SET语句完成后才尝试使用RENAME函数,因此为时已晚。如上所示,将RENAME用作SET语句选项,可以在SET读取变量之前重命名该变量。