Объединить два фрейма данных по дате в SAS - PullRequest
0 голосов
/ 07 мая 2020

У меня есть две таблицы, и я хочу объединить их по id и по последней дате перед датой в df1 для соответствующего id .

data df1;
 input id $ date value ;
 informat date yymmdd10.;
 format date yymmdd10. ;
cards;
a 19991231 1
a 20011231 2
b 20151231 4
;

data df2;
  input id $ date ;
  informat date yymmdd10.;
  format date yymmdd10.;
cards;
a 20020101
c 20160701
;

Я пробовал это, но чего-то не хватает.

proc sql;
create table output
as select a.*, b.date
from df1 as a, df2 as b
where a.id = b.id
group by a.id, b.id
having (a.date) > max(b.date);
quit;

Желаемый результат:

data output;
  input id $ date value;
  informat date yymmdd10.;
  format date yymmdd10.;
cards;
a 20011231 2
;

Ответы [ 3 ]

1 голос
/ 07 мая 2020

Я бы сделал это в два этапа, с помощью PROC SQL для объединения и сортировки двух таблиц, затем шаг data, чтобы вывести только самую последнюю дату для каждого идентификатора.

proc sql;
    create table o1 as 
        select  a.id,
                a.date,
                a.value
        from df1 a
        join df2 b
            on  b.id = a.id
            and b.date > a.date
        order by a.id, a.date
    ;
quit;

data output;
    set o1;

    by id;
    if last.id then output;
run;
0 голосов
/ 07 мая 2020
proc sort data=df1;
  by id descending date;

proc sort data=df2;
  by id;

data want;
  merge df1 (in=in1) df2 (in=in2 rename=(date=date_max));
  by id;

  ** Assume you want only values that are in both datasets **;
  if in1 & in2;

  retain flag;

  if first.id then flag = 0;

  ** If no dates before max date yet and this one is before max date, we have a winner **;
  if flag = 0 & date < date_max then do;
    ** Set flag to indicate this ID has already found the max date **;
    flag = 1;
    output;
  end;

run;
0 голосов
/ 07 мая 2020

Вы можете использовать SET для чередования записей. Используйте RETAIN, чтобы сохранить последнюю версию VALUE из первого набора данных. Вы не указали, есть ли у вас отсутствующие значения VALUE, но давайте все равно проверим это.

data want;
  set df1(in=in1) df2(in=in2);
  by id date ;
  retain last_value;
  if first.id then last_value=.;
  if in1 and not missing(value) then last_value=value;
  if in2 and not missing(last_value);
run;

Результат:

                                    last_
Obs    id          date    value    value

 1     a     2002-01-01      .        2

Обратите внимание, что этот метод принимает значение на или раньше ДАТА во втором наборе данных. Если вы хотите, чтобы оно принимало только последнее значение ПЕРЕД этой датой, измените порядок, в котором два набора данных упоминаются в операторе SET.

...