SAS Merge By не работает

Ниже приведен макрос, который я написал, чтобы исключить соединение двух наборов данных.

/*
* Macro to add the t-rate to the data
*/
%MACRO RFRATE(WITHOUT_RATE, WITH_RATE);
/*read the tbill rate data*/
data TBRATE;
  INFILE "T-RATE/T-RATE-FORMATTED.csv"
  DELIMITER = "," 
  MISSOVER DSD 
  FIRSTOBS=2
  LRECL=32767;
  INPUT DATE one_M three_M six_M one_Y two_Y three_Y five_Y seven_Y ten_Y twenty_Y thirty_Y;
  format DATE yymmddn8.;
  length Date 4;
run;

data &WITH_RATE;
  merge &WITHOUT_RATE(IN=A) TBRATE(IN=B);
  by Date;
  if A;
run;

/*I have also tried the following way (SQL)*/
/*
PROC SQL;
  Create table &WITH_RATE as
  Select a.*,b.*
  from
    &WITHOUT_RATE a
  left join
    TBRATE b
  on a.Date=b.Date;
quit;
*/

proc export data=&WITH_RATE (obs=99999)
  outfile= 'samplesmall.csv'
  dbms=CSV REPLACE;
  putname=YES;
run;

proc contents data= TBRATE  position; 
run;

proc contents data= &WITHOUT_RATE  position; 
run;

%mend;

TBRATE - это некоторые данные, похожие на следующий формат:

| Date     | Rate     |
|----------|----------|
| 20120101 | 1.0      | 
| 20120102 | 1.5      | 
| 20120103 | 1.5      |
| 20120104 | 1.3      |
| 20120105 | 1.1      |

WITHOUT_RATE - это некоторые данные, подобные следующим:

| Date     | Other Data    |
|----------|---------------|
| 20120101 | 7.0           | 
| 20120101 | 3.5           | 
| 20120101 | 4.5           |
| 20120101 | 2.3           |
| 20120101 | 11.1          |
| 20120102 | 23.0          | 
| 20120102 | 12.5          | 
| 20120102 | 12.5          |
| 20120102 | 11.3          |
| 20120102 | 11.1          |

Я хотел создать что-то похожее на следующее:

| Date     | Other Data    |   Rate  |
|----------|---------------|----------
| 20120101 | 7.0           | 1.0     | 
| 20120101 | 3.5           | 1.0     |
| 20120101 | 4.5           | 1.0     |
| 20120101 | 2.3           | 1.0     |
| 20120101 | 11.1          | 1.0     |
| 20120102 | 23.0          | 1.5     |
| 20120102 | 12.5          | 1.5     |
| 20120102 | 12.5          | 1.5     |
| 20120102 | 11.3          | 1.5     |
| 20120102 | 11.1          | 1.5     |

Формат переменной даты в WITHOUT_RATE:

 Variable      Type    Len    Format       Label
 DATE          Num       4    YYMMDDN8.    Quote date

Формат переменной даты в TBRATE:

 Variable    Type    Len    Format
 DATE        Num       4    YYMMDDN8.

Кажется, они одинаковы.

Тем не менее, код продолжает давать нулевые результаты:

| Date     | Other Data    |   Rate  |
|----------|---------------|----------
| 20120101 | 7.0           |         | 
| 20120101 | 3.5           |         |
| 20120101 | 4.5           |         |
| 20120101 | 2.3           |         |
| 20120101 | 11.1          |         |
| 20120102 | 23.0          |         |
| 20120102 | 12.5          |         |
| 20120102 | 12.5          |         |
| 20120102 | 11.3          |         |
| 20120102 | 11.1          |         |

Поэтому мне было интересно, где я ошибся?

Обновление № 2

The code used to call the macro: 

/*The output dataset*/
%NBBO(20130102, tempoutputset);
%NBBOReturn(tempoutputset, NBBODATA);
%RFRATE(NBBODATA, RFRATEDATA);

3 ответа

Решение

Я решил это. Благодаря предложениям @Quentin и @India.Rocket мне удалось найти решение.

Проблема была в чтении дат из файла CSV. Кажется, что даты в формате ггггммдд или гггг-мм-дд не могут быть прочитаны правильно. Мне пришлось переформатировать даты в csv в mm/dd/yyyy с помощью python, а затем ввести их как DATE:mmddyy10 в sas. Однако другой набор данных, с которым я сливался, имеет формат даты в yymmddn8. Поэтому мне пришлось переформатировать DATE:mmddyy10. до ггддн8. заставить все это работать.

Следующий код был использован.

data TBRATE;
  INFILE "T-RATE/T-RATE-FORMATTED.csv"
  DELIMITER = ","
  MISSOVER DSD
  FIRSTOBS=2
  LRECL=32767;
  INPUT DATE:mmddyy10. DateRaw one_M three_M six_M one_Y two_Y three_Y five_Y seven_Y ten_Y twenty_Y thirty_Y;
  format DATE yymmddn8.;
run;

Удалить set от data merge заявление. Вы не можете написать набор в операторе слияния данных. Также вам нужно отсортировать наборы данных, если они еще не отсортированы по умолчанию по дате, чтобы они слились в дату:-

Proc sort data=&WITHOUT_RATE; by Date; run;
Proc sort data=TBRATE; by Date; run;

data &WITH_RATE;
  merge &WITHOUT_RATE(IN=A) TBRATE(IN=B);
  by Date;
  if A;
run;

OR 

PROC SQL:
Create table &WITH_RATE as
Select a.*,b.Rate
from
&WITHOUT_RATE a
left join
TBRATE b
on a.Date=b.Date;
quit;

Согласитесь с @Reeza, я бы удалил код макроса, чтобы поработать над поиском источника проблемы. Как только он будет работать вне языка макросов, вернитесь к работе над макросом. На первый взгляд, я думаю, ваши значения BY не совпадают.

Попробуйте что-то вроде ниже, чтобы посмотреть на несовпадающие записи:

data WITH_RATE
     Aonly
     Bonly
     BothAandB
  ;
  merge WITHOUT_RATE(IN=A) TBRATE(IN=B);
  by Date;
  if A then output With_Rate;

  if A=1 and B=1 then output BothAandB;  
  else if B=0 then output Aonly;
  else if A=0 then output Bonly;

run;

Затем удалите форматы на дату и посмотрите на значения в Aonly и Bonly, чтобы понять, почему они не совпадают. Выходной набор данных Aonly будет содержать записи из WITHOUT_RATE, у которых нет совпадающей DATE в TBRATE. Выходной набор данных Bonly будет иметь записи из TBRATE, которые не имеют совпадающую DATE в WITHOUT_RATE. Выходной набор данных BothAandB будет иметь соответствующие записи.

Если вы видите значения в Aonly и Bonly, которые выглядят так, как будто они должны совпадать, и предполагая, что это даты, возможно, округлите их до слияния, чтобы убедиться, что они являются целыми числами, чтобы избежать любой возможной разницы в числовой точности / плавающей запятой.

Другие вопросы по тегам