我有一个表1,其中包含以下代码中显示的以下数据:
data have(index=(date));
infile cards truncover expandtabs;
input TPMC PWC PWSC $ Site ET $ Date : date9. Time $ DIAM $ PXMC $ SF;
format date date9.;
cards;
7101 7101 US000521 1 Works1 08Nov2016 11:58 890,3 1
7102 7102 US000361 1 Works2 02Nov2016 13:01 878,1 1
7102 7102 UC000348 2 Works3 07Nov2016 18:22 877,3 1
7106 7106 UC00424 1 Works1 05Oct2016 9:43 890,4 1
7106 7106 UC00437 3 Works2 07Nov2016 18:23 877,1 1
7106 7106 UC309 4 Works3 07Nov2016 18:26 877,8 1
7107 7107 UC05327 1 Works1 06Oct2016 8:41 837 1
7107 7107 UC200 2 Works2 13Oct2016 12:53 890,55 1
7108 7108 UC000361 3 Works1 02Nov2016 13:01 878,1 1
7108 7108 UC00432 1 Works2 07Nov2016 18:25 877,8 1
7108 7108 UC106 2 Works3 03Oct2016 9:37 890,3 1
;
run;
data want;
set have;
array x{1} _temporary_;
array y{1} $ 40 _temporary_;
x{1}=date;y{1}=TPMC;
call missing(of _all_);
TPMC=y{1};Time=0;
do i=5 to 1 by -1;
date=x{1}-i;output;
end;
set have point=_n_;output;
call missing(of _all_);
TPMC=y{1};Time=0;
do i=1 to 5;
date=x{1}+i;output;
end;
drop i;
run;
我还有另一张如下表所示的表格:
data have0001;
input WPmeas $ Date :date8. Time :Time. T_Id $ ASN $ WC $ CWC T_Side M_No $ Yval $ XVal $;
FORMAT DATE date8. Time HHMM.;
datalines;
1 19JAN16 12:19 20949 1 7604 US2301 R 1 -82140 2468
2 21JAN16 11:11 20949 1 7604 US2302 R 2 -81940 2466
3 01FEB16 16:13 20949 1 7604 US2303 R 3 -81739 2463
4 29MAR16 13:12 20949 1 7604 US2303 R 4 -81539 2459
5 13MAY16 14:11 20949 1 7604 US2304 R 5 -81339 2456
6 05OCT16 15:15 20949 1 7106 US2301 R 6 -82140 2468
7 07NOV16 16:18 20949 1 7106 US2302 R 7 -81940 2466
8 01FEB16 17:15 20949 1 7604 US2303 R 8 -81739 2463
9 29MAR16 18:17 20949 1 7604 US2303 R 9 -81539 2459
10 13MAY16 19:12 20949 1 7604 US2304 R 10 -81339 2456
;
run;
我只是想找出实现以下目标的方法:
选择t1.PWSC = t2.CWC和t1.TPMC = t2.WC
从t1选择日期(t1.Date)= t2.Date
从t1(t1.time)选择时间,仅从t2.Time选择时间的第一个值(即如果我们按升序对时间进行排序,则第一个将是00:00,前提是它在那里,否则无论哪个是先拿起来)
然后
换句话说,我需要的是从 t2 检索数据并仅在日期匹配时与 t1 合并,WC / TPMC和CWC / PWSC是匹配。而且,t2中的时间是asc中的第一次观察。顺序。
答案 0 :(得分:1)
无法评论您的帖子以询问规格。据我了解你的问题:你想合并你的表"想要" (= t2)和" have0001" (= T1)。重复关键变量pwc cwc和日期出现在" have0001" (= T1)。
我认为" have0001" (= t1)是小表并对其进行排序,同时不会导致太多问题。然后,以下代码使用哈希对象合并这两个表。
它生成一个表merge1,将t1中的第一个副本用于最小的时间值。如果您希望将重复项与t2中的相同值多次合并并输出它们,则代码末尾还会有一个示例,为您提供数据集merge2。
data have(index=(date));
infile cards truncover expandtabs;
input TPMC PWC PWSC $ Site ET $ Date : date9. Time :Time. DIAM $ PXMC $ SF;
format date date9.;
cards;
7101 7101 US2301 1 Works1 19JAN16 11:58 890,3 1
7102 7102 US2301 1 Works2 02Nov2016 13:01 878,1 1
7102 7102 UC000348 2 Works3 07Nov2016 18:22 877,3 1
7106 7106 UC00424 1 Works1 05Oct2016 9:43 890,4 1
7106 7106 UC00437 3 Works2 07Nov2016 18:23 877,1 1
7106 7106 UC309 4 Works3 07Nov2016 18:26 877,8 1
7107 7107 UC05327 1 Works1 06Oct2016 8:41 837 1
7107 7107 UC200 2 Works2 13Oct2016 12:53 890,55 1
7108 7108 UC000361 3 Works1 02Nov2016 13:01 878,1 1
7108 7108 UC00432 1 Works2 07Nov2016 18:25 877,8 1
7108 7108 UC106 2 Works3 03Oct2016 9:37 890,3 1
;
run;
data have0001;
input WPmeas $ Date :date8. Time :Time. T_Id $ ASN $ WC CWC $ T_Side M_No $ Yval $ XVal $;
FORMAT DATE date8. Time HHMM.;
datalines;
2 19JAN16 12:00 20949 1 7101 US2301 R 2 -81940 2466
1 19JAN16 11:58 20949 1 7101 US2301 R 1 -82140 2468
3 01FEB16 16:13 20949 1 7604 US2303 R 3 -81739 2463
4 29MAR16 13:12 20949 1 7604 US2303 R 4 -81539 2459
5 13MAY16 14:11 20949 1 7604 US2304 R 5 -81339 2456
6 05OCT16 15:15 20949 1 7106 US2301 R 6 -82140 2468
7 07NOV16 16:18 20949 1 7106 US2302 R 7 -81940 2466
8 01FEB16 17:15 20949 1 7604 US2303 R 8 -81739 2463
9 29MAR16 18:17 20949 1 7604 US2303 R 9 -81539 2459
10 13MAY16 19:12 20949 1 7604 US2304 R 10 -81339 2456
;
run;
data want;
set have;
array x{1} _temporary_;
array y{1} $ 40 _temporary_;
x{1}=date;y{1}=TPMC;
call missing(of _all_);
TPMC=y{1};Time=0;
do i=5 to 1 by -1;
date=x{1}-i;output;
end;
set have point=_n_;output;
call missing(of _all_);
TPMC=y{1};Time=0;
do i=1 to 5;
date=x{1}+i;output;
end;
drop i;
run;
proc sort data=have0001;
by WC CWC date time
run;
data merged1;
if 0 then set have0001;
if _N_ = 1 then do;
declare hash hh(dataset:'have0001',ordered:'Y',multidata:'Y');
hh.definekey('WC','CWC','date');
hh.definedata(all:'Y');
hh.definedone();
end;
do until (theend);
set want (rename=(PWSC=CWC TPMC=WC)) end=theend;
rc = hh.find();
if rc=0 then output;
end;
run;
data merged2;
if 0 then set have0001;
if _N_ = 1 then do;
declare hash hh(dataset:'have0001',ordered:'Y',multidata:'Y');
hh.definekey('WC','CWC','date');
hh.definedata(all:'Y');
hh.definedone();
end;
do until (theend);
set want (rename=(PWSC=CWC TPMC=WC)) end=theend;
rc = hh.find();
do while (rc = 0);
output;
rc = hh.find_next();
end;
end;
run;
答案 1 :(得分:1)
考虑proc sql解决方案,因为前两个列出的项可以是JOIN
子句,最后一个要求可以是WHERE
子句中的相关聚合subquery:
proc sql;
CREATE TABLE want AS
SELECT t1.TPMC, t1.PWC, t1.PWSC, t1.Site, t1.ET, t1.Date AS t1Date, t1.Time AS t1Time,
t1.DIAM, t1.PXMC, t1.SF, t2.WPmeas, t2.Date AS t2Date, t2.Time AS t2Time, t2.T_Id,
t2.ASN, t2.WC, t2.CWC, t2.T_Side, t2.M_No, t2.Yval, t2.XVal
FROM have t1
INNER JOIN have0001 t2
ON t1.TPMC = t2.WC AND t1.PWSC = t2.CWC AND t1.Date = t2.Date
WHERE t2.Time IN (SELECT MIN(sub.Time)
FROM have0001 sub
WHERE sub.CWC = t2.CWC
AND sub.Date = t2.Date);
quit;
如图所示,由于两个数据集中的重复列名称SELECT t1.*, t2.*
和Date
,所有列都列出而不是缩写为Time
。否则,SAS会使用WARNING