DB의 태생적인 오류 인지가 있을 수 있다는 것을 항상 생각하고 있어야 함
대용량 데이터이므로 효율적인 코드로 한번에 분석한다고 생각하지 말기
가설 : 당뇨(EXP)의 유병이 고혈압 발생 위험을 높일 것이다
study population
-inclusion: 2008년 이상
-exclusion: 2006년 전에 고혈압이 있는 대상자, 2008.12.31 이전 사망자 제외
exposure
2008년 1월 1일 ~ 2008년 12월 31일 사이에 의과 진료 기록에 당뇨('E11','E12','E13','E14') 상병이 있고 대상자-명세서(t20) 연계
LIBNAME A '경로'
PROC SQL;
CREATE TABLE STEP0 AS
SELECT DISTINCT RN_INDI
#자격 DB, 2008년도 UNIQUE 값만 뽑음
FROM A.Nsc2_edu_bnc
WHERE STD_YYYY='2008';
QUIT;
step0: 2008년에 unique한 id만 추출
PROC SQL;
CREATE TABLE HYPERT_Y AS
SELECT DISTINCT RN_INDI
FROM A.Nsc2_edu_m20 /*병원(의과) 명세서*/
WHERE SUBSTR(SICK_SYM1, 1, 3) IN ('I10','I11','I12','I13','I15')
AND MDCARE_STRT_DT BETWEEN '20060101' AND '20081231';
CREATE TABLE NON_HYPERT AS
SELECT RN_INDI
FROM STEP0
WHERE RN_INDI NOT IN (SELECT RN_INDI FROM HYPERT_Y);
QUIT;
select 유니크한 사람만 뽑는다 -> 그 때 병원을 가서 고혈압 판정을 받은것임
where 기간 동안에 고혈압이 없었던 사람만 남는다
PROC SQL;
CREATE TABLE DTH_BEFORE_2008 AS
SELECT DISTINCT RN_INDI, DTH_YYYY
FROM A.Nsc2_edu_bnd /*출생 및 사망자료*/
WHERE DTH_YYYY BETWEEN '2006' AND '2008';
CREATE TABLE STEP1 AS
SELECT RN_INDI
FROM NON_HYPERT
WHERE RN_INDI NOT IN (SELECT RN_INDI FROM DTH_BEFORE_2008);
QUIT;
이렇게 하면 step1에 study population이 만들어짐
대상자-명세서(T20) 연계;
PROC SQL;
CREATE TABLE ID_T20_MERGED AS
SELECT A.*, B.*
FROM STEP1 AS A LEFT JOIN
A.Nsc2_edu_m20 AS B
ON A.RN_INDI=B.RN_INDI
ORDER BY A.RN_INDI, MDCARE_STRT_DT;
QUIT;
PROC SQL;
CREATE TABLE STEP2 AS
SELECT *
FROM ID_T20_MERGED
WHERE MDCARE_STRT_DT BETWEEN '20080101' AND '20081231'
AND SUBSTR(SICK_SYM1, 1, 3) IN ('E11', 'E12', 'E13', 'E14');
QUIT;
step2: 1년 동안 당뇨인 것만 걸러낸다
#대상자-명세서-세부 진료내역(T30) 연계;
PROC SQL;
CREATE TABLE MED_PRESC AS
SELECT DISTINCT A.*, B.*
FROM STEP2 AS A INNER JOIN
A.Nsc2_edu_m30 AS B /*병원(의과)에서 원내처방*/
#이걸 key로 연결함
ON A.RN_INDI=B.RN_INDI
AND A.RN_KEY=B.RN_KEY
WHERE B.MCARE_DIV_CD IN ('165702ATB', '191502ATB', '191502ATR','249002ATB', '165704ATB', '170101BIJ', '474300ATB', '191504ATB', '191501ATB', '431901ATB')
#당뇨약 처방 건만 남긴다
ORDER BY A.RN_INDI, MDCARE_STRT_DT;
QUIT;
PROC SQL;
CREATE TABLE PHARM_PRESC AS
SELECT DISTINCT A.*, B.*
FROM STEP2 AS A INNER JOIN
A.Nsc2_edu_m60 AS B
#병원(의과)에서 원외처방(약국에서 구매)
ON A.RN_INDI=B.RN_INDI
AND A.RN_KEY=B.RN_KEY
WHERE B.GNL_NM_CD IN ('165702ATB', '191502ATB', '191502ATR', '249002ATB', '165704ATB'
, '170101BIJ', '474300ATB', '191504ATB', '191501ATB', '431901ATB') /*당뇨약 처방 건만*/
ORDER BY A.RN_INDI, MDCARE_STRT_DT;
QUIT;
med : 30에서 약을 먹은 사람(의과안에서 먹은 사람), pham: 약국에서 처방받아서 먹은 사람 -> 합치면 다 나온다
#당뇨약 처방건;
DATA DIA_PRESC;
SET MED_PRESC PHARM_PRESC(RENAME=(GNL_NM_CD=MCARE_DIV_CD));
#두 테이블 위아래로 합치기
KEEP RN_INDI RN_KEY MDCARE_STRT_DT MCARE_DIV_CD;
RUN;
#최종 당뇨 유병자;
PROC SORT DATA=DIA_PRESC OUT=STEP3(KEEP=RN_INDI) NODUPKEY; BY RN_INDI; RUN;
#dupli 지우기, unique 아이디만 남기기
#정보 병합(당뇨 유병 여부);
PROC SQL;
CREATE TABLE DATA_E AS
SELECT A.*
, CASE WHEN B.RN_INDI IS NULL THEN 0 ELSE 1
#붙였을 때 병이 있으면 1 아니면 0으로 고쳐준다
END AS DIABETES_YN
FROM STEP1 AS A LEFT JOIN
STEP3 AS B
ON A.RN_INDI=B.RN_INDI;
QUIT;
STEP3 : 당뇨약도 먹고 당뇨 처방도 받은 사람들
-> 전처리 DATA_E
1) 2009년 1월 1일 ~ 2012년 12월 31일 사이에 고혈압 주상병 진단 코드 있는 대상자
2) 상병코드: 'I10', 'I11','I12','I13','I15'
*대상자의 2009년 1월 1일 ~ 2012년 12월 31일 사이 병원(의과) 방문 고혈압 진료기록;
PROC SQL;
CREATE TABLE HYPERT_HISTORY AS
SELECT *
FROM ID_T20_MERGED /*앞에서 대상자-명세서(T20) 연계한 테이블*/
WHERE MDCARE_STRT_DT BETWEEN '20090101' AND '20121231'
AND SUBSTR(SICK_SYM1, 1, 3) IN ('I10', 'I11','I12','I13','I15');
QUIT;
*고혈압 진단 가장 빠른 날짜;
PROC SORT DATA=HYPERT_HISTORY; BY RN_INDI MDCARE_STRT_DT; RUN;
PROC SORT DATA=HYPERT_HISTORY OUT=STEP4 NODUPKEY; BY RN_INDI; RUN;
*정보 병합(고혈압 유병 여부, 고혈압 최초 병원방문 날짜);
PROC SQL;
CREATE TABLE DATA_EO AS
SELECT A.*
, CASE WHEN B.RN_INDI IS NULL THEN 0 ELSE 1
END AS HYPERT_YN
, B.MDCARE_STRT_DT AS OUTCOME_DT
FROM DATA_E AS A LEFT JOIN
STEP4 AS B
ON A.RN_INDI=B.RN_INDI;
QUIT;
*자격 정보 병합;
PROC SQL;
CREATE TABLE DATA_EOC AS
SELECT DISTINCT
A.*
, B.SEX /*성별 */
, B.SIDO /*지역코드*/
, B.CTRB_Q10 /*소득분위*/
, B.DSB_TYPE_CD /*장애여부*/
FROM DATA_EO AS A LEFT JOIN
A.Nsc2_edu_bnc AS B
ON A.RN_INDI=B.RN_INDI
WHERE B.STD_YYYY='2008';
QUIT;
Cox regression(Time-fixed)
Time: 2009년 1월 1일부터 고혈압 발병까지의 기간
Follow-up period: 2009.01.01 ~ 2012.12.31 (총 4년간)
Censoring: 사망, 추적종료
*사망 정보 병합;
PROC SQL;
CREATE TABLE DATA_EOCD AS
SELECT DISTINCT
A.*
, B.DTH_YYYY /*사망년도 */
FROM DATA_EOC AS A LEFT JOIN
A.Nsc2_edu_bnd AS B
ON A.RN_INDI=B.RN_INDI;
QUIT;
*EVENT, TIME 설정;
DATA DATA_EOCDT;
SET DATA_EOCD;
/*TIME 계산용 변수*/
START_DT='20090101'; /*Follow-up 시작 시점*/
END_DT='20121231'; /*Follow-up 종료 시점*/
IF DTH_YYYY ^= '' THEN DTH_DT=COMPRESS(DTH_YYYY||'1231');
/*(유의) 사망 시점(사망일자 제공이 안 되어 연말로 임의로 설정함. 실제 분석에서는 정확한 사망일자 사용)*/
/*OUTCOME EVENT 변수*/
IF HYPERT_YN =1 THEN EVENT=1; ELSE EVENT=0;
/*TIME 변수*/
*EVENT 있으면 EVENT 발생시점까지;
IF OUTCOME_DT^='' THEN TIME=INTCK("DAY",
INPUT(START_DT,YYMMDD10.),INPUT(OUTCOME_DT,YYMMDD10.) );
*EVENT 없고 2012년 이전 사망기록 있으면 사망시점까지;
ELSE IF OUTCOME_DT ='' AND (DTH_DT ^='' AND DTH_YYYY <= 2012) THEN
TIME=INTCK("DAY", INPUT(START_DT,YYMMDD10.),INPUT(DTH_DT,YYMMDD10.) );
*둘 다 없으면 추적종료시점까지;
ELSE TIME=INTCK("DAY", INPUT(START_DT,YYMMDD10.),INPUT(END_DT,YYMMDD10.) );
RUN;
/*최종 분석용 변수 세팅*/
DATA DATA_FINAL;
SET DATA_EOCDT;
/*성별은 SEX 변수 그대로 사용가능*/
/*지역변수*/
/*11 : 서울특별시 26 : 부산광역시 27 : 대구광역시 28 : 인천광역시 29 : 광주광역시 30 : 대전광역시 31 : 울산광역시*/
IF SIDO IN ('11', '26', '27', '28', '29', '30', '31') THEN CAPITAL_REGION=1;
ELSE CAPITAL_REGION=0;
/*소득변수*/
/*(유의) 교육 자료에서는 결측 제외 시 SAMPLE 수 부족으로 소득결측을 임의로 0으로 설정함.
실제 분석에서는 결측은 제외 또는 다른 정보로 보완 필요*/
IF CTRB_Q10=. THEN CTRB_Q10=0;
IF CTRB_Q10 <= 5 THEN INCOME_GROUP=0; /*5분위 이하*/
IF CTRB_Q10 > 5 THEN INCOME_GROUP=1; /*6분위 이상*/
/* 장애여부 변수*/
IF DSB_TYPE_CD='1' THEN DISAB=1;
ELSE DISAB=0;
RUN;
*Cox regression;
/*공변량 무보정*/
PROC PHREG DATA=DATA_FINAL;
CLASS DIABETES_YN(REF='0') ;
MODEL TIME*EVENT(0)=DIABETES_YN / RL COVB;
RUN;
/*공변량 보정*/
PROC PHREG DATA=DATA_FINAL;
CLASS DIABETES_YN(REF='0') SEX(REF='1') CAPITAL_REGION(REF='0')
INCOME_GROUP(REF='0') DISAB(REF='0');
MODEL TIME*EVENT(0)=DIABETES_YN SEX CAPITAL_REGION
INCOME_GROUP DISAB / RL COVB;
RUN;