코딩의 효율성은 일반적으로 CPU 시간, 디스크 공간 또는 메모리 사용량으로 측정됩니다. SAS 프로그램은 많은 양의 데이터를 처리하는 데 사용될 가능성은 낮지만 유사한 처리가 필요한 일련의 시험에서 사용할 수 있도록 업데이트되고 조정될 가능성이 매우 높습니다. 프로그램이 5분 동안만 실행될 때 CPU 시간을 50% 절약해도 코딩 효율성에 큰 영향을 미치지 않습니다. 이번 게시글에서는 다양한 유형의 SAS 프로그램에서 효율적으로 코딩할 때 선택해야 하는 사항에 대해 설명합니다.
IF...THEN...ELSE 및 SELECT...WHEN 구문은 속도와 유지 관리 시간을 모두 향상시키기 위해 작성할 수 있는 구문입니다. 3가지의 방법으로 속도와 유지 관리 시간을 향상 시키는 문법을 알아보려 합니다.
아래의 3가지 예시는 A, B, C를 포함하는 입력 데이터 세트의 값을 새 변수로 값을 할당하는 여러 가지 방법입니다.
예시 1)
DATA new;
SET old;
IF oldvar = 'A' THEN newvar = 1;
IF oldvar = 'B' THEN newvar = 2;
IF oldvar = 'C' THEN newvar = 3;
RUN;
첫 번째 예시는 그다지 효율적인 코드는 아닙니다. 이유는 모든 IF 조건이 모든 레코드에 적용되기 때문입니다. 하지만, 작은 데이터셋에 위와 같은 코드를 적용할 경우 비효율적인지 인지하지 못할 수도 있습니다.
예시 2)
DATA new;
SET old;
IF oldvar = 'A' THEN newvar = 1;
ELSE IF oldvar = 'B' THEN newvar = 2;
ELSE IF oldvar = 'C' THEN newvar = 3;
RUN;
다음 코드는 IF 조건이 일치하는 조건까지만 적용되므로 더 효율적입니다. 하지만 이것도 작은 데이터셋에 적용할 경우 효율적인지 비효율적인지 인지하지 못할 수도 있습니다 . IF 조건을 정렬하여 가장 일반적으로 사용되는 값이 맨 위에 배치되도록 하면 속도를 더욱 향상시킬 수 있지만, 데이터가 이미 잘 알려져 있고 가장 일반적인 값이 매우 일반적인 경우가 아니라면 이 값은 유용하지 않을 수 있습니다.
예시 3)
DATA new;
SET old;
SELECT (oldvar);
WHEN ('A') newvar = 1;
WHEN ('B') newvar = 2;
WHEN ('C') newvar = 3;
OTHERWISE;
END;
RUN;
IF 조건을 정렬하여 가장 일반적으로 사용되는 값이 맨 위에 배치되도록 하면 속도를 더욱 향상시킬 수 있지만, 데이터가 이미 잘 알려져 있고 가장 일반적인 값이 매우 일반적인 경우가 아니라면 이 값은 유용하지 않을 수 있습니다. 또한, 작은 입력 데이터 세트의 경우 속도가 빨라진 것을 느끼지 못할 수 있습니다.
위와 같은 구문은 동일한 레이아웃을 가지기 때문에 유지 관리가 더 쉽습니다. 따라서 구문 오류가 발생할 위험을 줄이면서 줄을 insert 하거나 delete 할 수 있습니다. 그리고 OTHERWISE 절은 필수 구문으로 이전 조건이 충족되지 않은 경우 기본값을 포함할 수 있는 분명한 위치를 제공합니다.
다음 두개의 샘플 코드는 두 변수를 사용하여 세 개의 데이터 세트를 병합한 다음 결과 데이터 세트의 순서를 다른 변수로 변경합니다.
예시1)
PROC SORT DATA = a OUT = a1;
BY cat_b;
RUN;
PROC SORT DATA = b OUT = b1;
BY cat_b;
RUN;
DATA a1_b1;
MERGE a1 (IN = a) b1 (IN = b);
BY cat_b;
IF a AND b;
RUN;
PROC SORT DATA = a1_b1 OUT = a1_b11;
BY cat_c;
RUN;
PROC SORT DATA = c OUT = c1;
BY cat_c;
RUN;
DATA a1_b1_c1;
MERGE a1_b11 (IN = ab) c1 (IN = c);
BY cat_c;
IF ab AND c;
RUN;
PROC SORT DATA = a1_b1_c1;
BY cat_a cat_b cat_c;
RUN;
위의 코드는 Proc Sort 와 Data Step이 같이 있는 코드입니다. 코드는 처리에 관한 것은 효율적이지만 병합하기 전에 개별 데이터 세트를 정렬해야 하기 때문에 상당히 길고 복잡합니다.
예시2)
PROC SQL;
CREATE TABLE a_b_c AS
SELECT a.cat_a
,b.cat_b
,c.cat_c
,a.num_a1
,a.num_a2
,b.num_b1
,b.num_b2
,c.num_c1
,c.num_c2
FROM a
,b
,c
WHERE a.cat_b = b.cat_b
AND a.cat_c = c.cat_c
ORDER BY
a.cat_a
,b.cat_b
,c.cat_c
;
QUIT;
위의 예제는 PROC SQL 로 one step 부터 final sort 까지 모두 나와있는 코드입니다. 입력 데이터 세트의 크기가 작거나 중간인 경우 이 코드와 이전 코드에서 사용하는 CPU 시간에는 거의 차이가 없지만 매우 큰 입력 데이터 세트는 PROC SQL을 사용할 때 처리 속도가 느려질 수 있습니다. 단점은 두 개 이상의 데이터 세트를 겹치는 변수로 결합할 때 출력 데이터 세트에 포함될 모든 변수를 나열해야 한다는 것입니다.
장점은 유지보수가 쉽다는 것입니다.
단순 병합 코딩은 DATA 또는 PROC SQL 단계를 사용하여 매우 간단하지만 일대일 일치가 아닌 값 범위를 기반으로 테이블을 조인할 때 PROC SQL이 좋은 선택이 될 수 있습니다.
아래의 두개의 예시 코드는 서로 28일 이내의 레코드 간의 가장 큰 차이를 계산합니다.
예시1)
PROC SORT DATA = old OUT = temp;
BY cat;
RUN;
DATA temp;
SET temp;
BY cat;
RETAIN order;
7
IF FIRST.cat THEN order = 1;
ELSE order + 1;
RUN;
PROC TRANSPOSE DATA = temp OUT = num PREFIX = num;
BY cat;
VAR num;
ID order;
RUN;
PROC TRANSPOSE DATA = temp OUT = val PREFIX = val;
BY cat;
VAR val;
ID order;
RUN;
DATA all (DROP = _:);
MERGE num val;
BY cat;
RUN;
DATA new (KEEP = cat maxval);
SET all;
BY cat;
ARRAY num num:;
ARRAY val val:;
ARRAY test test1-test50;
maxval = .;
reset = 1;
DO i = 1 TO DIM(num);
DO j = i+1 TO DIM(num);
IF num(j) - num(i) LE 28
AND ROUND(val(j) – val(i), .0001) GT maxval
THEN maxval = ROUND(val(j) – val(i), .0001);
END;
END;
IF LAST.cat THEN OUTPUT;
RUN;
이것은 PROC SORT, PROC TRANSPOSE 및 DATA 단계의 조합으로, 처리에 관한 한 효율적일 수 있지만 모든 개별 레코드 쌍을 범주화하기 위해 배열을 사용해야 하기 때문에 상당히 길고 복잡합니다.
예시2)
PROC SQL;
CREATE TABLE temp AS
SELECT b1.cat
,b1.num
,MAX(b2.val - b1.val) AS maxval
FROM old b1
LEFT JOIN
old b2
ON b1.cat = b2.cat
AND (b2.num - b1.num) BETWEEN 1 AND 28
GROUP BY
b1.cat
,b1.num
;
QUIT;
PROC SQL;
CREATE TABLE new AS
SELECT cat
,MAX(maxval) AS maxval
FROM temp
GROUP BY
cat
;
QUIT;
이것은 최종 정렬(final sort)을 포함하여 한 단계에서 모든 작업을 수행하는 단일 PROC SQL 단계입니다. 입력 데이터 세트의 크기가 작거나 중간인 경우 이 코드와 이전 코드에서 사용하는 CPU 시간에는 거의 차이가 없지만 매우 큰 입력 데이터 세트는 PROC SQL을 사용할 때 처리 속도가 느려질 수 있습니다.
하지만 이 예제 역시 유지보수하기가 쉽다는 장잠이 있습니다.
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and save with the early bird rate—just $795!