/*----------------------------------------------------------* This is the code of each of the ten ways data could be merged as presented at NESUG 2009. This code is provided "AS IS" with no implied warrenty. In other words, use this code at your own risk. *----------------------------------------------------------*/ *--------------------------------------; * The data ; *--------------------------------------; data PATDATA; infile cards; input SUBJECT TRT_CODE $; cards; 124263 A 124264 A 124266 B 124267 B ; run; data ADVERSE; infile cards; input SUBJECT EVENT $ 8-15; cards; 124263 HEADACHE 124265 VOMITING 124266 FEVER 124266 NAUSEA ; run; *--------------------------------------; * 1. MERGE Statement ; *--------------------------------------; DATA alldata0; MERGE adverse (in=a) patdata (in=b); BY subject; IF a; RUN; *--------------------------------------; * 2. SQL ; *--------------------------------------; PROC SQL; CREATE TABLE alldata0 AS SELECT a.*, b.trt_code FROM adverse a LEFT JOIN patdata b ON a.subject=b.subject; QUIT; RUN; *--------------------------------------; * 3. KEY= option ; *--------------------------------------; DATA alldata0; SET adverse; SET patdata KEY=subject /UNIQUE; DO; IF _IORC_ THEN DO; _ERROR_=0; trt_code=''; END; END; RUN; *--------------------------------------; * 4. FORMAT Procedure ; *--------------------------------------; DATA fmt; RETAIN fmtname 'TRT_FMT' type 'C'; SET patdata; RENAME subject=start trt_code=label; PROC FORMAT CNTLIN=fmt; DATA alldata0; SET adverse; ATTRIB trt_code LENGTH=$1 LABEL='Treatment Code'; trt_code=PUT(subject,$trt_fmt.); RUN; *--------------------------------------; * 5. Hash Tables ; *--------------------------------------; DATA alldata0; IF _n_=0 THEN SET patdata; IF _n_=1 THEN DO; DECLARE HASH _h1 (dataset: "PATDATA"); rc=_h1.definekey("SUBJECT"); rc=_h1.definedata("TRT_CODE"); rc=_h1.definedone(); call missing(SUBJECT,TRT_CODE); END; SET adverse; rc=_h1.find(); IF rc^=0 THEN trt_code=" "; DROP rc;; RUN; *--------------------------------------; * 6. Loading Unique Dataset into an ; * Array ; *--------------------------------------; DATA _null_; SET sashelp.vtable; WHERE libname='WORK'; WHERE ALSO memname in('PATDATA','ADVERSE'); CALL SYMPUT('X'||memname,put(nobs,8.)); DATA alldata0; LENGTH trt_code $1; ARRAY f{&xpatdata.,2} $6 _TEMPORARY_; DO i=1 TO &xpatdata.; SET patdata (RENAME=(trt_code=trt_code_dict)); f{i,1}=PUT(subject,6.); f{i,2}=trt_code_dict; END; DO i=1 TO &xadverse.; SET adverse; trt_code=''; DO j=1 TO &xpatdata.; IF subject=INPUT(f(j,1),best.) THEN DO; trt_code=f{j,2}; OUTPUT; END; IF ^MISSING(trt_code) THEN LEAVE; END; IF MISSING(trt_code) THEN OUTPUT; END; DROP i j trt_code_dict; RUN; *--------------------------------------; * 7. MODIFY Statement ; *--------------------------------------; DATA adverse adverse2; DO p=1 TO totobs; _iorc_=0; SET patdata point=p nobs=totobs; DO WHILE(_iorc_=%sysrc(_sok)); MODIFY adverse KEY=subject; SELECT (_iorc_); WHEN (%sysrc(_sok)) DO; /*Match Found*/ SET patdata POINT=p; OUTPUT adverse2; END; WHEN (%sysrc(_dsenom)) _error_=0; /*No Match*/ OTHERWISE DO; /*A major problem somewhere*/ PUT 'error: _iorc_ = ' _iorc_ / 'program halted.'; _error_ = 0; STOP; END; END; END; END; STOP; RUN; *--------------------------------------; * 8. Merge with Update ; *--------------------------------------; DATA alldata0 (DROP=_trt_code); LENGTH _trt_code $1; /*Temporary variable containing TRT_CODE*/ RETAIN _trt_code ''; UPDATE adverse (in=a) patdata; BY subject; IF a; IF FIRST.subject THEN _trt_code=trt_code; ELSE trt_code=_trt_code; RUN; *--------------------------------------; * 9. CALL EXECUTE ; *--------------------------------------; DATA _null_; SET patdata; CALL EXECUTE("DATA alldat;"|| " SET adverse;"|| " WHERE subject='"|| STRIP(subject)||"';"|| " trt_code='"|| STRIP(trt_code)||"';"|| "PROC APPEND BASE=alldata0 "|| "DATA=dat0 FORCE;"|| "RUN;"); RUN; *--------------------------------------; * 10. PEEK(C) and POKE ; *--------------------------------------; DATA alldata0; ARRAY f{&xpatdata.} $6 _TEMPORARY_; /*Store SUBJECT values*/ ARRAY g{&xpatdata.} $1 _TEMPORARY_; /*Store TRT_CODE values*/ LENGTH trt_code $1; DO i=1 TO &xpatdata.; SET patdata (RENAME=(trt_code=trt_dict)); CALL POKE(CATS(subject), ADDR(f[1])+((i-1)*6),6); CALL POKE(CATS(trt_dict), ADDR(g[1])+((i-1)*1),1); END; DO i=1 TO &xadverse.; SET adverse; trt_code=''; DO j=1 TO &xpatdata.; IF subject=PEEKC(ADDR(f[1])+((j-1)*6),6) THEN DO; trt_code=PEEKC(ADDR(g[1])+((j-1)*1),1); OUTPUT; END; IF ^MISSING(trt_code) THEN LEAVE; END; IF MISSING(trt_code) THEN OUTPUT; END; DROP i j trt_code_dict; RUN; /*EOF*/