* 제목 : 다수의 Hash 테이블을 사용하여서 transaction(변동) 데이터 처리하기;
* Sample 25988: Using multiple hash tables to manage transaction data;
* 출처 : http://support.sas.com/kb/25/988.html;
* 목적 : REPLACE 매소드를 사용하여서 transaction 형태에 따라서 HASH 테이블을 갱신(Update)한다.;
/* TYPE 변수에서 'p' 는 구매를 표시하고, 's'는 판매를 표시한다.
SYMBOL 변수는 양쪽 데이터 세트에 공통적으로 존재한다. */
data Transactions;
input date date7. symbol $ type $ Size;
datalines;
15Jun05 A p 500
16Jun05 G s 250
16Jun05 A s 100
17Jun05 C s 750
;
data DailyInventory;
input symbol $ Size;
datalines;
G 1000
C 1500
;
/* SIZE 변수의 총 합계 값을 저장하기 위한 TOTSIZE 변수에 대한 초기값을 획득하기 위하여 PROC SUMMARY를 사용한다. */
proc summary data=dailyinventory;
output out=totalinventory(keep=size);
var size ;
freq size;
run;
/* 매크로 변수(STOTSIZE) 생성 */
data _null_;
set totalinventory;
call symput('stotsize',left(put(size,8.)));
stop;
run;
proc sort data=transactions;
by date;
run;
data _null_;
set transactions(rename=(size=t_size)) end=end;
by date;
/* PDV을 구성하기 위하여 HAHS 오브젝트에 정의된 변수의 LENGTH 속성을 정의한다. */
length symbol $ 8 size date totsize 8;
retain totsize;
/* 데이터 스텝의 첫 번째 반복 작업에서 Hash 테이블 DAILY를 생성하고 인스턴트화 한다.
DATASET: 인수 태그를 사용하여서 DAILYINVENTORY 데이터 세트를 Hash 테이블 DAILY에 로딩한다.
daily HASH 테이블 검색을 위하여 DEFINEKEY 매소드를 사용하여서 SYMBOL 변수를 조회 키 변수로 정의하고,
DEFINEDATA 매소드를 사용하여서 키와 연관된 데이터 값으로 SYMBOL,SIZE 변수를 데이터 항목으로 정의한다.
출력 데이터 세트에 SYMBOL 변수의 값을 출력하기 위하여 KEY와 DATA 양쪽 항목에 정의한다.
키 변수는 사용자가 별도의 프로그램 작업을 수행 하지 않으면 기본적으로 출력되지 않는다.
두 번째 HASH 테이블 TOT를 생성한다. TOT HASH 객체에 y 변수의 데이터를 사용자가 지정한 올림차순 방식으로
정렬하여서 로드하기 위하여 ORDERED: 인수를 사용한다.
TOT HASH 테이블 검색을 위하여 DEFINEKEY 매소드를 사용하여서 DATE 변수를 조회 키 변수로 정의하고,
DEFINEDATA 매소드를 사용하여서 키와 연관된 데이터 값으로 DATE, TOTSIZE 변수를 데이터 항목으로 정의한다. */
if _n_=1 then do;
dcl hash daily(dataset:'dailyinventory');
daily.definekey('symbol');
daily.definedata('symbol', 'size');
daily.definedone();
dcl hash tot(ordered:'y');
tot.definekey('date');
tot.definedata('date','totsize');
tot.definedone();
totsize=&stotsize;
* daily.output(dataset:'DAILY');
end;
/* 개별 BY 그룹에서 첫 번째 관측치를 처리하는 경우 ADD 매소드를 사용하여서 현재 데이터 값을 TOT HASH 테이블에 추가한다. */
if first.date then DO;
tot.add();
tot.output(dataset:'TOT');
END;
/* FIND 매소드를 사용하여서 DAILY HASH 오브젝트에서 SYMBOL 변수(transactions 데이터 세트)의 현재 값을 찾는다. */
rc=daily.find();
/* SYMBOL의 현재 값이 DAILY HASH 테이블에 존재하지 않으면, 그 값을 HASH 테이블에 추가한다. */
if rc ne 0 then DO;
rcadd=daily.add();
* daily.output(dataset:'DAILY1');
END;
/* TYPE 변수가 'p'(구매) 인경우에는 SIZE 변수의 값을 계산하고,
REPLACE 매소드를 사용하여서 계산된 SIZE 값으로 DAILY HASH 테이블에서 SIZE 변수의 값을 갱신한다. */
if type='p' then do;
size=sum(size,t_size);
daily.replace();
/* FIND 매소드를 사용하여서 DATE 변수의 값과 일치하는 값을 찾아서 TOTSIZE 변수를 갱신하고,
TOT HASH 테이블에서 TOTSIZE 변수의 값을 변경한다. */
tot.find();
totsize=totsize+t_size;
tot.replace();
end;
/* TYPE 변수가 's'(판매)인 경우에는 조건에 따라서 DAILY와 TOT HASH 테이블의 값을 갱신한다. */
else if type='s' then do;
size=sum(size,(-1*t_size));
daily.replace();
tot.find();
totsize=totsize-t_size;
tot.replace();
end;
/* TRANSACTION 의 모든 관측치를 처리한 후에, OUTPUT 매소드를 사용하여서 TOT HASH 테이블을
TOTALINVENTORY 데이터 세트로 생성하고, DAILY HASH 테이블을 DAILYINVENTORY 데이터 세트로 생성한다. */
if end then do;
tot.output(dataset:'totalinventory');
daily.output(dataset:'dailyinventory');
end;
run;
title 'Daily Inventory';
proc print data=dailyinventory;
run;
title 'Total Inventory';
proc print data=totalinventory;
format date date7.;
run;
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!