코드
- function
| 함수 | 변환 전 | 변환 후 |
|---|---|---|
| Input | 문자형 | 숫자형 |
| Put | 숫자형 | 문자형 |
PROC FORMAT
proc format;
value agefmt; /* format name */
1 = 'Young' /* 값 = 라벨 */
2 = 'Old';
run;
proc format;
value agegrp;
low - <65 = 'Under 65'
65 - high = '65+';
run;
적용
proc freq data = data1;
tables age;
format age agegrp.;
run;
proc format;
value sexfmt; /* format name */
'M' = 'Male' /* 값 = 라벨 */
'F' = 'Female';
run;
적용
proc freq data = data1;
tables sex;
format sex $sexfmt.;
run;
숫자형과 달리 문자형 포맷에는 $ 기호 존재
PROC SORT
proc sort data=data1;
by usubjid;
run;
- by group
data want;
set data;
by usubjid visit;
if first.usubjid;
/* if last.usubjid;*/
run;
- nodupkey
proc sort data = data nodupkey;
by usubjid;
run;
PROC SORT-> Maximum
proc sort data = data;
by usubjid descending aval;
run;
data max;
set data1;
by usubjid;
if first.usubjid;
run;
- merge
data data1;
merge a(in=inA where flag='Y') b(in=inB);
by key;
if inA and inB; /* inner join */
/* if inA; left join */
/* if inB; right join */
run;
PROC TRANSPOSE
long data -> wide data / wide data -> long data
proc sort data = data1; by usubjid; run;
proc transpose data=data1 out=data2;
by usubjid; /* 그룹 변수 */
id visit; /* 열의 이름이 될 변수 */
var aval; /* 값 변수*/
run;
data1
| USUBJID | VISIT | AVAL |
|---|---|---|
| 01 | Week1 | 10 |
| 01 | Week2 | 15 |
| 01 | Week3 | 20 |
data2
| USUBJID | Week1 | Week2 | Week3 |
|---|---|---|---|
| 01 | 10 | 15 | 20 |
PROC REPORT
proc report data = data1 nowd; /* data1 데이터를 사용해서 report 생성, nowd = interactive 창 없이 바로 실행 */
column trtp age; /* 출력할 컬럼 순서 지정: trtp 먼저, age 다음 */
define trtp / group; /* trtp를 그룹 변수로 설정 → 같은 값끼리 묶어서 한 줄로 요약 */
define age / analysis mean; /* age를 분석 변수로 설정 → 각 trtp 그룹별로 평균(mean) 계산 */
run; /* 프로시저 실행 */
proc report data=data1 nowd;
column trtp sex age height weight;
define trtp / group "Treatment"; /* trtp 기준으로 그룹화: 치료군별 한 줄씩 요약 */
define sex / group "Sex"; /* trtp 안에서 sex별로 한 번 더 그룹화 */
define age / analysis mean "Mean Age"; /* 각 trtp-sex 그룹별 age 평균 계산 */
define height / analysis mean "Mean Height"; /* 각 trtp-sex 그룹별 height 평균 계산 */
define weight / analysis mean "Mean Weight"; /* 각 trtp-sex 그룹별 weight 평균 계산 */
break after trtp / summarize; /* 각 trtp 그룹이 끝날 때 소계 행 생성 */
rbreak after / summarize; /* 전체 마지막에 전체 요약 행 생성 */
compute after trtp; /* trtp별 소계 행에 표시할 내용 지정 */
sex = "Subtotal"; /* 소계 행의 sex 칸에 Subtotal 표시 */
endcomp;
compute after; /* 전체 요약 행에 표시할 내용 지정 */
trtp = "Total"; /* 전체 요약 행의 trtp 칸에 Total 표시 */
endcomp;
run;
PROC IMPORT
proc import /* 외부 파일 → SAS로 불러오는 프로시저 */
datafile="&Path\data.xlsx" /* 불러올 파일 경로 (매크로 변수 사용) */
/* 예: C:\project\data.xlsx */
dbms=xlsx /* 파일 형식 지정 (Excel .xlsx) */
replace /* 같은 이름의 dataset 있으면 덮어쓰기 */
out=data1; /* 결과를 data1으로 저장 */
sheet="sheet1"; /* Excel의 특정 시트 선택 */
run;
PROC MEANS
proc means data=advs n mean std median min max;
var aval;
output out=stat
n=n
mean=mean
std=std;
run;
proc means data = data1 nway;
class trtp;
var aval;
output out=summary mean=;
run;
-> mean= 의미: sas의 기본 이름 쓰라는 명령
-> nway 가장 하위그룹의 통계량만 출력하도록 제한
ttest
one-sample ttest
proc ttest data=advs h0=0;
var aval;
run;
- two-sample ttest
proc ttest data=advs;
class trta;
var aval;
run;
- paired ttest
proc ttest data=advs;
paired base*week4;
run;
- Wilcoxon
proc npar1way data=advs wilcoxon;
class trta;
var aval;
run;
- ANOVA
proc anova data=advs;
class trta;
model aval = trta;
run;
fixed, random effect
proc glm data=advs;
class trta;
model aval = trta;
run;
모두 fixed
proc mixed data = data1;
class trta;
model aval = trta;
run;
- Kruskal-Wallis
proc npar1way data=advs;
class trta;
var aval;
run;
- chi square
proc freq data=adae;
tables trta*aeflag / chisq;
run;
- Fisher’s exact Test
proc freq data=adae;
tables trta*aeflag / fisher;
run;
BE guidance
2 by 2
proc mixed data=&data ; /* &data 데이터셋으로 mixed model 실행 */
class TRTA(ref="&ref") /* 처리군 변수. &ref를 기준군(reference)으로 설정 */
USUBJID /* 대상자 ID */
APERIOD /* period 변수 */
TRTSEQA; /* treatment sequence 변수 */
model ¶ = TRTSEQA APERIOD TRTA; /* 종속변수 ¶를 sequence, period, treatment로 설명 */
/* 보통 ¶는 log-transformed PK parameter일 수 있음 */
random USUBJID(TRTSEQA); /* sequence 내 subject를 random effect로 지정 */
/* 같은 sequence 안의 대상자 간 변동 고려 */
estimate "&TRT2header/&TRT1header" /* treatment contrast 이름 */
TRTA 1 -1 /* TRTA 두 수준 간 차이 추정 */
/ cl alpha=0.1; /* 신뢰구간 출력, alpha=0.1 → 90% CI */
lsmeans TRTA; /* treatment별 least squares mean 산출 */
run;
2 by 4
Method A - PROC GLM (Recommended)
proc glm data=replicate; /* replicate design dataset 사용 */
class formulation subject period sequence; /* 범주형 변수 선언 */
/* formulation = T/R */
/* subject = 대상자 */
/* period = 투여 period */
/* sequence = 투여 순서 */
model logDATA = sequence
subject(sequence)
period
formulation; /* log PK parameter를 분석 */
/* sequence, period, formulation 효과 포함 */
/* subject(sequence)를 fixed effect처럼 포함 */
estimate "test-ref" formulation -1 1; /* Test - Reference 차이 추정 */
/* level 순서에 따라 부호 확인 필요 */
test h=sequence e=subject(sequence); /* sequence effect 검정 시 */
/* subject(sequence)를 error term으로 사용 */
lsmeans formulation / adjust=t
pdiff=control("R")
CL alpha=0.10; /* formulation별 LS mean */
/* Reference("R") 대비 비교 */
/* alpha=0.10 → 90% CI */
run;
2 by 4
Method B - PROC MISED
proc mixed data=replicate; /* mixed model 사용 */
class formulation subject period sequence; /* 범주형 변수 선언 */
model logDATA = sequence
period
formulation; /* fixed effect */
/* sequence, period, formulation 포함 */
random subject(sequence); /* subject(sequence)를 random effect로 지정 */
/* sequence 내 subject variability 반영 */
estimate "test-ref" formulation -1 1
/ CL alpha=0.10; /* Test - Reference 차이 */
/* 90% CI 출력 */
run;
2 by 4
Method C - PROC MIXED (FDA style)
proc mixed data=replicate; /* FDA-style replicate design mixed model */
classes sequence subject period formulation; /* 범주형 변수 선언 */
model logDATA = sequence
period
formulation
/ ddfm=satterth; /* fixed effect */
/* ddfm=satterth = Satterthwaite 자유도 보정 */
random formulation / type=FA0(2)
sub=subject
G; /* subject별 formulation random effect */
/* subject × formulation interaction 반영 */
/* G = covariance matrix 출력 */
repeated / grp=formulation
sub=subject; /* formulation별 residual variance 허용 */
/* Test와 Reference의 within-subject variance 분리 */
estimate 'test-ref' formulation -1 1
/ CL alpha=0.10; /* Test - Reference 차이 */
/* 90% CI 출력 */
run;
문제
1
- ttest
| USUBJID | TRTP | AVAL |
|---|---|---|
| 01 | Placebo | 12 |
| 02 | Placebo | 15 |
| 03 | Placebo | 14 |
| 04 | Drug | 20 |
| 05 | Drug | 18 |
| 06 | Drug | 22 |
- 위 데이터를 이용해 SAS dataset data1 생성하라.
data data1;
input USUBJID $ TRTP $ AVAL;
datalines;
01 Placebo 12
02 Placebo 15
03 Placebo 14
04 Drug 20
05 Drug 18
06 Drug 22
;
run;
- Treatment group (TRTP) 간 AVAL 평균 차이를 비교하라.
- 적절한 PROC TTEST 코드를 작성하라.
proc ttest data=data1 /*alpha=0.05*/;
class TRTP;
var AVAL;
run;
- 결과에서 어느 group 평균이 더 높은지 해석하라.
| TRTP | Method | N | Mean | Std Dev | Std Err | Minimum | Maximum |
|---|---|---|---|---|---|---|---|
| Drug | 3 | 20.0000 | 2.0000 | 1.1547 | 18.0000 | 22.0000 | |
| Placebo | 3 | 13.6667 | 1.5275 | 0.8819 | 12.0000 | 15.0000 | |
| Diff (1-2) | Pooled | 6.3333 | 1.7795 | 1.4530 | |||
| Diff (1-2) | Satterthwaite | 6.3333 | 1.4530 |
| TRTP | Method | Mean | 95% CL Mean (Lower) | 95% CL Mean (Upper) | Std Dev | 95% CL Std Dev (Lower) | 95% CL Std Dev (Upper) |
|---|---|---|---|---|---|---|---|
| Drug | 20.0000 | 15.0317 | 24.9683 | 2.0000 | 1.0413 | 12.5695 | |
| Placebo | 13.6667 | 9.8721 | 17.4612 | 1.5275 | 0.7953 | 9.6001 | |
| Diff (1-2) | Pooled | 6.3333 | 2.2993 | 10.3674 | 1.7795 | 1.0662 | 5.1135 |
| Diff (1-2) | Satterthwaite | 6.3333 | 2.1866 | 10.4800 |
| Method | Variances | DF | t Value | Pr > |t| |
|---|---|---|---|---|
| Pooled | Equal | 4 | 4.36 | 0.0121 |
| Satterthwaite | Unequal | 3.7409 | 4.36 | 0.0140 |
| Method | Num DF | Den DF | F Value | Pr > F |
|---|---|---|---|---|
| Folded F | 2 | 2 | 1.71 | 0.7368 |
- independent two-sample t-test를 통해 treatment group 간 평균 차이를 비교하였다.
- drug의 평군은 placebo보다 높았다.
2
- Proc glm
| USUBJID | TRTP | BASE | CHG |
|---|---|---|---|
| 01 | Placebo | 10 | 2 |
| 02 | Placebo | 12 | 1 |
| 03 | Placebo | 11 | 3 |
| 04 | Drug | 10 | 7 |
| 05 | Drug | 13 | 8 |
| 06 | Drug | 12 | 6 |
- SAS dataset 생성
data data1;
input USUBJID $ TRTP $ BASE CHG;
datalines;
01 Placebo 10 2
02 Placebo 12 1
03 Placebo 11 3
04 Drug 10 7
05 Drug 13 8
06 Drug 12 6
;
run;
- Baseline(BASE)를 보정하여 treatment(TRTP) 간 CHG 차이를 비교하라
- 적절한 PROC GLM 코드 작성
proc glm data=data1; /*ANCOVA*/
class TRTP;
model CHG = TRTP BASE;
lsmeans TRTP / pdiff cl;
run;
quit;
| Source | DF | Sum of Squares | Mean Square | F Value | Pr > F |
|---|---|---|---|---|---|
| Model | 2 | 37.50000000 | 18.75000000 | 14.06 | 0.0299 |
| Error | 3 | 4.00000000 | 1.33333333 | ||
| Corrected Total | 5 | 41.50000000 |
- 유의수준 0.05에서 통계적으로 유의함(p = 0.0299)
- 모델이 유의하다고 해석 가능
| R-Square | Coeff Var | Root MSE | CHG Mean |
|---|---|---|---|
| 0.903614 | 25.66001 | 1.154701 | 4.500000 |
- \(R^2\)은 90%, 모델 설명력이 높음
| Source | DF | Type I SS | Mean Square | F Value | Pr > F |
|---|---|---|---|---|---|
| TRTP | 1 | 37.50000000 | 37.50000000 | 28.13 | 0.0131 |
| BASE | 1 | 0.00000000 | 0.00000000 | 0.00 | 1.0000 |
| Source | DF | Type III SS | Mean Square | F Value | Pr > F |
|---|---|---|---|---|---|
| TRTP | 1 | 34.09090909 | 34.09090909 | 25.57 | 0.0149 |
| BASE | 1 | 0.00000000 | 0.00000000 | 0.00 | 1.0000 |
- type III 기준 TRTP가 유의함(p=0.0131)
- treatment group 간 CHG 차이가 통계적으로 유의함
- base는 영향 없음
| TRTP | CHG LSMEAN | Pr > |t| |
|---|---|---|
| Drug | 7.0000000 | 0.0149 |
| Placebo | 2.0000000 |
| TRTP | CHG LSMEAN | Lower 95% CL | Upper 95% CL |
|---|---|---|---|
| Drug | 7.000000 | 4.825975 | 9.174025 |
| Placebo | 2.000000 | -0.174025 | 4.174025 |
| i | j | Difference Between Means | Lower 95% CL | Upper 95% CL |
|---|---|---|---|---|
| 1 | 2 | 5.000000 | 1.853113 | 8.146887 |
- 어떤 treatment가 더 효과적인지 해석하라
- chg 평균이 더 높은 drug가 더 효과적임(chg mean 7 vs 2)
3
- Proc mixed
| USUBJID | TRTP | VISIT | CHG |
|---|---|---|---|
| 01 | Placebo | Week1 | 1 |
| 01 | Placebo | Week2 | 2 |
| 02 | Placebo | Week1 | 0 |
| 02 | Placebo | Week2 | 1 |
| 03 | Drug | Week1 | 3 |
| 03 | Drug | Week2 | 5 |
| 04 | Drug | Week1 | 4 |
| 04 | Drug | Week2 | 6 |
- SAS dataset 생성
data data2;
input USUBJID $ TRTP $ VISIT $ CHG;
datalines;
01 Placebo Week1 1
01 Placebo Week2 2
02 Placebo Week1 0
02 Placebo Week2 1
03 Drug Week1 3
03 Drug Week2 5
04 Drug Week1 4
04 Drug Week2 6
;
run;
- Visit별 treatment effect를 평가하라
- 적절한 PROC MIXED 코드 작성
proc mixed data=data2 method=REML;
class USUBJID TRTP VISIT;
model CHG = TRTP VISIT TRTP*VISIT / solution;
repeated VISIT / subject=USUBJID;
lsmeans TRTP*VISIT / diff cl;
run;
| Statistic | Value |
|---|---|
| -2 Res Log Likelihood | 11.4 |
| AIC (Smaller is Better) | 13.4 |
| AICC (Smaller is Better) | 15.4 |
| BIC (Smaller is Better) | 12.7 |
| DF | Chi-Square | Pr > ChiSq |
|---|---|---|
| 0 | 0.00 | 1.0000 |
| Effect | TRTP | VISIT | Estimate | Standard Error | DF | t Value | Pr > |t| |
|---|---|---|---|---|---|---|---|
| Intercept | 1.5000 | 0.5000 | 2 | 3.00 | 0.0955 | ||
| TRTP | Drug | 4.0000 | 0.7071 | 2 | 5.66 | 0.0299 | |
| TRTP | Placebo | 0 | . | . | . | . | |
| VISIT | Week1 | -1.0000 | 0.7071 | 2 | -1.41 | 0.2929 | |
| VISIT | Week2 | 0 | . | . | . | . | |
| TRTP*VISIT | Drug | Week1 | -1.0000 | 1.0000 | 2 | -1.00 | 0.4226 |
| TRTP*VISIT | Drug | Week2 | 0 | . | . | . | . |
| TRTP*VISIT | Placebo | Week1 | 0 | . | . | . | . |
| TRTP*VISIT | Placebo | Week2 | 0 | . | . | . | . |
| Effect | Num DF | Den DF | F Value | Pr > F |
|---|---|---|---|---|
| TRTP | 1 | 2 | 49.00 | 0.0198 |
| VISIT | 1 | 2 | 9.00 | 0.0955 |
| TRTP*VISIT | 1 | 2 | 1.00 | 0.4226 |
- type III fixed effect
- treatment group간 통계적으로 유의한 chg 차이가 존재
- visit에 따라 통계적으로 유의한 chg 차이가 존재하지 않음
- visit에 따라 treatment 효과가 달라진다고할 수 없음.(통계적으로 유의하지 않은 chg차이)
| Effect | TRTP | VISIT | Estimate | Standard Error | DF | t Value | Pr > |t| | Alpha | Lower | Upper |
|---|---|---|---|---|---|---|---|---|---|---|
| TRTP*VISIT | Drug | Week1 | 3.5000 | 0.5000 | 2 | 7.00 | 0.0198 | 0.05 | 1.3487 | 5.6513 |
| TRTP*VISIT | Drug | Week2 | 5.5000 | 0.5000 | 2 | 11.00 | 0.0082 | 0.05 | 3.3487 | 7.6513 |
| TRTP*VISIT | Placebo | Week1 | 0.5000 | 0.5000 | 2 | 1.00 | 0.4226 | 0.05 | -1.6513 | 2.6513 |
| TRTP*VISIT | Placebo | Week2 | 1.5000 | 0.5000 | 2 | 3.00 | 0.0955 | 0.05 | -0.6513 | 3.6513 |
- 모든 시점에서 drug가 placebo보다 평균적으로 추정치가 높다.
| Effect | TRTP | VISIT | _TRTP | _VISIT | Estimate | Standard Error | DF | t Value | Pr > |t| | Alpha | Lower | Upper |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| TRTP*VISIT | Drug | Week1 | Drug | Week2 | -2.0000 | 0.7071 | 2 | -2.83 | 0.1056 | 0.05 | -5.0424 | 1.0424 |
| TRTP*VISIT | Drug | Week1 | Placebo | Week1 | 3.0000 | 0.7071 | 2 | 4.24 | 0.0513 | 0.05 | -0.04243 | 6.0424 |
| TRTP*VISIT | Drug | Week1 | Placebo | Week2 | 2.0000 | 0.7071 | 2 | 2.83 | 0.1056 | 0.05 | -1.0424 | 5.0424 |
| TRTP*VISIT | Drug | Week2 | Placebo | Week1 | 5.0000 | 0.7071 | 2 | 7.07 | 0.0194 | 0.05 | 1.9576 | 8.0424 |
| TRTP*VISIT | Drug | Week2 | Placebo | Week2 | 4.0000 | 0.7071 | 2 | 5.66 | 0.0299 | 0.05 | 0.9576 | 7.0424 |
| TRTP*VISIT | Placebo | Week1 | Placebo | Week2 | -1.0000 | 0.7071 | 2 | -1.41 | 0.2929 | 0.05 | -4.0424 | 2.0424 |
- Repeated statement 의미 설명
- subject=USUBJID는 반복 측정 단위로, 같은 subject내 상관성 고려
4
- merge
data adsl;
input USUBJID $ TRTP $;
datalines;
01 Drug
02 Drug
03 Placebo
;
run;
data adlb;
input USUBJID $ BASE AVAL ;
datalines;
01 10 15
02 12 20
03 11 13
;
run;
- 두 dataset merge
- CHG = AVAL - BASE 생성
proc sort data = adsl; by USUBJID; run;
proc sort data = adlb; by USUBJID; run;
data merged;
merge adsl(in=a) adlb(in=b);
by USUBJID;
if a and b;
chg = aval - base;
run;
- treatment별 평균 CHG 계산
proc means data = merged mean;
class TRTP;
var chg;
run;
- 결과
| TRTP | 관측값 수 | 평균 |
|---|---|---|
| Drug | 2 | 6.5000000 |
| Placebo | 1 | 2.0000000 |
5
- Treatment별 AE 발생 빈도 계산
- Chi-square test 수행
data adae;
input USUBJID $ TRTP $ AEFLAG $;
datalines;
01 Drug Y
02 Drug N
03 Placebo Y
04 Placebo N
;
run;
proc freq data = adae;
tables trtp * aeflag / chisq;
run;
WARNING: 100%개의 셀이 5보다 적은 기대빈도를 가지고 있습니다. 카이제곱 검정은 올바르지 않을 수 있습니다.
-> 따라서 fisher 결과 해석, fisher’s p값은 1