반응형

[SAS] 변수 계산 (비교 연산) - DATA, SET, GE, LE, NE, IN, MIN, MAX

조건에 따라 변수를 바꾸고 싶을 때가 있다. 예를 들어, 인구를 1) AST 40 이상, 2) AST 20 이상 40 미만, 3) AST 20 미만으로 나누고 싶을 수 있다. 이런 경우에 사용하는 비교 연산에 대해 알아보고자 한다. 내용은 다음과 같다.

 

1) >, <, >=, <=, =, ^=

2) MAX

3) MIN

4) IN, NOT IN

 

*실습용 데이터는 아래 링크를 클릭하면 다운로드할 수 있습니다.

2022.08.04 - [공지사항 및 소개] - 분석용 데이터 (update 22.10.06)

 

분석용 데이터 (update 22.10.06)

2022년 08월 29일 버전입니다. 변수는 계속하여 추가될 예정입니다. 다음 카테고리에 있는 글에서 이용된 데이터입니다. - 기술 통계 - 통계 프로그램 사용 방법 1) 엑셀 파일 2) CSV 파일 3) 코드북

medistat.tistory.com

시작하기 위해 라이브러리를 만들고, 파일을 불러온다.

라이브러리 만드는 방법: 2022.08.05 - [통계 프로그램 사용 방법/SAS] - [SAS] 라이브러리 만들기 - LIBNAME

파일 불러오는 방법: 2022.08.05 - [통계 프로그램 사용 방법/SAS] - [SAS] 데이터 불러오기 및 저장하기 - PROC IMPORT, PROC EXPORT

 

*라이브러리 지정하기;
LIBNAME hong "C:/Users/User/Documents/Tistory_blog";

*파일 불러오기;
PROC IMPORT
DATAFILE="C:\Users\user\Documents\Tistory_blog\Data.xlsx"
DBMS=EXCEL
OUT=hong.df
REPLACE;
RUN;

 

상황: 전체 인구를 1) AST 40 이상, 2) AST 20 이상 40 미만, 3) AST 20 미만으로 나누고 싶을 때

 AST는 연속 변수로 코딩되어 있음을 코드북에서 확인할 수 있다. 우리는 ALT_S3이라는 변수를 새로 만들어 다음과 같이 코딩되기를 바란다.

AST_S2 0 1 2
AST 40 이상 20 이상 40 미만 20 미만

 이를 실행하는 방법은 여러 가지가 있는데, 코드를 하나씩 살펴보면 다음과 같다. 변수를 바꿀 때 쓰는 DATA-SET구문에 대한 설명은 다음 링크를 확인하길 바란다. 2022.10.06 - [통계 프로그램 사용 방법/SAS] - [SAS] 변수 계산 (산술 연산) - DATA, SET

 

가장 기초적인 방법 (하지만 잘못된 코드다)

DATA hong.df_new;
SET hong.df;

*AST를 기준으로 셋으로 나누기;
IF AST>=40 THEN AST_S3=0;
	ELSE IF AST<40 AND AST>=20 THEN AST_S3=1;
	ELSE IF AST<20 THEN AST_S3=2;

RUN;

조건문 (IF, ELSE IF)와 AND 연산자에 대한 내용은 다음 링크를 확인하길 바란다. 2022.10.06 - [통계 프로그램 사용 방법/SAS] - [SAS] 변수 계산 (논리 연산) - DATA, SET, IF, ELSE IF, ELSE, AND, OR

 

IF AST>=40 THEN AST_S3=0; : AST가 40 이상이면 AST_S3의 값은 0을 부여한다.
     ELSE IF AST<40 AND AST>=20 THEN AST_S3=1; : AST가 40 미만이면서 20 이상이면 AST_S3의 값은 1을 부여한다.
     ELSE IF AST<20 THEN AST_S3=2; : AST가 20 미만이면 AST_S3의 값은 2를 부여한다.

 

 

문제점: 결측치

얼핏 보면 이상할 것이 없어 보이는 이 코드가 왜 잘못되었다고 하는 것일까?

문제는 결측치다.

 

다음 코드로 AST의 분포를 확인해보면 8개의 결측치가 있음을 알 수 있다. PROC MEANS에 관한 내용은 다음 링크에서 확인할 수 있다. 2022.09.23 - [기술 통계/SAS] - [SAS] 기술 통계 (평균, 표준편차, 표준오차, 최댓값, 최솟값, 중위수, 분위수 등) - PROC UNIVARIATE, PROC MEANS

 

결측치 확인 코드

PROC MEANS DATA=hong.df NMISS; 
VAR AST; 
RUN;

 

결과

 

결측치 확인 코드

그런데, AST_S3에는 결측치가 없음을 다음 코드에서 확인할 수 있다.

PROC MEANS DATA=hong.df_new NMISS; 
VAR AST_S3; 
RUN;

 

결과

 

결측치 향방 확인하는 코드

그렇다면 결측치는 모두 어디에 가있는 것일까? SAS에서는 결측치를 "."으로 표현한다. 결측치를 1로, 결측치가 아닌 경우를 0으로 코딩한 변수 AST_MISS를 만들고, AST_S3과의 분할표를 만들어 확인해보자. 분할표에 대한 내용은 다음 링크를 확인하길 바란다. 2022.08.18 - [기술 통계/SAS] - [SAS] 도수분포표 (Frequency table), 분할표 (Contingency table) 만들기 - PROC FREQ

DATA hong.df_new;
SET hong.df;

*AST를 기준으로 셋으로 나누기;
IF AST>=40 THEN AST_S3=0;
	ELSE IF AST<40 AND AST>=20 THEN AST_S3=1;
	ELSE IF AST<20 THEN AST_S3=2;

