CAFE

SAS_게시판

LAG함수의 작동원리에 대해..

작성자최홍규|작성시간04.04.06|조회수963 목록 댓글 0
/*
LAG함수가 실행될 때 어떤 일이 일어나는가에 대해 다소 오해의 소지가 있어, 엉터리 번역이지만 SAS OnlineDoc에서 LAG함수에 대한 부분을 아래에 번역해 봤습니다.

----------------------
lag1, lag2, ... lag100 등의 Lag 함수는 큐(queue)로부터 값을 내보내줍니다. lag1은 lag로도 쓸수 있습니다. LAGn 함수는 큐에 값을 저장하고, 앞선 작업에서 큐에 저장되었던 값을 내보내줍니다. LAGn함수가 프로그램안에서 출현할 때마다 각각 그 자신의 큐값을 생성합니다.

LAGn에 대한 큐는 n개의 미싱값으로 초기화됩니다. 여기서 n은 큐의 길이입니다.(예를들어 LAG2 큐는 두개의 미싱값으로 초기화됩니다.) LAGn이 실행될 때, 맨위의 큐값을 제거하면서 내보내주고, 나머지 값들이 하나씩 위로 이동하며, 인수의 새로운 값이 맨 아래의 큐에 위치하게 됩니다. 따라서 LAGn은 최초로 n번 실행할 때까지는 미싱값을 내보내주고, 그 이후에야 시차된 값을 내보내주기 시작합니다.

주의 : 맨밑의 큐에 저장하고 맨위의 큐로부터 값을 내보내는 행위는 반드시 함수가 실행될 때에만 일어납니다. 조건적으로 실행되는 LAGn함수는 조건이 만족되는 관측치에 대해서만 값을 저장하고 내보낼 것입니다. 다음의 Storing Every Other Lagged Value 샘플을 참조하십시요.

만약에 LAGn함수의 인수가 배열명이라면, 배열의 각 변수들에 대한 큐가 분리되어 유지됩니다.


The LAG functions, LAG1, LAG2, . . . , LAG100 return values from a queue. LAG1 can also be written as LAG. A LAGn function stores a value in a queue and returns a value stored previously in that queue. Each occurrence of a LAGn function in a program generates its own queue of values.

The queue for LAGn is initialized with n missing values, where n is the length of the queue (for example, a LAG2 queue is initialized with two missing values). When LAGn is executed, the value at the top of the queue is removed and returned, the remaining values are shifted upwards, and the new value of the argument is placed at the bottom of the queue. Hence, missing values are returned for the first n executions of LAGn, after which the lagged values of the argument begin to appear.

Note: Storing values at the bottom of the queue and returning values from the top of the queue occurs only when the function is executed. A LAGn function that is executed conditionally will store and return values only from the observations for which the condition is satisfied. See Storing Every Other Lagged Value .

If the argument of LAGn is an array name, a separate queue is maintained for each variable in the array.


아래의 예는 프로그램에 조건로직이 사용된 것의 여부에 따라 출력의 차이가 나는 것을 보여줍니다. LAG함수는 자신이 호출될 때에만 큐에 값을 저장하기 때문에 정확한 답을 얻기 위해서는 조건과 무관한 곳에서 LAG함수를 호출해야 합니다.

This example shows the difference in output when you use conditional and unconditional logic in your program. Because the LAG function stores values on the queue only when it is called, you must call LAG unconditionally to get the correct answers.
*/

options pagesize=25 linesize=64 nodate pageno=1;

title "Store Every Other Lagged Value";

data test;
input x @@;
if mod(x,2)=0 then a=lag(x);
b=lag(x);
if mod(x,2)=0 then c=b;
label a="(WRONG) a" c="(RIGHT) c";
datalines;
1 2 3 4 5 6 7 8
;

proc print label data=test;
run;


/*
결국, LAG함수는 실행될 때마다 앞의 레코드를 읽어서 그 값을 내보내는 것이 아니라, 레코드를 읽으면서 다음에 사용할 것에 대비해서 메모리에 미리 저장해 놓는 방식을 취하고 있기 때문에 I/O에 따른 속도저하문제는 크지 않아 보입니다.

잘 모르지만, 제 생각에 "현장"에서 LAG함수를 잘 사용하지 않는다면, 그 이유는 속도상의 문제라기 보다는, 많은 작업을 하다보면 위의 예처럼 조건절에서 LAG함수가 실수로 사용될 수 있기 때문이 아닐까요?
이렇게 생각하는 이유는...
시차가 긴 Lag를 사용하면 그만큼의 메모리를 큐에 잡아야 하기 때문에 속도가 느려질 수 있겠습니다만, 시차가 긴 LAG는 retain만으로는 해결하기 어렵기 때문에 다소 복잡한 다른 방법(예를들어 firstobs를 이용한 엇갈린 merge)을 써야 해결이 가능하기 때문에 속도면에서 그리 나아보이지 않고,
짧은 시차에서 retain을 이용한다고 하더라도 어짜피 if문(속도때문에 되도록이면 쓰지 않는 것이 좋다는 이야기를 많이 하지요.)을 쓰거나 lag함수를 대신하기 위해 추가적으로 필요한 구문이 늘어나기 때문에 속도면에서 결코 빠르다고 할 수 없을 것이기 때문입니다.

한편, retain을 이용해서 lag기능을 구현하는 것은, 다음과 같이 하면 조금 더 간략히 될 수 있을 것 같네요.
*/

data abc_1 ;
set abc ;
retain share_T_1 0;
output;
share_T_1 = share_T ;
run ;
proc print;run;
다음검색
현재 게시글 추가 기능 열기
맨위로

카페 검색

카페 검색어 입력폼