重命名 SAS Table 中的所有变量
Renaming all variables from a SAS Table
我有两个相同的 SAS table,只是列名不同。
第一个 table D1
有 80 个具有以下模式的列名称 X1000_a010_b020
,第二个 table D2
有 80 个具有以下模式的列名称 X_1000_a0010_b0020
。请注意,它们的顺序不同。
我想确保 D1
中的所有列都与 D2
中的名称相同。换句话说,我想在X后面加下划线,在所有a和b后面加一个0。
但是我不知道如何进行。我想 RegEx 会是首选,但我不熟悉它。
作为结构示例,前段时间我使用以下代码将列名中的空格替换为下划线。我想做同样的事情,但对于 X 之后的下划线和 a 和 b 之后的 0。
%macro rename_vars(table);
%local rename_list sqlobs;
proc sql noprint;
select catx('=',nliteral(name),translate(trim(name),'_',' '))
into :rename_list separated by ' '
from sashelp.vcolumn
where libname=%upcase("%scan(work.&table,-2,.)")
and memname=%upcase("%scan(&table,-1,.)")
and indexc(trim(name),' ')
;
quit;
%if &sqlobs %then %do ;
proc datasets lib=%scan(WORK.&table,-2);
modify %scan(&table,-1);
rename &rename_list;
run;
quit;
%end;
%mend rename_vars;
您的示例代码似乎表明您已经制定了如何实施重命名的计划,因此让我们专注于生成 OLDNAME <-> NEWNAME 对。您可以使用 PROC CONTENTS 或使用 SQL 代码(或使用任何工具 SASHELP.VCOLUMN 查询 DICTIONARY.COLUMNS 来生成特定数据集中的名称列表。因此,假设您有一个名为 CONTENTS 的数据集,其中包含一个名为 NAME 的变量。所以目标是创建一个新变量,我们可以称之为 NEWNAME。
因此,让我们将您所说的三个转换直接转化为单独的操作。你可以折叠步骤,但是这个操作对效率没有迫切要求。
data fixed_names;
set contents;
newname = tranwrd(upcase(name),'_A','_A0');
newname = tranwrd(newname,'_B','_B0');
newname = cats(char(newname,1),'_',substr(newname,2));
keep name newname;
run;
现在您可以将该列表拉入宏变量。因此 space 分隔的 old=new
对列表对于重命名很有用。
proc sql noprint;
select catx('=',name,newname) into :renames
from fixed_names
where newname ne upcase(name)
;
quit;
或者,如果目标是逐字比较两个数据集,您可能希望生成一个旧名称列表和一个单独的新名称列表。
select name,newname
into :oldlist separated by ' '
, :newlist separated by ' '
from fixed_names
;
然后您可以直接将其与 PROC COMPARE 一起使用,而无需重命名任何变量。
proc compare data=DS1 compare=DS2 ;
var &oldlist;
with &newlist;
run;
我有两个相同的 SAS table,只是列名不同。
第一个 table D1
有 80 个具有以下模式的列名称 X1000_a010_b020
,第二个 table D2
有 80 个具有以下模式的列名称 X_1000_a0010_b0020
。请注意,它们的顺序不同。
我想确保 D1
中的所有列都与 D2
中的名称相同。换句话说,我想在X后面加下划线,在所有a和b后面加一个0。
但是我不知道如何进行。我想 RegEx 会是首选,但我不熟悉它。
作为结构示例,前段时间我使用以下代码将列名中的空格替换为下划线。我想做同样的事情,但对于 X 之后的下划线和 a 和 b 之后的 0。
%macro rename_vars(table);
%local rename_list sqlobs;
proc sql noprint;
select catx('=',nliteral(name),translate(trim(name),'_',' '))
into :rename_list separated by ' '
from sashelp.vcolumn
where libname=%upcase("%scan(work.&table,-2,.)")
and memname=%upcase("%scan(&table,-1,.)")
and indexc(trim(name),' ')
;
quit;
%if &sqlobs %then %do ;
proc datasets lib=%scan(WORK.&table,-2);
modify %scan(&table,-1);
rename &rename_list;
run;
quit;
%end;
%mend rename_vars;
您的示例代码似乎表明您已经制定了如何实施重命名的计划,因此让我们专注于生成 OLDNAME <-> NEWNAME 对。您可以使用 PROC CONTENTS 或使用 SQL 代码(或使用任何工具 SASHELP.VCOLUMN 查询 DICTIONARY.COLUMNS 来生成特定数据集中的名称列表。因此,假设您有一个名为 CONTENTS 的数据集,其中包含一个名为 NAME 的变量。所以目标是创建一个新变量,我们可以称之为 NEWNAME。
因此,让我们将您所说的三个转换直接转化为单独的操作。你可以折叠步骤,但是这个操作对效率没有迫切要求。
data fixed_names;
set contents;
newname = tranwrd(upcase(name),'_A','_A0');
newname = tranwrd(newname,'_B','_B0');
newname = cats(char(newname,1),'_',substr(newname,2));
keep name newname;
run;
现在您可以将该列表拉入宏变量。因此 space 分隔的 old=new
对列表对于重命名很有用。
proc sql noprint;
select catx('=',name,newname) into :renames
from fixed_names
where newname ne upcase(name)
;
quit;
或者,如果目标是逐字比较两个数据集,您可能希望生成一个旧名称列表和一个单独的新名称列表。
select name,newname
into :oldlist separated by ' '
, :newlist separated by ' '
from fixed_names
;
然后您可以直接将其与 PROC COMPARE 一起使用,而无需重命名任何变量。
proc compare data=DS1 compare=DS2 ;
var &oldlist;
with &newlist;
run;