我有一个包含邮政编码字段(数字类型)的表格,有些邮政编码只包含4位数字。我需要用前导空格填充4位邮政编码。 我创建了一个字符如下:
proc sql;
create table myTable as
select * , put(Zip,5.) as ZipChar
from Mytable;
create table myTable as
select *, case when Zip<10000 then " "||ZipChar else ZipChar end as Zip_Fixed
from Mytable;
quit;
现在我的困难是如何找到Zip_Fixed而不是Zip列。 Zip是数字类型,Zip_Fixed是字符类型。必须更换,因为必须保留列的顺序。我对所有其他创造性解决方案都很感兴趣。
谢谢, 阿迪
答案 0 :(得分:3)
我写了一个宏,它在几个月前重新排序变量。它可能不是最短的方式,但它应该可以解决你的问题。
假设您有一个数据集,并希望在move_me
v1
data temp;
input v1 v2 v3 v4 v5 move_me;
datalines;
1 2 3 4 5 0
1 2 3 4 5 0
1 2 3 4 5 0
;
run;
运行下面的%order
宏:
%macro order(dsn, var1, before_or_after, var2);
/* get list of variables in your dataset from dictionary.columns*/
proc sql;
create table vars as select
varnum, name
from dictionary.columns
where memname = upcase("&dsn.");
quit;
/* assign the final position of the variable that you want to move*/
proc sql;
create table vars2 as select
a.*,
case when a.name = "&var1." then max(b.varnum) else . end as varnum_want
from vars as a
left join vars (where = (name = "&var2.")) as b
on a.varnum = b.varnum;
quit;
/* move the variable to that location*/
data vars3 (drop = varnum_want);
set vars2;
%if &before_or_after. = before %then %do;
if name = "&var1." then varnum = varnum_want - 0.5;
%end;
%else %if &before_or_after. = after %then %do;
if name = "&var1." then varnum = varnum_want + 0.5;
%end;
%else %do;
putlog "ERROR: Pick 'before' or 'after'";
%end;
proc sort; by varnum;
run;
/* select variables into a macro variable in correct order*/
proc sql noprint;
select name into: ordered_vars separated by " " from vars3 order by varnum;
quit;
/* reorder variables*/
data &dsn._reordered;
retain &ordered_vars.;
set &dsn.;
run;
%mend order;
然后,您可以使用语法%order(temp, move_me, before, v1);
创建名为temp_reordered
的数据集,该数据集在move_me
之前已插入v1
。在您的情况下,听起来您希望运行%order(myTable, zipFixed, before, [your 8th variable's name])
然后删除任何无关的变量以保持变量的正确排序。
答案 1 :(得分:2)
您对PUT()
函数的使用将创建一个带前导空格的字符字段。你的第二步将增加另一个领先空间。
为什么不直接使用前导零?然后,这些值看起来更像数字,仍然可以正确排序。
put(zip,Z5.)
如果最终目标是创建一个具有固定宽度字段的文本文件(作为您提及的其他注释之一),那么您只需使用用于编写文本文件的PUT语句中的格式。
data _null_;
set mytable ;
file 'myfile.txt';
put ... zip 5. ... ;
run;
答案 2 :(得分:0)
如Tom所说,邮政编码通常用零填充,而不是空格。在少数情况下它们也可以是三位数(例如波多黎各),所以要注意这一点。
此外,根据您的需要,格式化列可能就足够了。它不会更改数字列的内容,但会改变它的显示方式。
proc datasets;
modify have;
format zip z5.;
quit;
同样,对于某些用例,这不会有所帮助,但对于其他用户而言,它可能优于转换为角色。