按数字范围合并

时间:2011-05-20 04:05:42

标签: merge range sas

我想根据范围而不是显式数字为一个人分配一个人的姓名。使用格式可以做到这一点,但由于我在数据集中有名称,我宁愿避免编写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
;

感谢您的帮助。

3 个答案:

答案 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;

同样,它要求数字以预定的增量进行,例如,整数。