SAS Programming

Author

SEOYEON CHOI

Published

April 29, 2026

코드

  • 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 &para = TRTSEQA APERIOD TRTA;         /* 종속변수 &para를 sequence, period, treatment로 설명 */
                                                /* 보통 &para는 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
  1. 위 데이터를 이용해 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;
  1. Treatment group (TRTP) 간 AVAL 평균 차이를 비교하라.
  2. 적절한 PROC TTEST 코드를 작성하라.
proc ttest data=data1 /*alpha=0.05*/;
    class TRTP;
    var AVAL;
run;
  1. 결과에서 어느 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
  1. 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;
  1. Baseline(BASE)를 보정하여 treatment(TRTP) 간 CHG 차이를 비교하라
  2. 적절한 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
  1. 어떤 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
  1. 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;
  1. Visit별 treatment effect를 평가하라
  2. 적절한 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
  1. 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;
  1. 두 dataset merge
  2. 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;
  1. treatment별 평균 CHG 계산
proc means data = merged mean;
    class TRTP;
    var chg;
run;
  • 결과
TRTP 관측값 수 평균
Drug 2 6.5000000
Placebo 1 2.0000000

5

  1. Treatment별 AE 발생 빈도 계산
  2. 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