*AST 결측 여부 확인 변수 만들기;
IF AST=. THEN AST_MISS=1;
	ELSE AST_MISS=0;

RUN;

*분할표 만들기;
PROC FREQ DATA=hong.df_new; 
TABLE AST_S3 * AST_MISS / NOROW NOCOL NOPERCENT; 
RUN;

 

결과

결측값 8개에 AST_S3의 값으로 2가 부여되어 있다. 이는 명백히 "ELSE IF AST<20 THEN AST_S3=2;" 코드에서 기인한 문제다. 즉, SAS는 AST의 결측치에 대해 "AST<20"가 옳다고 (TRUE) 본 것이다. 이를 해결하기 위해서는 코드를 다음과 같이 작성해야 한다. (두 가지 방법 모두 옳다.)

 

코드

*방법 1: "AST>=0"을 추가하기;
DATA hong.df_new;
SET hong.df;

*AST를 기준으로 셋으로 나누기;
IF AST>=40 THEN AST_S3=0;
	ELSE IF AST<40 AND AST>=20 THEN AST_S3=1;
	ELSE IF AST<20 AND AST>=0 THEN AST_S3=2;

RUN;

*방법 2: "AST^=."을 추가하기;
DATA hong.df_new;
SET hong.df;

*AST를 기준으로 셋으로 나누기;
IF AST>=40 THEN AST_S3=0;
	ELSE IF AST<40 AND AST>=20 THEN AST_S3=1;
	ELSE IF AST<20 AND AST^=. THEN AST_S3=2;

RUN;

방법 1은 "AST>=0"을 추가하여 결측치는 해당 조건을 만족하지 않게 조정한 것이다.

방법 2는 "AST^=."을 추가하였다.  "^="는 같지 않다는 뜻이므로, AST가 결측이 아니라는 뜻을 의미한다. 

 

각 방법에는 세 가지 조건이 존재한다. 방법 2를 기준으로 한다면 

조건 1: AST>=40

조건 2: AST<40 AND AST>=20

조건 3: AST<20 AND AST^=.

인데, 결측치는 세 조건 모두 부합하지 않았다. 따라서 결측치는 THEN 뒤로 넘어가 본 적이 없다. THEN 뒤에서는 AST_S3의 값을 배정받으므로 결측치는 AST_S3값을 배정받아본 적이 없는 것이다. 따라서 AST가 결측인 경우에는 AST_S3 또한 결측치가 된다. 

 

>, <, >=, <=등은 실제 코딩을 하다 보면 매우 입력하기 귀찮아지는데, 다음과 같은 영문 부호로 이를 대체할 수도 있다.

연산 부호 영문 부호
= EQ 같다
~=
^=
NE 같지 않다
> GT 크다
< LT 작다
>= GE 크거나 같다
<= LE 작거나 같다
^>
~>
NG 크지 않다
^<
~<
NL 작지 않다

 

 

 

MAX, MIN

최댓값을 구하는 MAX, 최솟값을 구하는 MIN 함수다. 간 기능 지표 (ALT, AST) 중 큰 것을 고른 LIVER_MAX변수와, 작은 것을 고른 LIVER_MIN변수를 새로 만든다고 하자. 그럼 코드는 다음과 같다.

DATA hong.df_new;
SET hong.df;

*최댓값;
LIVER_MAX=MAX(AST, ALT);
*최솟값;
LIVER_MIN=MIN(AST, ALT);
RUN;

LIVER_MAX=MAX(AST, ALT); : AST와 ALT 중 더 큰 값을 LIVER_MAX에 저장하라.
LIVER_MIN=MIN(AST, ALT); : AST와 ALT 중 더 작은 값을 LIVER_MIN에 저장하라.

 

여기에서는 결측치를 어떻게 처리할까?

AST, ALT 둘 중 하나가 결측치인 경우 MIN, MAX모두 결측치가 아닌 값을 반환한다. 

만약, AST, ALT 둘 다 결측치인 경우 MIN, MAX은 결측치를 반환한다.

 

 

상황: 전체 인구를 1) 과거 흡연자, 2) 비흡연자 및 현재 흡연자로 나누고 싶을 때

 이전 포스팅에서 이런 경우 조건문(IF)을 이용하여 나눌 수 있다고 하였다. 2022.10.06 - [통계 프로그램 사용 방법/SAS] - [SAS] 변수 계산 (논리 연산) - DATA, SET, IF, ELSE IF, ELSE, AND, OR

위 글에서도 간단하게 설명했지만 IN이라는 연산자를 이용하면 매우 빠르게 할 수 있다.

 

IN은 다음과 같이 사용할 수 있다. 

 

1) IN (0 2) : 0 혹은 2에 해당하는 경우

2) IN (0:2) : 0 이상 2 이하 정수에 해당하는 경우

 

IN을 NOT IN으로 바꾸면 "해당하지 않는 경우"로 바뀐다.

*결측치가 없음을 확인하기;
PROC MEANS DATA=hong.df NMISS;
VAR SMOK;
RUN;

DATA hong.df_new;
SET hong.df;

*과거 흡연자 // 현재 흡연자 + 비흡연자로 나누기;
IF SMOK IN (0 2) THEN SMOK_S2=0;
	ELSE SMOK_S2=1;

RUN;

IF SMOK IN (0 2) THEN SMOK_S2=0; : SMOK가 0 혹은 2인 경우 SMOK_S2에는 0을 부여한다.
ELSE SMOK_S2=1; : 그 외에는 SMOK_S2에 1을 부여한다.

 

SAS 변수 계산 (비교 연산) 정복 완료!

작성일: 2022.10.06.

최종 수정일: 2022.10.06.

이용 프로그램: SAS v9.4

운영체제: Windows 10

반응형

+ Recent posts