我想根据范围而不是显式数字为一个人分配一个人的姓名。使用格式可以做到这一点,但由于我在数据集中有名称,我宁愿避免编写proc format
的手动过程。
data names;
input low high name $;
datalines;
1 10 John
11 20 Paul
21 30 George
31 40 Ringo
;
data numbers;
input number;
datalines;
33
21
17
5
;
所需的输出是:
data output;
input number name $;
datalines;
33 Ringo
21 George
17 Paul
5 John
;
感谢您的帮助。
答案 0 :(得分:5)
你可以使用PROC SQL这样做:
proc sql;
create table output as
select numbers.number, names.name
from numbers left join names
on numbers.number ge names.low
and numbers.number le names.high
;
quit;
答案 1 :(得分:3)
proc format
的一个便利功能是能够使用数据集来创建格式,而不是手动输入。您的方案似乎是此功能的完美方案。
在您给出的示例中,对“名称”数据集进行一些小的更改会将其放入可以通过proc格式读取的表单中。
例如,如果我像这样修改名称数据集。
data names;
retain fmtname "names" type "N";
input start end label $;
datalines;
1 10 John
11 20 Paul
21 30 George
31 40 Ringo
;
然后我可以发出此命令来构建基于它的格式。
proc format cntlin=names;run;
现在,我可以像使用任何其他格式一样使用此格式。例如,要根据数字创建包含所需“名称”的新列,您可以执行以下操作:
data numbers;
input number;
number_formatted=put(number,names.);
datalines;
33
21
17
5
;
以下是输出结果:
number_
number formatted
33 Ringo
21 George
17 Paul
5 John
更新以解决问题:
从文本文件中读取所需的编码没有太大区别。我们只需要设置它,以便输出数据集具有proc格式所需的特定变量名称(fmtname,type,start,end和label)。
例如,如果我有一个名为“names.csv”的外部逗号分隔文件,如下所示:
1,10,John
11,20,Paul
21,30,George
31,40,Ringo
然后我只需更改创建“名称”数据集的代码,使其如下所示:
data names;
retain fmtname "names" type "N";
infile "<path to file>/names.csv" dsd;
input start end label $;
run;
现在我可以像以前一样使用cntlin选项运行proc格式:
proc format cntlin=names;run;
答案 2 :(得分:1)
我认为SQL确实更简洁,但是如果你不是它的忠实粉丝并且数字以已知的增量出现,你可以尝试类似的东西:
data ranges;
set names;
do number = low to high; /* by ... */
output;
end;
proc sort;
by number;
run;
data output;
merge ranges
numbers ( in = innum )
;
by number;
keep number name;
if innum;
run;
同样,它要求数字以预定的增量进行,例如,整数。