Слияние по диапазону чисел - PullRequest
2 голосов
/ 20 мая 2011

Я бы хотел присвоить имя человека номеру на основе диапазона, а не явного номера. Это можно сделать с помощью форматов, но поскольку у меня есть имена в наборе данных, я бы предпочел избежать ручного процесса написания 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 ]

5 голосов
/ 20 мая 2011

Вы можете сделать это, используя 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;
3 голосов
/ 24 мая 2011

Одна удобная функция proc format - это возможность использовать набор данных для создания формата вместо того, чтобы вводить его вручную.Ваш сценарий кажется идеальным сценарием для этой функции.

В приведенном вами примере несколько небольших изменений в наборе данных "names" приведут его в форму, которую можно прочитать в формате 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

Затем я могу просто изменить код, который создает набор данных "names", чтобы он выглядел следующим образом:

data names;
   retain fmtname "names" type "N";
   infile "<path to file>/names.csv" dsd;
   input start end label $;
run;

Теперь я могу запустить proc proc с опцией cntlin, как я делал раньше:

proc format cntlin=names;run;
1 голос
/ 22 мая 2011

Я думаю, что 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;

Опять же, требуется, чтобы числа приходили с заранее определенными приращениями, например, целые числа.

...