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