SAS Certification Prep Guide :

Base Programming for SAS 9 Summary

Chapter 1. Basic Concepts

□ SAS 시스템의 구조

ex)	data clinic.admit2;	→ admit2이라는 데이터셋 생성
	set clinic.admit;
	run; 하나의 구문(statement)는 세미콜론(;)으로 종료됨 모든 step은 run;으로 종료되며, 종종 quit으로 종료되는 경우도 있음
	proc print data=clinic.data2;
	run;

ㅇ SAS는 DATA, PROC, RUN. QUIT을 만나면, 구문 읽는 것을 멈추고, 이전 스텝을 실행

(위의 예시에서 data step과 proc step 사이에 run은 안써도 무관)

□ Library의 개념

ㅇ Library는 (Windows 환경 하에서) 같은 디렉토리(폴더)에 저장되어 있는 SAS 파일들의 그룹을 의미 : 일부 운영체계에서는 논리적/물리적 가능

(sas dataset이 저장되는 폴더라고 생각하면 됨)

- 일시적 Library : work.파일명

- 영구적 Library : 기타Library.파일명

(사용자가 아무거나 설정 가능 : SASUSER, SASHELP 포함)

-> 즉, work를 제외한 라이브러리는 모두 permanent함.

□ SAS data set의 규칙

ㅇ 1~32 문자

ㅇ 문자로 시작해야 함(A-Z(대․소문자 가능, 또는 _)

ㅇ 숫자, 문자, _의 조합으로 연속 가능

→ 이는 data set 내의 variable의 규칙과도 동일

□ SAS variable(=columns)의 규칙

ㅇ 기본적으로는 SAS data set의 규칙과 동일

ㅇ variable의 경우 null값을 표시하는 방법이 다름

- 문자 변수의 경우 ‘공백’

- 숫자 변수의 경우 ‘마침표(.)’

ㅇ 문자 변수는 Length는 32,767 bytes까지 가능하고, length statement로 길이가 정해지거나, 다른 rule(처음 입력되는 변수 값의 길이)를 통해 길이가 정해지는 반면,

숫자 변수의 경우 default length가 8

□ Format, Informat, Label

구 분	내 용	예 시
Format	데이터 표시할 때 (출력포맷)	원data는 5678인데, COMMA8.2로 5,678.00으로 표시
Informat	데이터 불러들일 때 (입력포맷)	원data $1,234.00에서 COMMA10.으로 1234.00으로 읽음($와 ,빠짐)
Label	변수에 대한 추가 설명	name이라는 변수명을 patient name으로 표시

Chapter 2. Referencing Files and Setting Options

□ SAS의 default library

ㅇ Sashelp : Permanent - read only, SAS control

ㅇ Sasuser : Permanent - personal setting

ㅇ Work : Temporary

□ Library 할당

ㅇ Libname test 'c:\sas\definitice';

- Library명은 1-8 크기의 문자이며, 문자/_로 시작해야하고, 문자/숫자/_만을 포함할 수 있음

* Libarary statement는 Global : SAS 세션이 종료되거나, 라이브러리를 수정 또는 취소하기 전까지 유효

ㅇ Libname test SPSS 'g:\myspss.dat';

- BMDP, OSIRIS, SPSS file에 대한 읽기-전용 라이브러리 설정 가능

□ 라이브러리 조회

1) proc contents

ㅇ proc contents data=mylib._all_nods;    * Library명 뒤의 마침표 유의!

- _all_ : 라이브러리의 모든 파일 조회(‘라이브러리명._all_‘로 표시)

- nods : no detail 의미(_all_ 쓸 때만 사용 가능)

ㅇ proc contents data=mylib.admit;

- 특정 데이터셋(admit)의 정보 조회시 데이터셋명 명시

2) proc datasets의 contents statement

ㅇ proc datasets;

contents data=sasuser._all_nods;

quit;

▷ proc contents와 proc datasets의 차이

차이1) proc contents는 work 또는 user가 default Library인 반면, proc datasets의 contents statement는 procedure input library가 default임

차이2) proc datatets은 run statement가 아닌 quit statement가 요구되는 상호적 프로시져임

※ proc datasets;

contents data=sasuser._all_nods;

quit;

proc contents data=sasuser._all_nods;

run;

→ 두 프로시져는 실질적으로 동일한 결과 산출

(사소한 포맷 차이는 있을수 있음)

□ 라이브러리의 변수(Variable=Column) 정보 조회

ㅇ Proc contents나 Proc datasets의 contents statement에서 VARNUM 옵션 사용

- ex1) Proc datasets;

- ex1) contents data=sasuser.admit varnum;

- ex2) Proc contents data=sasuser.damit varnum;

□ SAS의 output

ㅇ SAS에서는 아래의 output 생성 가능

1) HTML document

2) Listing(traditional SAS output)

3) 위의 둘 다

ㅇ Option statement로 시스템 옵션 수정 가능

** Option statement는 global : SAS session을 끝내거나 옵션을 수정할 때까지 유효

** SAS listing에서의 적용임에 유의

- nonumber/nodate : SAS output에 Default로 표시되는 페이지 넘버와 날짜 미표시

- pageno : 페이지 넘버 표시할 경우, 시작 페이지를 설정

(default는 1)

- pagesize : 한 페이지에 몇 개의 라인이 포함될지를 설정

(default는 15 : 제목, 날짜 등 포함)

- linesize : 페이지의 너비를 설정

- yearcutoff : 두자리 연도의 범위를 설정  * 연도 데이터가 4자리인 경우는 불필요!

(default는 1920)

ex) yearcutoff=1920일 경우, 1920 ~ 2019의 범위로 인식

A. ‘41.03.26 인 경우 : 1941.03.26

B. ‘15.05.31 인 경우 : 2015.05.31

C. ‘21.11.12 인 경우 : 1921.11.12

- firstobs/obs : firstobs는 추출하려는 첫 번째 행을(default는 1), obs는 마지막 행을 설정

(두 옵션을 같이 써서 추출 범위를 설정 가능)

** obs=max 옵션으로 마지막 관측치의 수를 초기화 가능

** firstobs와 obs옵션을 시스템 옵션이 아닌 데이터셋 옵션으로 사용하면, 시스템 옵션에 우선시됨

즉, options firstobs=10 obs=15;

proc print data=sasuser.heart;

run; 하면, 10~15까지 6개 관측치가 표시되는데,

options firstobs=10 obs=15;

proc print data=sasuser.heart(firstobs=4 obs=20);

run;처럼 데이터셋 옵션으로 지정하면, 위 옵션 무시하고 4~20까지의 관측치 표시

□ System Option 조회

ㅇ 모든 옵션 조회시

- proc options;

ㅇ 특정 옵션 조회시

- proc options option=yearcutoff;

□ 부가 옵션

ㅇ formchar : proc freq, proc tabulate 등에서 테이블 아웃라인 등을 만들기 위해 사용되는 formatting character 지정

(프로시져에서 별도 옵션으로 설정되지 않으면, default는 formchar 시스템 옵션값이 됨)

ㅇ formdlim : 페이지 나누기를 위한 구분 문자 지정

(통상 null)

ㅇ label / nolabel : 일시적으로 변수명 변환

ㅇ obs : 관측치의 수 지정

ㅇ source / nosource : SAS source statement의 SAS LOG내 저장 여부 조정

(default는 source)

Chapter 3. Editing and Debugging SAS Programs

□ SAS 프로그램의 layout

ㅇ SAS statement는 거의 모든 형식으로 작성 가능하나, 일관된 layout이 도움이 될 것임. 아래는 예시임

- DATA/PROC step은 첫 번째 열에서 시작

- 스텝 내에서는 statement 들여쓰기

- RUN statement는 첫 번째 열에서 시작

- 매 DATA/PROC step에 RUN statement 포함

□ Error의 종류

ㅇ snytax(문법) error : SAS의 언어 규칙 따르지 않는 경우

(misspelled words 등)

ㅇ data error : 데이터 값이 프로그램에서 설정된 SAS 구문에 적합하지 않는 경우

□ syntax error

ㅇ SAS 프로그램을 실행하면, step별로 syntax error 여부를 검색하고, error가 없다면 해당 step 실행후 다음 스텝 진행

ㅇ syntax error의 종류

- missing RUN statement

․ SAS는 step별로 실행되며, DATA/PROC statement 또는 RUN/QUIT statement를 만나면 현재 step의 끝임을 인식

※ ex) data clinic.admitfee;

set clinic.admit;

run;

proc print data=clinic.admitfee;

var id name actlevel fee;

→ 이 경우, SAS는 data step은 실행하되, proc step은  실행되지 않음 ∵proc step의 끝을 알 수가 없기 때문(proc step 다음에 다른 data/proc step이 나오지 않고, run이 있지도 않으므로)

→ 단, EG에서는 자동으로 모든 코드의 끝에 run statement가 추가되므로 위 예시의 data step이 실행됨에 유의

- missing semicolon

- unbalanced quotation marks

․ SAS에에서는 이 error의 경우 통상 따옴표 추가하는 것만으로는 오류 수정이 안됨. SAS에서는 이 문제 해결을 위해 「*‘; run」을 실행하여 프로그램을 취소하고, 「*‘; run」를 제거 후에 수정된 프로그램을 재실행해야 함

․ EG에서는 자동으로 끝부분의 따옴표 처리가 되므로 에러 메시지가 뜨지 않을 수 있으나, 정확한 값이 나오지는 않을 것이며, 코드 창의 코드 색을 참조하여 에러를 수정할 수 있을 것

- invalid option

□ SAS에서의 주석

ㅇ *text* 또는 /*text*/의 형식으로 주석 처리

□ SAS 시스템 옵션

ㅇ errors = n : 데이터 에러 메시지 표시수 설정

ㅇ fmterr/nofmterr : 변수의 format이 부적절할 때 error 메시지 발생 여부 조절

(default는 fmterr)

ㅇ source/nosource : SAS log에 source statement 저장 여부를 조절

(default는 source)

Chapter 4. Creating List Reports

□ Proc print

ㅇ 데이터셋에 들어있는 변수의 순서대로 변수 추출해서 보여줌

ㅇ noobs 옵션으로 Listing의 obs 컬럼 제외 가능

□ Var 구문

ㅇ proc print는 default로 모든 변수를 추출하며, var 구문을 이용하여 출력을 원하는 변수 선택 가능(여러 개의 변수 선택시 공백으로 변수 구분)

□ id 구문

ㅇ obs 대신 한 개 이상의 변수를 지정할 수 있음

ㅇ proc print에서 변수명이 많아 한페이지에 못 담아지는 경우(HTML은 자동으로 한페이지에 표시됨. Listing의 경우는 안됨), id 구문에서  지정한 변수가 페이지마다 반복되도록 할 수 있음

* 단, id 구문에도 있고, var 구문에도 있는 변수는 결과물에서 2번 표시됨에 유의

□ where 구문

ㅇ 문자와 숫자에 모두 적용 가능

- 문자는 작은따옴표(’example’)로 묶어야 하고, 데이터셋에 있는 대로 대/소문자 구분이 되어야 함

ㅇ step에 한 번만 존재 가능

ㅇ var에서 지정한 변수 뿐만 아니라, 원데이터셋에 있는 모든 변수들을 지정가능

- 비교 연산자

표시	= or eq	^= or ne	> or gt	< or lt	>= or ge	<= or le
의미	같음	같지 않음	초과	미만	이상	이하

- 포함 연산자(contains or ?)

ex. where firstname contains 'Justice'

또는, where firstname ? ‘Justice'

- 비교 연산자

AND or &	OR or｜
and, both 의미	or, either 의미

- IN 연산자

ex. where actlevel in ('low','mod')

= where actlevel ='low' or actlevel = 'mod'

□ DATA 정렬

ㅇ 데이터셋에 들어있는 관측치(행, observation)의 순서대로 보여주고,  proc sort를 활용해 정렬 가능

ㅇ proc sort는,

- 새로 정렬된 데이터를 저장하는 새로운 데이터셋을 생성하고,

- default로 원 데이터셋을 정렬하여 대체하며(∵ out 옵션 지정 필요),

- 프린팅 아웃풋을 만들어내지 않고(∴proc print 필요),

- 결측값은 가능한 작은 값으로 처리함

ex1) proc sort data=clinic.damit out=work.test;

by weight age; (※ weight → age 순 오름차순)

run;

ex2) proc sort data=clinic.damit out=work.test;

by descending weight age; (※ descending은 weight에만 적용됨에 유의)

run;

□ 컬럼 합계 계산

ㅇ proc print에 sum statement를 써서 컬럼의 합계 계산 가능

ㅇ sum statement에 넣으면, var statement에 컬럼명 지정할 필요 없음

- proc print data=clinic.insure;

var name policy balancedue;

where pctinsured < 100;

sum balancedue;      →name, policy, balancedue 표시되고

run;                     →가장 마지막줄에 balancedue의 합계 계산됨

□ 부분합 계산

ㅇ sum 과 by statement를 동시에 사용하여 부분합 계산

- proc print data=work.activity;

var age height weight fee;

where age>30;

sum fee;

by actlevel;   (※ actlevel 그룹별로 fee의 합계 계산)

run;

→ 즉, actlevel 그룹별로 height, weight, fee 표시되고, 각 테이블의 마지막에 fee의 부분합이 계산되며, 테이블 가장 밑에 전체 fee 합계도 표시됨

□ By groups와 ID variable을 활용한 사용자 맞춤 레이아웃 생성

ㅇ 위의 예시처럼 by actlevel 쓰면, actlevel이 불필요하게 2번(그룹별 표 제목과 표 내의 그룹소계별) 표시되고, OBS도 표시됨

- by statement와 ID statement를 동시에 씀으로써,

1) OBS 컬럼을 안보이게 할 수 있고,

2) ID/By 변수가 가장 왼쪽 컬럼에 표시되며,

3) 각각의 ID/By 값은 by group의 시작점(한 표 내에서 그룹별 가장 처음)과 부분합 부분(그룹별 소계)에만 표시되도록 할 수 있음

4) pageby를 적용하면, 그룹별로 표가 분할되되, 그룹별 표 제목은 표시 안됨

․ 단, pageby 변수는 proc print의 by에도 존재하는 변수여야함

- proc print data=work.activity;

var age height weight fee;

where age>30;

sum fee;

by actlevel;

id actlevel;

pageby actlevel;

run;

< 예 시 >

libname clinic 'c:\sas'; proc print data=clinic.admit; run;	기본
proc print data=clinic.admit; sum fee; run;	아래에 sum(fee) 표시
proc sort data=clinic.admit out=admit; by age; run; proc print data=admit.label noobs; var age fee; label fee = 'Admission Fee'; where age>30; run;	※proc sort임에 유의 age로 정렬(오름차순) obs 제외 age와 fee만 추출 Fee의 변수명을 변경 age>30인것만 추출
proc print data=sales.reps; id idnum name; var idnum jobcode salary;	obs 대신에 idnum과 name 표시 id와 var에 둘다 있으면 중복 표시

□ Double-Spacing Listing Output

ㅇ Proc print의 double option으로 레이아웃을 더블스페이스로 할 수 있음

- proc print data=clinic.stress double;

※ double option은 HTML output에는 적용 안됨에 유의

□ Title과 Footnote statement

ㅇ 최대 10개의 title과 footnote 적용 가능

ㅇ title과 footnote statement는 global 하므로, proc print 앞에 놓여야 함

※ global하다는 것은, title/footnote 정의 후에는 1)수정하거나 2) 취소하거나 3)SAS 세션을 끝내기 전까지는 계속 유효함을 의미

ㅇ 지정 → proc print → 재지정 → proc print의 경우 재지정된 title/footnote가 적용됨

ㅇ default 값은 title의 경우 ‘The SAS System‘, foonote의 경우 없음

ㅇ title과 footnote의 최대 길이는 linesize 옵션의 값에 따라 정해짐

ㅇ title/footnote 구문 바로 뒤의 숫자를 지정 안하면 title1/footnote1을 의미

ㅇ 적용한 title/footnote의 취소는 ‘title/footnote’(문자 또는 숫자 없는 null title/footnote) 또는 text(본문) 없는 'title1/footnote1’로 가능하며, 이 경우 default title인 ‘The SAS System'도 취소됨

- 그리고, 다시 지정한 title/footnote는  더 큰 번호의 title/footnote를 취소함

․ 예를 들어, foonote1, foonote2, foonote3, foonote4 후에, 다시 footnote2하면, foonote3과 foonote4는 취소된다는 말

ex) title1 'Heart rates for patients with';

title3 'Increased Stress Tolerance Levels';

footnote1 'Data from Treadmill Tests';

footnote3 '1Q Admissions';

proc print data=clinic.stress;

var resthr maxhr rechr;

where tolerance='I';

run;

→ HTML output에서는 title/Footnote가 줄바뀜 없이 연속되어 표시됨

(title) ‘Heart rates for patients with Increased Stress Tolerance Levels‘

(footnote) ‘Data from Treadmil Tests 1Q Admissions'

→ SAS listing output에서는 title2가 없으므로, 한줄 띄워서 표시됨

(title) ‘Heart rates for patients with

<빈 줄>

Increased Stress Tolerance Levels‘

(footnote) 'Data from Treadmill Tests

<빈 줄>

1Q Admissions'

□ Label 설정 (※temporarily)

ㅇ Label은 변수명에 대한 설명 표시를 의미

ㅇ Label의 길이는 문자 256까지이며, 작은 따옴표로 묶여야 함

ㅇ Label은 위치하고 있는 프로시져에만 적용됨

ex) proc print data=clinic.therapy label;

label walkjogrun = 'Walk/Jog/Run';

label age = 'Age of Patient';     ※ 복수 Label 설정 가능

※복수의 Label 설정 시에는 label statement를 한번만 써도 됨

label walkjogrun = 'Walk/Jog/Run'

age = 'Age of Patient';

□ 데이터 값에 대한 Format

ㅇ Format은 데이터 값이 SAS에서 어떻게 표시되는지를 조정

ㅇ Format은 output에서의 표시에만 영향줄 뿐 데이터셋의 실제 데이터에 영향 미치지는 않음

ㅇ Format도 위치하고 있는 프로셔져에만 적용됨

ㅇ Format도 한 변수 또는 여러 변수에 동시에 적용 가능

ex) format date mmddyy8.;

ex) format net comma5.0 gross comma8.2;

format net gross dollar9.2;

→ 둘 다 net과 gross를 모두 dollar9.2 처리

< 자주 쓰는 Format >

Format	설 명
COMMAw.d	천단위와 소수자리 표시
DOLLARw.d	$,천단위, 소수자리 표시
MMDDYYw.	MMDDYY8.이면 11/31/06, MMDDYY10.이면 11/31/2006
w.	정수 w자리으로 반올림
w.d	정수 w자리의 소수자리d로 반올림
$w.	w자리 문자 변수
DATEw.	DATE7.이면 16OCT99, DATA9.면 16OCT1999

ㅇ 자리수 w에는 천단위(콤마), $, 소수점, 소수자리까지 포함됨에 유의

예시) 5400을 5,400으로 표시하고 싶으면, comma5.d 이상 필요

2030을 2,030,00으로 표시하고 싶으면, comma 8.2 이상 필요

15374를 $15,374.00으로 표시하고 싶으면, dollar10.2 이상 필요

< Format 예시 >

데이터셋의 값	Format	표시값	비 고
38245.3975	COMMA12.2	38,245.40
	12.2	38245.40	$ 없음
	DOLLAR12.2	$38,245.40
	DOLLAR9.2	$38245.40	천단위 없음
	DOLLAR8.2	38245.40	$, 천단위 없음

□ Permanent Label/Format 설정

ㅇ Label/Format은 Proc print에 있으면 temporary, Data step에 있으면 permanent함

ex) data flights.march;

set flights.mar01;

label date='Departure Date';

format date date9.;

run;

proc print data=flights.march label;

run;

→ data step에서 label/format을 적용하더라도, 여전히 proc print에서 label 옵션 필요함에 유의

→ 실행 결과는, date 컬럼이 ‘Departure Date'로 표시되며, ‘01MAR2000‘의 형식임

□ 부가 기능

ㅇ Label을 나누는 식별자 지정

split = '분리문자‘ : label을 나누는 식별자(delimiter) 지정

ex) proc print data=reps split='*'

ㅇ 자기만의 Format 생성

ex) proc format;

value $repfmt

'TFB' = 'Bynum'

'MDC' = 'Crowley'

'WKK' = 'King;

proc print data=vcrsales;

var salesrep type unitsold;

format salesrep $repfmt.;      (※ 뒷장에서 추가 설명)

run;

Chapter 5. Creating SAS Data Sets from Raw Data

□ SAS 프로시져를 사용하여 보고서를 만들기 위해서는, SAS 데이터셋  형식의 data가 필요

ㅇ data가 SAS 데이터셋 형식이 아니라면, 다음의 방식으로 SAS 데이터셋 생성 필요

- data 직접 입력

- raw data 불러오기

- 다른 소프트웨어에서 생성된 파일 불러오기

< 데이터 불러오기 관련 주요 statement >

작업명	SAS statement
SAS 라이브러리 참조	Libname
외부파일 참조	Filename
SAS 데이터셋 명명	Data
외부파일 인식	Infile
data 기술	Input
Data step 실행	Run
data 나열	Proc print
프로시져 실행	Run

□ SAS 라이브러리 참조 (→ Libname은 폴더에 대한 별칭)

ㅇ Libname taxes 'c:\users\acct\qtrl\report';

- c:\users\acct\qtrl\report 폴더를 라이브러리 taxes로 할당

ㅇ 항상 libname 구문을 쓸 필요는 없음 : temporary SAS 데이터셋에 저장하는 경우 등에는 불필요

▢ 외부파일 참조 (→ Filename은 파일에 대한 별칭)

ㅇ filename tests 'c:\users\tmil.dat';

- c:\users\tmil.dat을 파일 Tests로 할당

ㅇ filename finance 'c:\users\personal\finances';

- 이렇게 c:\users\personal\finances 폴더 설정도 가능

ㅇ fileref명은(위에서는 tests/finance) 1~8 길의 문자이며, 문자 또는 _로 시작해야하고, 문자, 숫자, _만을 포함 가능

※ libname과 filename statement는 global함

□ Infile로 외부파일 인식

ㅇ infile exercise;

- 한 개의 외부파일만 있는 exercise라는 fileref 인식

ㅇ infile tax(refund.dat);

- 여러 개의 외부파일이 있는 tax라는 fileref의 refund.dat라는 외부파일 인식

- windows 환경이라면, 파일 확장자 생략 가능. 단, 따옴표로 파일명을 묶어야 함

: infile tax('refund')

□ 데이터셋 명명

ㅇ data clinic.stress;

- libref.filename의 형식으로 데이터셋 또는 생성될 데이터셋을 명명

- 위에서 clinic은 libref, stress는 filename

□ raw data file 명시

ㅇ filename으로 경로, infile로 파일명 인식하든가,

- filename finance 'c:\users\personal\finances';

infile finance(refund.dat);

ㅇ 아니면 infile로 바로 경로와 파일명 지정가능 (※통상 이렇게들 씀)

- infile 'c:\users\personal\finances\refund.dat';

□ column input

ㅇ 통상의 데이터 입력 스타일인 column input은 다음의 경우 가능

- data는 표준 문자 또는 수치 값이어야 하고,

· 표준 수치는 숫자, 소수점, 과학 또는 E 기호(예를 들어 2.3E4)  , +/- 기호만을 포함 가능

· 비표준 수치는 %/$/,(콤마) 등과 같은 문자, 날짜/시간, 깨진 data, 이진수, 16진수 등

ex) 컬럼 값에 29,996.63이 있으면, 이는 천단위 콤마(,)가 있으므로, 비표준 수치이고, 따라서 column input 사용 불가능

- 고정필드(fixed field)여야 함

·  각 컬럼별 시작/끝 위치가 동일해야 함을 의미

□ data 기술

ㅇ filename exer 'c:\users\exer.dat';

data exercise;

infile exer;

앞의 설명대로라면, filename과 infile을 따로 쓰지 않고, infile 'c:\users\exer.dat'; 한번으로도 가능함(확인)

input ID $ 1-4 Age 6-7 Actlevel $ 9-12 Sex $ 14

→ ID와 Actlevel, Sex는 문자임을 의미하고($), Age는 6칸에서 7칸 까지의 값임을 의미

□ 변수명 명시

ㅇ 변수명은 1~32 문자 길이이며, 문자(A-Z) 또는 _로 시작해야 하고, 숫자/문자/_의 조합 가능

□ data step 프로그램 제출(submit)

ㅇ obs 옵션으로 몇 개의 데이터만 검증 가능(검증 후에는 obs 옵션을 빼고 다시 돌려야 전체 Data를 가져올 수 있음에 유의)

- infile tests obs=10;

ㅇ run statement로 실행

- 단, syntax error나 invalid data error의 경우에는 SAS가 멈추지 않고 계속 실행되므로, Log를 살펴야 함에 유의

□ 변수 생성/수정

ㅇ 할당(assignment) 구문

- name = 'Toby Witherspoon';

: Toby Witherspoon라는 문자 값을 변수명 name에 할당

※ 할당구문은 키워드로 시작하지 않는 몇 개 안되는 SAS 구문임

□ 산술 연산자

연산자	내용	예시	우선선위
-	음수 표시	negative=-x;	I
**	자승	raise=x**y	I
*	곱셈	mult=x*y	II
/	나누기	divide=x/y	II
+	덧셈	sum=x+y	III
-	뺄셈	diff=x-y	III

주 1. 우선순위 I은 II보다, II는 III보다 우선하여 처리됨

□ date/time/datetime 상수(→날짜에는 d,시간에는 t, 날짜&시간에는 dt)

ㅇ testdate1 = '01jan2000'd;

testdate2 = '01jan00'd;

ㅇ time = '9:25't;

ㅇ datetime = '18jan2005;9;27;5'dt;

□ data 부분화(subsetting)

ㅇ if statement를 활용해 특정 조건을 만족하는 data만 부분화 가능

- data clinic.stress;

infile tests;

input ID 1-4 name $ 6-25 resthr 27-29 tolerance $ 30;

if tolerance = 'D';

→ tolerance가 ‘D'인 관측치만 추출

□ Instream data 읽기 : 외부파일이 아닌, SAS를 활용한 직접 데이터 입력

ㅇ dataline statement를 data step의 가장 마지막(run 제외)에 쓰고, data 입력후, 입력 데이터의 가장 마지막에는 null statement(single ;)로 마무리

- 한 개의 data step에는 한 개의 dataline statement만 가능. 복수의 데이터 셋을 만들려면 별개의 data step을 구성해야 함

- dataline statement 대신 cards statement 쓸 수도 있음

- 데이터가 ;를 포함한다면, dataline4 statement와 ;;;; 사용

- dataline statement의 마지막인 null statement(single ;) 다음에는 run statement 불필요

∵ dataline statement가 쓰이면 null statement(single ;)는 경계로 인식되므로, null statement(single ;) 만나면 data step은 바로 실행됨. 만약 null statement 다음에 run statement를 쓰면, 두 구분 사이의 구문들은 data step으로 실행되지 않음

□ _Null_키워드를 사용한 원시 데이터 생성

ㅇ data step에서 새 변수를 선언하면 raw 데이터 셋은 그대로 있으나, 작업중인 데이터셋이 바뀜

ex) data clinic.stress;

infile tests;

input ID 1-4 name $ 6-25 resthr 27-29 maxhr 31-33

rechr 35-37 timemin 39-40 timesec 42-43

torelance $ 45;

if tolerance ='D';

totaltime = (timemin*60)+timesec;

ㅇ 여기서 우리가 하고자 하는 것은 신규 데이터셋 생성 없이 raw data를 생성하려는 것임

- _null_키워드를 통해 신규 데이터셋 생성 없이 data 단계를 처리

- set statement는 읽어오는 데이터셋을 의미

- file statement는 output file 설정

(fileref 또는 경로 지정도 가능(따옴표))

- put statement는 input statement와 비슷한데, raw data에 저장되는 변수들 지정

(※ put은 새 데이터를 만드는 것이므로 문자형에도 $ 필요 없음)

ex) data _null_;

set clinic.stress;

file 'c:\clinic\stress.dat';

put id 1-4 name 6-25 resthr 27-29 maxhr 31-33;

run;

※ 만약 put statement 앞에 file statement를 쓰지 않으면, SAS Log에 저장하고, put statement 앞의 file statement에 print 옵션을 쓰면  프로시져 output file로 저장됨

Chapter 6. Understanding DATA step Processing

□ SAS가 프로그램을 처리하는 방법

ㅇ SAS DATA step은 두 부분으로 구성

- Compilation phase : Syntax error를 찾고, 완료시 새 데이터셋의 descriptor portion 이 생성됨

- Execution phase : input data를 읽고 처리하며, 데이터셋의 data portion이 생성됨. data portion은 데이터 값을 저장

※ [참고] compile은, C 같은 프로그래밍 언어로 작성된 소스를 컴퓨터가 이해하는 기계어로 바꿔주는 과정을 의미

□ Compilation phase

1) input buffer

ㅇ 외부 파일로부터 레코드를 불러오기 위해 메모리 영역인 input buffer 생성

- input buffer는 SAS 데이터셋이 아닌 raw data를 읽을때만 생성됨

- input buffer는 물리적 저장 영역이 아니라, 논리적 개념임

2) program data vector

ㅇ input buffer 생성 후, SAS가 한번에 관측치 하나당 데이터셋 적재하는 program data vector 생성

- program data vector 또한 논리적 개념임

- _N_과 _ERROR_라는 저장되지 않는 두 개의 자동 변수를 포함

· _N_ : data step이 실행되기 시작한 회수

· _ERROR_ : 실행 중 데이터에 의해 발생하는 오류 발생 의미. default는 0(오류 없음 의미)이며, 한 개 이상의 오류 발생시 값은 1로 고정됨

3) Syntax Checking

ㅇ compilation phase 동안 SAS는 DATA step의 syntax error를 검색

- syntax error의 종류

· keyword 누락 또는 철자오류

· 변수명 부정확

· 구두점(마침표, 콜론 등) 누락 또는 부정확

· 유효하지 않은 옵션 등

4) Data set Variables

ㅇ input 구분이 컴파일되면, program data vector에는 각각의 변수에 대한 공간이 추가되며, assign 구문에 의해 만들어진 변수에 대해서도 공간 추가

- 길이나 종류 같은 변수의 성질은 변수가 처음 만들어졌을 때 결정됨

ex) 두 숫자 변수 A와 B를 더해서 C라는 변수를 assign 했을 때(C=A+B), C는 숫자이며 defult 길이는 8)

숫자 변수는 default 길이가 8(chapter 1 참고)

5) 데이터의 descriptor Portion

ㅇ Data step의 마지막(run 구문)에서는 compilation phase가 끝나고,  새로운 SAS 데이터셋의 descriptor portion이 생성됨

ㅇ Descriptor portion은 데이터셋의 이름, 관측치와 변수의 수, 변수의 이름 및 성질 등을 포함

□ Execution Phase

ㅇ data step은 별다른 추가 구문으로 지정되지 않는 한, input file의  각각의 레코드에 대해 한번씩만 실행됨

- 예를 들어 파일에 9개의 레코드가 있다면, 9번 실행

ex) data perm.update;

infile invent;

input item $ 1-13 idnum $ 15-19 instock 21-22 backord 24-25;

total=instock+backord;

run;

1) 변수 초기화

ㅇ execution phase의 처음에는 _N_값은 1이며, data 오류가 없기 때문에 _ERROR_값은 0임

ㅇ 문자 변수는 초기값이 blank이며, 숫자 변수는 마침표(.)임

< program data vector >

_N_	_ERROR_	item	idnum	instock	backord	total
1	0			.	.	.

주. 변수의 개수 + 할당한 변수(total)만큼의 slot 생성

2) input data

ㅇ infile 구문으로 raw data의 위치를 인식

3) input pointer

ㅇ input 구문으로 데이터를 읽어오기 시작하면, 첫 번째 레코드(_N_=1)의 첫 번째 열에서(column 1) input pointer 시작

- column 1~13까지를 item으로 인식하고, 15~19까지를 idnum으로 인식..(계속)

4) data step의 종료

ㅇ data step의 마지막에서는 program data vector의 값(_N_=1)이 output data set의 첫 번째 관측치로 저장됨

ㅇ 그 다음 _N_이 2로 설정되고, data step의 처음으로 되돌아가 반복됨

< program data vector >

_N_	_ERROR_	item	idnum	instock	backord	total
2	0			.	.	.

ㅇ raw data로부터 변수를 불러올 경우 SAS는 data step의 각 사이클 마다 데이터를 결측값 처리하나, 다음의 경우는 예외

- retain statement로 명명된 변수

- sum statement로 생성된 변수

- _TEMPORARY_ 배열에 있는 데이터 항목

- file 또는 infile statement의 옵션으로 생성된 변수

- 자동 변수

※ 이와는 대조로, sas data set으로부터 변수를 불러올 경우에는 첫data step의 첫 사이클의 시작에만 데이터를 결측값 처리함에 유의

여기 좀 더 구분할 필요

5) data step의 반복

ㅇ data step은 loop처럼 반복되며, 각각의 loop은 iteration이라고 불림

- 두 번째 iteration에서 _N_인 2, _ERROR_은 0이며, input pointer는 두 번째 레코드의 column 1에 위치

6) End of file marker : 파일의 끝을 알리는 표시

ㅇ execution phase는 이런 식으로 raw data file의 end of file marker에 도달할 때까지 반복됨

- raw data에 더 이상 읽을 레코드가 없을 때 새로운 데이터 셋의 data portion이 종료됨

ㅇ data step에서 지정된 변수의 순서대로 data set에 저장됨에 유의

- input idnum $ 15-19 item $ 1-13 → idnum, item 순으로 저장

- input item $ 1-13 idnum $ 15-19 → item, idnum 순으로 저장

7) execution phase의 종료

ㅇ execution phase의 마지막에서는 raw data file이 읽어졌음을 log에 표시하고, data set의 관측치 및 변수의 수를 표시

□ data step debugging

ㅇ compilation phase에서의 오류 진단

- 오타, ; 누락, ‘ 누락, 부정확한 옵션 등의 syntax error

- compilation phase에서의 오류는 compile되지만 실행되지는 않음

ㅇ execution phase에서의 오류 진단

- 예를 들어, fileref가 test인데 tett로 잘못 쓴 경우, compilation phase에서의 error는 아님. 이 경우 exection phase에서 데이터를 읽을 수가 없으므로 SAS는 error 표시하고 멈춤

- 변수의 속성(문자/숫자)을 잘못 지정한 경우도 마찬가지임

□ 프로그래밍 test

ㅇ data step을 작성 또는 수정한 다음에는 data set 생성 없이 프로그램을 수행함으로써 검증 가능

- 가장 간단한 방법이 _NULL_ 키워드를 data step의 data set 명으로 사용하는 것임

ex) data _null;

infile invent;

input item $ 1-13 idnum $ 15-19 instock 21-22 backord 24-25;

total=instock+backord;

run;

→ 이 경우 data step을 실행해도 데이터셋은 생성되지 않으나 변수값을 읽고 검증한 후에 compilation 또는 execution error가 log에 기록됨. error를 수정한 후에는 _NULL_ 키워드를 원하는 데이터셋 명으로 대체하면 됨

ㅇ 관측치 제한

- infile statement의 obs 옵션으로 관측치의 숫자를 제한할 수 있음

ex) infile invent obs=10;   (10개의 관치치를 가져옴)

ㅇ put statement

- 오류의 원천이 무엇인지 불명확할 경우에는 if-then/else statement와 put statement를 활용하여 변수를 검증하고 log에 자신만의 메세지 표시 가능

ex) data work.test;

infile loan;

input code $ 1 amount 3-10;

if code='1' then type='variable';

else if code='2' then type='fixed';

else put 'my note : invalid value:'

code=;

→ 실행하여 code가 1이나 2의 값이 아닌 경우, put statement는 log에 <my note : invalid value : code=v> 표시

< put statement의 예시 >

statement	log
put 'my note : invalid value :'	my note : invalid value :
put 'my note : invalid value :' code type;	my note : invalid value : v fixed
put 'my note : invalid value :' code type=;	my note : invalid value : v type=fixed
put my note : invalud value : _all_	log에 모든 변수명, 변수값 표시

주. ‘변수명 = 변수값‘으로 표시하기 위해서는 변수명 뒤에 ’=’ 첨부

- 자동 변수

․ put 'My note : invalid value : ' code=_n_= _error_=;

→ log에 「My note : invalid value : code=v N=4 Error=0」 표시됨

․ put 'My note : invalid value : ' _all_;

→ log에 모든 변수명, 변수값과 N=, Error=까지 표시됨

Chapter 7 : Creating and Applying user-Defined

□ Proc Format을 활용하여 사용자 정의 format 생성 가능

ㅇ library option을 활용하면 영구적인 format 카탈로그에 저장 가능

(libname 구문이 먼저 필요하고, 'Library‘를 libref로 쓰는 것이 추천됨)

ex) libname library 'c:\sas\formats\lib';

proc format library = library;

(※ proc format lib = library; → 이렇게 약어로 쓸 수도 있음)

ㅇ format 생성시에는, 'value'로 시작하여 format 내용 입력후 ‘;’로 종료

ex) proc format lib=library;

value jobfmt   (※format 생성시에는, 숫자나 마침표로 끝나면 안됨)

103='manager'

105='test processor';

- 문자형 column값에 대한 format은 $ 표시와 따옴표 필요

ex) proc format lib=library;

value $grade

‘A'=‘good'

'B'='fair'

- value로는 특정값(개별값), 수치값 범위, 문자값 범위, 콤마로 구분된 특정값(개별값) 가능

예를 들어, ‘A' = 'Good'

'0 - <13 = 'child'

'B' - 'D' = 'Fair'

'I', 'U' = 'See inspector'

- low는 숫자에서는 missing을 미포함하고, 문자에서는 missing 포함

※ 숫자에서는 other로 지정되지 않은 값과, missing 처리 가능

ex) low-<13= 'child'

13-<20 =' teenager'

20-<65 = 'adult'

other = 'unknown'

ㅇ 여러 개의 컬럼에 대한 format도 한 개의 proc format 구문에서 가능

ex) proc format lib=library;

value jobfmt

103='manager' ...;

value $respnse

'Y' = 'Yes'...;

□ 변수에 대한 format 적용은, data step 또는 proc step에서의 format statement로 가능

(앞장에서 배웠듯이, format 구문은 data step에서 적용할 경우 permanent, proc step에서 적용할 경우 temporarily함)

ㅇ proc format으로 생성한 사용자 정의 format 적용시에는, format명 뒤에 마침표 있어야 함

※ SAS format(comma9.2 등)은 width.decimal place임.

ex) data perm.empinfo;

infile empdata;

input @9 firstname $5. @1 lastname $7. +7 jobtitle 3.

@19 salary comma9.;

format salary comma9.2 jobtitle jobfmt.; (※jobfmt 뒤에 마침표)

ㅇ proc format의 value에서 설정 안된 변수값은, 원래 변수값이 표현됨

□ format 목록 표시

ㅇ proc format에 FMTLIB 키워드를 적용하면, catalog의 모든 format명과 값에 대한 설명 표시

ex) libname library 'c:\sas\formats\lib';

proc format library = library fmtlib;

- 표시되는 항목은, format명, 범위, 라벨,가장 긴 라벨의 길이, 이 format에 의해 지정된 항목수, 이 format과 호환가능한 SAS 버전, 생성 일자와 시간 등

Chapter 8. Creating Enhanced List and Summary

□ List Report 생성

ㅇ Nowindows/Nowd 옵션 : output 창에 표시

(Windows/Wd 옵션은 report창에 표시하며, Wd옵션이 default임)

ex) proc report data=flights.europe nowd;

□ 변수 및 관측치 선택

ㅇ proc report에서는 column statement로 변수 선택하고, where statement로 관측치 선택

ex) proc report data=flights.europe nowd;

column flight orig dest mail freight revenue;

where dest in ('LON','PAR');

run;

□ 변수 정의

ㅇ define 구문의 형식은,

- define 컬럼명 / 옵션1 옵션2...

ㅇ proc report에서는 define statement를 활용하여 변수 표시 방법 설정

- format옵션으로 format 설정(format=comma9.2 등)

- 컬럼의 길이는 별도 format이 설정 안된 경우, 문자 변수명은 그 문자 변수값의 길이, 숫자 변수명은 9임

* 숫자 컬럼은, default 컬럼명은 9, 컬럼값은 8임에 유의

ex) flight라는 변수에 format이 없고, 관측값이 문자로 821 처럼 3자리라면, SAS listing output에서 flight 변수명은 2줄로 표시됨(∵ format이 없고, 문자형이므로 그 문자 변수값의 길이인 3자리 적용)

※ HTML ouptput은 HTML 컬럼이 그 내용의 길이를 따라감

- 리포트에서 컬럼 길이 설정을 위해서는 width 옵션 활용

(※width 옵션은 HTML output에서는 영향 없음에 유의)

- 컬럼 사이의 공간은 spacing 옵션으로 제어

· spacing 옵션은 선택한 변수와, 그 바로 왼쪽에 있는 변수 사이의 공간을 제어

· default column spacing은 2

· spacing 옵션은 HTML output에는 영향 미치지 않음에 유의

- 컬럼명(Heading) 정의 가능 : define statement에서 따옴표 사이에 원하는 컬럼명을 넣으면 됨

· 컬럼명이 너무 긴 경우에는 split 문자로 줄 변경 가능

(default는 ‘/’이며, proc report의 split 옵션으로 별도 spilt 문자 지정 가능(* 등))

※ SAS listing에서는 컬럼명의 줄이 바뀌나, HTML report에서는 바뀌지 않음에 유의

- 컬럼 정렬 : define statement에 center/left/right 옵션으로 정렬 가능

- Headline과 Headskip 옵션으로 컬럼명(Heading)의 모양 변경 가능

· Headline은 컬럼명 아래에 밑줄 처리

· Headskip은 headline 옵션이 적용되었을 때 아래 위로 공백(빈줄) 처리

※ Headline과 headskip은 HTML output에서는 미적용

ex) proc report data=flights.europe nowd spilt='*' headline headskip;

column flight orig dest mail freight revenue;

where dest in ('LON','PAR');

define revenue / format= dollar15.2;

define orig / width=4 spacing=5; (※orig와 flight 사이의 공간이 5)

define flight / width=13 'flight*number' center;

□ 변수의 용법(usage) 정의

ㅇ proc report는 변수를 6가지(Display, Order, Group, Across, Analysis, Computed) 중 하나로 적용

- default로 문자변수는 display 변수로, 숫자 변수는 analysis로 변수로 적용

· analysis 변수는 SUM과 같은 통계량을 계산하는데 활용됨

- Order 변수는 오름차순으로 정렬되는데, 정렬된 컬럼에서 컬럼값이 같은 경우 맨 위의 1개씩만 표시됨

· 내림차순으로 정렬시에는 order descending 적용

- group 변수는 summary report 생성시 활용되며, group 변수 말고, summary report에서 요약되는 변수(default로 sum 처리되는 변수)가 문자 변수(display)인 경우에는 안됨 : 모든 문자 변수를 group 변수로 처리하면 가능(※group 변수 처리는 엑셀의 피벗 기능과 유사)

· summary report의 변수는 group, analysis, across, computed로 정의되어 있어야 하며, proc report가 group을 생성할 수 없을 경우에는 group 변수를 order 변수로 처리

· group이 생성된 경우, analysis 변수에 대한 default 통계량은 SUM이며, 다른 통계량을 원한다면 요약되는 변수에 통계량명을 지정하면 됨

< proc report의 통계량 >

구 분	설 명
CSS	Corrected sum of squares
USS	Uncorrected sum of squares
CV	coefficient of variation
MAX	Maximum value
MEAD	Average
MIN	Minimum value
N	Number of observations with nonmissing values
NMISS	Number of observations with missing values
RANGE	Range
STD	Standard deviation
STDERR	Standard error of the mean
SUM	Sum
SUMWGT	Sum of the weight variable values
PCTN	Percentage of a cell or row frequency to a total frequency
PCTSUM	Percentage of a cell or row sum to a total sum
VAR	Variance
T	Student's t for testing the hypothesis that the population mean is 0
PRT	Probability of a greater absolute value of student's t

- across 변수는 group 변수와 유사하나, group 변수는 vertical하게 표시하는 반면, across 변수는 horizontal하게 표시

- computed 변수는 report에 사용자가 정의하는 숫자 또는 문자 변수임

· computed 변수는,

1) column statement에 존재해야하고,

2) define statement에서 computed로 지정되어야 하며,

3) compute statement에서 ‘변수명.통계량‘의 형식으로 정의되어야 하고,

4) compute statement의 마무리는 'endcomp'로 함

ex) proc report data=flights.europe nowd;;

column flight capacity deplaned emptyseats;

define emptyseats / computed 'Empty Seats'

compute emptyseats;

emptyseats = capacity.sum - deplaned.sum;

endcomp;

run;

Chapter 9 : Producing Descriptive Statistics

□ Proc means

ㅇ Proc means은 각 변수에 대한 N(nonmissing 값의 수), Mean(평균), Std(표준편차), Min(최소값), Max(최대값) 제공

ㅇ 위의 다섯 개 통계량 말고도 추가 옵션으로 별도 통계량 조회 가능

< Proc mean 통계량 >

통계량	내용	통계량	내용
CLM	Two-sided confidence limit for the mean	SUMWGT	Sum of the weight variable value
CSS	Corrected sum of squares	UCLM	One-sided confidence limit above the mean
CV	Coefficient of variation	USS	uncorrected sum of squares
KURTOSIS/ KURT	Kurtosis	VAR	variance
LCLM	One-sided confidence limit below the mean	MEDIAN/ P50	Median of 50th percentile
MAX	Maximum value	P1	1st percentile
MEAN	Average	P5	5th percentile
MIN	Minimum value	P10	10th percentile
N	Number of observations with non-missing value	Q1/P25	lower quartile or 25th percentile
NMISS	Number of observations with missing value	Q3/P75	upper quartile or 75th percentile
RANGE	Range	P90	90th percentile
SKEWNESS/ SKEW	Skewness	P95	95th percentile
STDDEV/ STD	Standard deviation	P99	99th percentile
STDERR/ STDMEAN	Standard error of the mean	PROBIT	Probability of a greater absolute value for the t value
SUM	Sum	T	Student's t for testing the hypothesis that the population mean is 0

ㅇ 소수점 제한

- proc means은 default로 best. format 적용하므로, 불필요한 소수점이 표현될 수 있음

- proc means의 maxdec 옵션을 통해 소수점 제한 가능

ex) maxdec=0으로 하면 소수점 없이 정수자리까지만 표현

ㅇ 변수 선택

- var statement를 통해 분석을 원하는 변수 지정

- var statement에서는 개별 변수 뿐만 아니라 범위로도 지정 가능

ex) var item1-item5

ㅇ 그룹 처리

- class statement를 통해 ‘group by‘ 기능 구현 가능

· class 변수는 문자일 수도 있고, 숫자일 수도 있음

- by statement를 통해서도 ‘group by' 기능 구현 가능

· class와 by의 차이점은,

1) by statement는 변수가 먼저 proc sort로 정렬되어 있거나, index 처리 되어 있어야 함

※ proc sort 적용시 out=옵션쓰지 않으면 원래 데이터셋이 정렬된 값으로 저장됨에 유의

※ 그리고, by는 정렬되어 있으므로, 많은 변수가 있는 데이터 처리시에 더 효과적

2) by statement는 변수마다 작은 테이블을 구성하는 반면, class statement는 큰 하나의 테이블 구성

ㅇ 요약 데이터셋 생성

- 요약 변수만을 포함하는 output SAS 데이터셋을 output statement로 생성 가능

- output statement의 통계량= 키워드 생략시, 모든 변수에 대한 N, Mean, Std, Min, Max 통계량이 생성됨

․ 형식은, "output out = 데이터세명 통계량키워드=변수명"

(여기서의 변수는 var 구문에서 지정된 변수들이며,

변수명은 보고서에 표현을 원하는대로 바꿔도 됨)

ex.원래 변수는 weight인데, avgweight로 해도 됨

ex) proc means data=clinic.diabetes;

var age height weight;

class sex;

output out=work.sum_gender

mean=avgage avgheight avgweight

min=minage minheight minweight;

run;

→ sex로 그룹화하여 age, height, weight에 대한 N, mean, std, min, max를 표시하는 clinic.diabetes가 생성되고,

(proc means에 noprint 옵션 적용하면 리포트 미생성)

→ avgage, avgheight, avgweight, minage, minheight, minweight를 표시하는 work.sum_gender가 생성됨

(즉, work.sum_gender는 mean과 min만을 표시하며, proc print로 별도조회해야 함)

□ proc summary를 활용한 요약 데이터셋 생성

ㅇ 요약 데이터셋 생성은 proc means의 output statement 말고도, proc summary를 활용하여 생성 가능

- 차이점은, proc means는 기본적으로 report를 제공하지만(noprint 옵션으로 보고서 제한 가능), proc summary는 기본적으로 report를 제공하지 않는다는 점

→ proc summary에서는 'print' 옵션을 통해 report 조회 가능

ex) proc summary data=clinic.diabetes print;

var age height weitht;

class sex;

output out=work.sum_gender

mean=avgage avgheight avgweight;

-> 결과적으로, Proc mean과 Proc summary의 print 옵션 쓴 결과는 동일

□ Frequency table 생성(one way frequency table)

ㅇ proc frequency는 defalut로 모든 변수에 대한 빈도, 퍼센트, 누적 빈도, 누적 퍼센트 산출

ㅇ 특정 변수만 지정시에는 var statement가 아닌, tables statement 사용

- 범위로도 지정 가능 : ex. tables item1-item3;

- tables statement에 nocum 옵션 적용하면 누적 빈도와 누적 퍼센트 미표시

□ Frequency table 생성(n way frequency table)

ㅇ table A*B; 적용시 A 변수를 행으로, B 변수를 열로 하는 frequency table 생성되며, 셀의 빈도/퍼센트/행 퍼센트/열 퍼센트 표시

ㅇ table A*B*C; 처럼 3 way 이상일 경우에는, 가장 우측에 있는 두   변수인 B와 C를 활용하여 2 way frequency table이 생성되고, 그 왼쪽에 있는 변수들은(A) level 생성

→ 즉, A별로 B*C의 2 way frequecy table 생성

ㅇ table statement의 crosslist 옵션 사용시, n way frequency table report가 아닌, list 형식의 report 생성

ex) tables sex*weight*height / crosslist

- crosslist 옵션 대신 list 옵션 적용시, 빈도가 0인 셀은 제외하고 표시됨

□ 테이블의 정보 제한

ㅇ n way frequency table에서는 셀 빈도, 퍼센트, 행 퍼센트, 열 퍼센트가 default로 표시되며, tables statement에 다음의 옵션 처리를 통해 표시 제한 가능

- nofreq : 셀 빈도 표시 제한

- nopercent : 셀 퍼센트 표시 제한

- norow : 행 퍼센트 표시 제한

- nocol : 열 퍼센트 표시 제한

Chapter 10 : Producing HTML Output

□ ODS(Output Delivery System)를 활용하여 HTML output, 프로시져   결과에 대한 output 데이터셋, SAS listing output를 포함한 다양한  형식의 output을 쉽게 생성 가능

□ ODS로 다음의 output 생성 가능하며, default는 SAS listing output임

ㅇ HTML

ㅇ Listing (Traditional SAS procedure(listing) output)

ㅇ Markup Language Family (XML 등)

ㅇ ODS Document

ㅇ Output (SAS dataset)

ㅇ Printer Family (PDF 등)

ㅇ RTF (Rich Text Format output for MS-WORD)

ex) ods html body = 'c:\mydata.html';

proc print data=sasuser.mydata;

run;

ods html close;

→ ODS는 열고(open) 닫았음(close)에 유의

※ listing은 default로 열리고, 열려있는 ods는 시스템 리소스를 차지하므로,  프로그램의 시작 부분에서 listing ods를 닫아주는 것이 좋으며, 다시 ODS를 켜거나 SAS이 종료되기 전까지는 계속 닫혀 있으므로, 프로그램의 맨 마지막에는 listing ods를 다시 켜주는 것이 좋음

ex) ods listing close;                   → 맨 처음 listing 닫음

ods html body='c:\mydata.html';   → html 열음

proc princ data=sasuser.mydata;

run;

ods html close;                   → html 닫음

ods listing;                        → listing 열음

→ HTML output만 생성함

□ 동시에 공존하는 다수의 ODS 닫기

ㅇ ods close statement에 _all_ 키워드를 적용하여 여러개의 ODS를   한번에 닫을 수 있음

ex) ods html file='html-file-pathname';

ods pdf file='pdf-file-pathname';

proc print data=sasuser.html;

run;

ods _all_ close;

ods listing;

□ HTML ODS 생성

ㅇ ods HTML body='경로‘;

또는 ods html file='경로‘ (※body는 file의 다른 명칭)

ex) ods listing close;

ods html body='f:\admit.html';

proc print data=clinic.admit label;

var sex age height weight actlevel;

label actlevel='activity level';

run;

ods html close;

ods listing;

→ Proc print을 HTML file로 생성하며, f:\admit.html에 결과 저장

(admit.html은 ods html과 ods html close 사이의 모든 프로시져에 대한 결과를 포함)

ㅇ 하나의 ods statement 안에 여러 개의 procedure 써도 됨

- 실행 결과들이 html output에 각각 첨부됨

ㅇ ods html의 파일 위치를 설정하는 body 옵션 뒤에 contents 옵션과 frame 옵션을 활용함으로써 프레임 파일 구현 가능

이부분 추가 확인 필요.p254 ~ p258'

□ HTML output의 외관 변경

ㅇ ODS HTML statement의 style 옵션 활용

ex) ods listing close;

ods html body='c:\record\data.html' (url='data.html')

contents='c:\record\toc.html' (url='toc.html')

frame='c:\record\frame.html'

style=brick;

→ 벽돌 무늬 스타일 적용

□ 부가 기능

ㅇ HTML output 커스터마이징

- proc template를 활용하여 원하는 스타일 적용 가능

Chapter 11. Creating and Manageing Variables

□ 누적 합계

ㅇ sum statement 활용

- 키워드로 시작하지 않는 몇 개 안되는 SAS 구문

- 형식은 ‘variable + expression'

․ variable은 누적변수명으로 숫자이어야 하고, default는 0임

(variable은 쓰기 나름. sumsec, totalsec.. 등등)

․ expression의 값을 variable에 누적시킴

ㅇ data step에 sum statement를 써서 누적 합계 계산 가능

(※ Proc print의 sum statement와 다름에 유의)

ex) data clinic.stress;

infile stress;

input ID $ 1-4 name $ 6-25 resthr 27-29 timemin 30-31              timesec 33-34;

totaltime = (timemin*60)+timesec;

sumsec+totaltime;

→ sum statement(sumsec+totaltime;)에 의한 sumsec은 0에서 시작하여 누적됨(Default로 0에서 시작)

* 0이 아닌 특정값에서 시작하기를 원하는 경우 retain statement 적용하면 됨

ex) totaltime = (timemin*60)+timesec;

retain sumsec 5400;

sumsec+totaltime;

→ sumsec라는 누적변수를 만들었으며, 이는 0이 아닌 5,400에서   시작하여 누적됨

□ 조건부 변수 할당

ㅇ if-then statement를 활용하여 조건별로 변수 할당 가능

ex) if totaltime>800 then testlength='long';

if 750<=totaltime<=800 then testlength='normal';

if totaltime<750 then testlength='short';

→이렇게도 적용할 수 있으나, 이는 시스템 자원을 잡아먹고 오래 걸리므로, 다음과 같이 else 적용

(※ else statement는 앞의 if-then/else statement가 false값일때만 실행)

ex) if totaltime>800 then testlength='long';

else if 750<=totaltime<=800 then testlength='normal';

else if totaltime<750 then testlength='short';

ㅇ put statement를 활용하여 검증 가능

ex) data clinic.stress;

infile stress;

input ID $ 1-4 name $ 6-25 resthr 27-29 timemin 30-31              timesec 33-34;

totaltime = (timemin*60)+timesec;

retain sumsec 5400;

sumsec+totaltime;

if totaltime>800 then testlength='long';

else if 750<=totaltime<=800 then testlength='normal';

else if 120<=totaltime<750 then testlength='short';

else put 'Note: Check this Length :' totaltime=;

run;

→ 6장에서 공부했듯이, Log에 메시지와 totaltime 값 표시

□ 변수의 길이 설정

ㅇ 앞의 예시에서, 할당 구문에 의해 새 변수인 testlength를 만들 때, SAS는 해당 변수에 대해 첫 번째로 접하게 되는 값의 길이를 그   변수의 길이로 설정함

- 위의 예시에서는 long을 처음 만나므로, testlength의 길이는 4가 되며, normal과 short은 줄여져 각각 norm, shor으로 표시됨

ㅇ length statement를 통해 변수의 길이 설정 가능하며, 문자 변수에는 변수명 뒤에 $ 표시 추가

예시) length type $ 8;

length address1 ardress2 address3 $ 200;

length address $ 12 lastname $ 16

- Length statement는 변수 할당 전에 적용되어야 함에 유의

ex) length testlength $ 6;

if totaltime>800 then testlength='long';

else if 750<=totaltime<=800 then testlength='normal';

else if 120<=totaltime<750 then testlength='short';

else put 'Note: Check this Length :' totaltime=;

□ 데이터 분할하기(subset)

ㅇ if-then statement에 delete statement를 적용하여 생성하는 데이터 셋에서 관측치 생략 가능

ex) if resthr < 70 then delete;

□ drop= 및 keep= 옵션을 활용한 변수 선택

ㅇ data step의 drop=변수명, keep=변수명 옵션 또는 drop/keep statement를 통해 변수 선택 또는 제거 가능

ex) data clinic.stress (drop=timemin timesec)

ex) data clinic.stress;

infile stress;

input ID $ 1-4 name $ 6-25 resthr 27-29 timemin 30-31              timesec 33-34;

drop timemin timesec;

totaltime = (timemin*60)+timesec;

retain sumsec 5400;

sumsec+totaltime;

if totaltime>800 then testlength='long';

else if 750<=totaltime<=800 then testlength='normal';

else if 120<=totaltime<750 then testlength='short';

else put 'Note: Check this Length :' totaltime=;

run;

□ 영구적 label/format 설정

ㅇ 4장에서 공부했듯이, label/format은 print step에 적용하면 temporarily, data step에 적용하면 permanent함

※ 또한, label/format은 데이터가 저장되는 것에 영향미치는 것이 아니라, output에서 어떻게 보여지는가에 영향미치는 것임에 유의

ㅇ data step에 적용하든, print step에 적용하든 output에서 label이 조회되도록 하려면, proc print에서 label 옵션 적용해야 함

- proc step에 적용한 temporarily label/format은 data step의 permamant label/format에 우선시됨

□ select groups를 활용한 조건적 변수 할당

ㅇ if-then/else statement와 유사하며, 다음의 기준에 의거하여 판단

- 다량의 상호 배타적인 조건이고 숫자인 경우 select group을 활용하는 것이 더 CPU time이 적게 걸리며, 읽고 debug하는 것도 편리

ex) select (A) ;

when (1) x=x*10;

when (3,4,5) x=x*100;

otherwise;

ex) end;

→ 변수 A가 1인 경우 x는 10배, 3~5인 경우 100배 처리하고, 2이거나 나머지의 경우에는 아무런 처리 없음

ex) data emps (keep=salary group);

set sasuser.payrollmaster;

length group $ 20;

select (jobcode);

when ("FA1") group ="Flight attendant I";

when ("FA2") group ="Flight attendant II";

otherwise group="other";

end;

run;

→ 위의 예시에서 length=20으로 설정 안하면, 첫번째 변수값인 Flight attendant I의 길이가 적용됨에 유의

→ 대소문자를 구분해야 함. fa1로 적용하면 otherwise로 분류됨

ㅇ select statement에서는 select 바로 뒤의 변수명 지정 여부에 따라 when 이하에서의 적용 변수가 달라짐

1) 변수명 지정한 경우

ex) select (toy);

when ("BEAR") price=35.00;

when ("VIOLIN") price=139.00;'

otherwise put "check unknown toy:" toy=;

ex) end;

→ when에서는 toy 변수만을 관측하며, otherwise의 경우 put을 적용하였으므로 log 표시

2) 변수명 지정 안한 경우

ex) select;

when (toy="BEAR" and month in ('OCT','NOV','DEC'))

price=45.00;

when (toy="BEAR" and month in ('JAN','FEB'))

price=25.00;

when (toy="BEAR") price=35.00;

otherwise;

ex) end;

→ toy가 BEAR이고 월이 FEB인 경우 두 번째와 세 번째  when 구문에서 true이나, 첫 번째 true인 두 번째 when이 적용되어 price=25.00이 됨

□ Do group를 활용한 그룹핑

ㅇ if-then/else나 select group에 do를 적용 가능

ex) if totaltime > 800 then

do;

testlength='long';

message = 'Run blood panel';

end;

else if 750<=totaltime<=800 then testlength='normal';

ex) select (payclass);

when ('monthly') amt='salary';

when ('hourly')

do;

amt=hrlywage*min(hrs,40);

if hrs>40 then put 'Check timecard';

end;

otherwise put 'Problem observation';

end;

Chapter 12 : Reading SAS DAta Sets

□ 하나의 데이터셋 읽기

ㅇ set statement를 활용하여 기존에 존재하는 데이터셋으로부터 데이터 읽음

ex) data lab23.drug1h;          ← 저장하는 데이터셋

set research.cltrials;        ← 읽어오는 데이터셋

run;

□ drop= / Keep= 옵션의 위치

ㅇ drop=/keep=은 data step의 옵션 또는 drop/keep statement로 적용할 수 있으며,

ㅇ 기 존재하는 데이터셋으로부터 데이터를 읽을 때는 data statement와 set statement에 적용 가능

- 어떤 변수를 따로 처리하지 않고, 새 데이터셋에 보이는 것을 원치 않으면 drop=옵션을 set statement에 적용

(읽어올 때부터 drop)

- 어떤 변수를 if 등으로 따로 처리한다면, drop=옵션을 data statement에 적용

(처리 다 하고, 저장되는 새 데이터셋에서만 drop되는 것이고,

여전히 원 데이터셋으로부터 읽혀져 있고, data step 내에서 이용 가능)

→ 어느 경우에서나, keep되는 변수보다 drop되는 변수가 더 많으면, drop 대신 keep 활용 가능

□ By-Group 처리

이부분 어려움..추가 확인 필요

ㅇ proc sort에서 by를 쓰면 정렬이 되며, data step에서 set statement와 by를 쓰면 그룹 처리가 됨

- set statement의 데이터셋은 by 변수로 정렬되어 있어야 함(proc sort로 정렬)

- data step은 first.변수명, last.변수명 2개의 임시 변수 생성

․ first.변수명은 첫 번째 관측치에서 1, 나머지에서는 0

․ last.변수명은 마지막 관측치에서 1, 나머지에서는 0

(※ first.변수명과 last.변수명은 by 처리되는 변수들임)

ex) proc sort data=company.usa out=work.temp;

by dept;                                   -> 먼저 정렬(sort)

run;

data company.budget(keep=dept payroll);

set work.temp;

by dept;                                   -> By-group 처리

if wagecat='S' then yearly=wagerate*12;

else if wagecat='H' then yearly=wagerate*2000;

if first.dept then payroll=0;

payroll+yearly;

if last.dept;    (※ last.dept=1인것만 대상으로 함 -> 후술(13장)

run;

proc print data=company.budget noobs;

sum payroll;  (※ 가장 아래 줄에 payroll의 합계 기재)

format payroll dollar12.2;

run;

→ detp별로 payroll의 합계가 계산됨

ㅇ 여러 개의 by변수 적용도 가능

□ 직접 접근을 통한 특정 관측치 불러오기

ㅇ point 옵션을 활용하여 관측치를 obsnum을 통해 직접 접근 가능

- point 변수는 임시 숫자 변수이어야 하며, obsnum이 당연히 대표적

ex) data work.getobss5;

obsnum=5;

set company.usa(keep manager payroll) point=obsnum;

run;

→ Data step은 input 데이터의 end-of-file marker(※6장 참고)를  만나야 관측치 불러오기를 멈추는데, 위의 예시에는 point 옵션을 활용해 관측치를 제한했으므로 end-of-file marker를 만날 수 없고, 순환 loop 에러

ㅇ point 옵션을 쓸 때는 그래서 stop statement를 써야 함

ex) data work.getobss5;

obsnum=5;

set company.usa(keep manager payroll) point=obsnum;

output;

stop;

run;

→ 더 이상 순환 loop 에러는 발생하지 않지만, data step은 step의 맨 마지막에 관측치를 output으로 저장하므로, 관측치도 output에 저장되지 않으므로, stop 전에 output statement를 서야 함

- output statement 뒤에 데이터셋 명을 쓰지 않으면, data step에 적어진 모든 데이터셋에(위의 예시에서는 work.getobss5) 관측치가 저장됨에 유의

․ output statement 뒤에 쓰이는 데이터셋은, data statement에 있어야 함

예시) data empty full;

set company.use;

output full;

run;

→ 이 경우에는 data step이 empty와 full 2개의 데이터셋을 생성하나, empty는 생성만 될 뿐 관측치가 하나도 저장되지 않고, 모든 관측치는 full에 저장됨

→ 결국, 위의 예시는 obsnum이 5인 관측치만 work.getobss5에 저장

□ 데이터셋의 끝 찾기

ㅇ data step의 set statement에서 end 옵션을 씀으로써 데이터의 마지막 관측치 조회 가능

※ end 옵션과 point 옵션을 같이 쓰지 말 것. point 옵션은 특정  관측치만 조회하는 것이므로 데이터셋의 마지막 관측치를 볼 수 없음

ex) data work.addtoend(drop=timemin timesec);

set work.stress2 (keep=timemin timesec);

totalmin+timemin;

totalsec+timesec;                 -> 11장의 sum statement

totaltime=summin*60+sumsec;        (totalsec은 생성시킨 누적변수)

run                                  (timsesec은 기존재 변수)

proc print data=work.addtoend;

run;

→ set의 keep에 의해 timemin과 timesec만 불러오며, 이를 활용해 totalmin, totalsec, totaltime을 생성(할당)하고, data의 drop에서 timemin과 timesec을 제외하므로, 최종적으로는, totalmin, totalsec, totaltime만 work.addtoend에 존재함

- 위의 예시에서 마지막 관측치만 조회하고 싶다면, set statement에 end=last 적고, last는 필요한 곳에 기재(아래 예시에서는 if에)

ex) data work.addtoend(drop=timemin timesec);

set work.stress2 (keep=timemin timesec) end=last;

totalmin+timemin;

totalsec+timesec;

totaltime=summin*60+sumsec;

if last;

run;

proc print data=work.addtoend;

run;

→ set에 end=last만 적용하면 결과는 같고, 아래에 if last;를 적용해야 마지막 관측치만 조회됨에 유의

SAS에서 If 구문에 변수명만 true일 경우를 의미. 13장 확인 및 실습 필요

Chapter 13 : Combining SAS Data Sets

□ 데이터셋 결합의 방법 4가지

구분

예시

One-to-one reading

- 각각의 데이터셋의 상대적 위치 기준 결합

- set statement

Dataset C				Dataset D
Num	Var A			Num		Var B
1	A1			2		B1
3	A2			4		B2
5	A3
Combined Dataset
Num		Var A			Var B
2		A1			B1
4		A2			B2

Concatenating

- 데이터셋끼리 세로로 붙이기

- set statement

Dataset A				Dataset D
Num	Var A			Num		Var B
1	A1			1		B1
2	A2			2		B2
3	A3			4		B3
Combined Dataset
Num		Var A			Var B
1		A1
2		A2
3		A3
1					B1
2					B2
4					B3

Interleaving

- 공통 변수 기준으로 데이터 끼워넣기

- set, by statement

Dataset C				Dataset D
Num	Var			Num	Var
1	C1			2	D1
2	C2			3	D2
2	C3			3	D3
3	C4
Combined Dataset
Num		Var
1		C1
2		C2
3		C3
2		D1
3		C4
3		D2
3		D3

Match-merging

- 공통 변수 기준으로 데이터 매치

- merge, by statement

Dataset A				Dataset B
Num	Var A			Num		Var B
1	A1			1		B1
2	A2			2		B2
3	A3			4		B3
Combined Dataset
Num		Var A			Var B
1		A1			B1
2		A2			B2
3		A3
4					B3

□ One-to-One Reading

ㅇ set을 활용하여 데이터 결합

ㅇ 새 데이터셋은 모든 input 데이터셋의 모든 변수들을 포함

- 원래 데이터셋들에 변수명이 같은 변수가 있다면, 마지막 데이터셋의 값이 업데이트됨

ㅇ 새 데이터셋의 관측치 개수는 원래 데이터셋 중 관측치가 작은 데이터셋의 관측치 수가 됨(※one-to-one reading은 join과는 무관한 개념인듯)

ex) data one2one;

set c;

set d;

run;

→ c가 9개, d가 6개의 관측치를 가지고 있다면, one2one은 6개의 변수를 가지게 됨

□ Concatenating(연관화)

ㅇ set을 활용하여 horizontal하게 데이터 결합

ㅇ 연관화하는 두 개의 데이터셋에 공통 변수가 있어야하며, 공통변수는 type 특성이 같아야 함

- 만약 length 특성이 다르다면, SAS는 첫 번째 데이터셋에 있는 공통변수의 길이를 취함

· 이는 label/format/informat에 대해서도 마찬가지

ㅇ 새 데이터셋은 모든 input 데이터셋의 모든 변수들을 포함하며, 세로로 모든 관측치를  적재

(※Concatenating 또한 join과는 무관한 개념)

ex) data concat;

set a b;

run;

→ a에 있는 모든 관측치와 b에 있는 모든 관측치 가져옴. 예를 들어 a에 3개(ID와 Var1), b에 3개(ID와 Var2)의 관측치가 있었다면, concat(공통변수 ID, Var1, Var2)은 6개의 관측치 보유

□ Interleaving(끼우기)

index 처리된 data가 무엇인가?

ㅇ set과 by를 활용하여 데이터를 horizontal하게 껴 넣으면서 적재

ㅇ by 변수의 순서대로 set statement의 데이터셋 순서로 끼워넣음

ㅇ 새 데이터셋은 input 데이터셋의 모든 변수 및 모든 관측치를 포함

(※interleaving 역시 join과는 무관한 개념)

ex) data interlv;

set c d;

by num;

run;

□ Merge

ㅇ merge와 by를 활용하여 데이터를 가로로 병합

ㅇ input data는 by 변수로 정렬되어 있어야 함(proc sort 활용)

- merge는 기본적으로 오름차순이며, 내림차순의 경우에는 descending 옵션을 달아야 함(proc sort에도)

· 단, index 처리된 data는 항상 오름차순이므로, descending 옵션 사용 불가

ex) data merged;

merge a b;

by num;

run;

※ 컬럼명이 같은 변수가 나오면, length는 처음 데이터셋의 것을 따라가고, 컬럼값은 마지막 데이터셋의 값을 따라감에 유의

앞의 어느 파트에서 나오는지 확인 필요

□ 변수명 변경

ㅇ merge 등의 경우 변수명이 같으면 overwriting되므로, merge statement의 rename 옵션을 활용하여 겹치는 변수명을 변경

ex) data clinic.merged;

merge clinic.demog(rename=(date=birthdate))

merge clinic.visit(rename=(date=visitdate));

by id

run;

→ clinic.demog와 clinic.visit에는 date 컬럼이 겹치므로, 각각 birstdate, visitdate로 변경

□ Temporary In=변수 생성

ㅇ 양 쪽 데이터셋에 모두 존재하는 관측치들만을 match-merge하고 싶은 경우, 임시 변수인 in=변수 활용

- 임시변수인 in=변수는 현재 데이터셋에 있으면 1, 없으면 0

ex) data clinic.merged;

merge clinic.demog(in=indemog

rename=(date=birthdate))

merge clinic.visit(in=invisit

rename=(date=visitdate));

by id

if indemog=1 and invisit=1

(※ 또는, if demog and invisit 이라고 적어도 됨)

run;

→ clinic.demog에 있으면 1, 없으면 0이 되는 indemog라는 임시 변수 생성하고, 마찬가지로 invisit 생성

→ 그리고 나서 if문으로 1인 것들만(존재하는 것들만) 추출하도록 함

※ SAS에서의 if statement

: if 문은, 0이 아니거나(non-zero) 결측치가 아닌(non-missing) 값은 true,

0이거나(zero) 결측치(missing)는 false 처리함에 유의

12장 내용 확인할 것

□ 변수 선택

ㅇ drop/keep 옵션은 data statement에서도 쓸 수 있고, merge statement에서도 쓸 수 있으나, 내부에서 계산에 활용되는 변수는 data statement에서만 drop해야 함에 유의

- 예를 들어, by id라고 한 경우, id 변수는 merge에서 drop하면 안됨

□ 부가 기능

ㅇ one-to-one merging은 두 가지를 제외하고는 one-to-one reading과 동일

- one-to-one merging은 모든 관측치를 포함하고, merge statement를 쓰는 반면,

- one-to-one reading은 관측치가 작은 데이터셋의 개수만큼만 관측치 수를 가져가며, set statement 사용

Chapter 14 : Transforming Data with SAS Functions

□ SAS 함수의 일반적 형식

ㅇ 「함수명(인자1, 인자2...)」의 형식이며 인자가 없더라도 today()처럼   괄호는 필요

- 몇몇 함수에서는 인자의 나열 대신 of를 활용한 배열도 OK

ex) mean(X1, X2, X3)

= mean(of X1-X3)

※ mean(X1-X3)는 X1 minus X3의 평균임에 유의

ㅇ 문자 함수로 생성된 변수의 default 길이는 200

□ 함수를 활용한 데이터 변환

ㅇ salary = payrate * hours라고 한 경우, payrate와 hours가 모두 숫자 변수여야 계산 가능

ㅇ 문자 → 숫자 변환

1) 자동 변환

- SAS는 계산 함수에서 문자/숫자 변수의 불일치가 발생하는 경우 자동으로 문자 ↔ 숫자 변환 실시

․ 그러나, $ 표시가 있는 경우 등은 변환되지 않음에 유의

․ 자동 변환은 문자 → 숫자 변환의 경우 w.d informat을 활용하며, 천단위 콤마 등으로 표준 숫자 표시에 위배되는 경우에는 결측치로 처리

※ 따라서 자동 변환에 너무 의지하지 않는 것이 좋음

< 문자 → 숫자 자동 변환의 예시 >

문자값	12.47	-8.96	1.243E1	1,742.64
▼
숫자값	12.47	-8.96	1.243

․ 또한 where 구문에서는 자동 변환 처리 안됨

ex. number가 숫자 변수인데 where number='4'라고 처리한 경우, 처리 안되고 에러 표시

2) input을 활용한 직접 변환

- salary = payrate * hours에서 payrate가 문자 변수여서 처리가 안된다면, salary = input(payrate,2.)*hours처럼 payrate를 숫자 변수로 변환후 처리

구 분	input	put
용도	문자 → 숫자	숫자 → 문자
형식	informat informat와 format의 차이 확인 필요 : informat은 불러들일때, format은 출력할 때	format

ㅇ 숫자 → 문자 변환

1) 자동 변환

- ∥ 등 문자변수를 필요로 하는 연산자가 있는 경우, 문자 인수를 필요로 하는 substr 같은 함수 등에서는 숫자 → 문자 자동 변환

ex) assignment = site∥'/'∥dept

(※ 모든 문자는 따옴표 처리가 되어야 하므로, /에 따옴표 처리되어 있음에 유의)

․ SAS는 자동변환시 숫자 변수를 BEST12. format으로 저장하며, 원 숫자값의 자리수가 12보다 작은 경우 변환된 문자값은   공백을 포함하게 되어 문제를 일으킬 수 있음

2) put을 활용한 직접 변환

- assignment = site∥'/'∥dept 에서는 자동 변환이 일어나나, put을 활용해서 명확하게 처리하는 것이 더 좋음

․ assignment = put(site, 2.)∥'/'∥dept

□ 함수로 SAS 날짜 값 다루기

ㅇ SAS는 date를 1960.1.1 부터의 일수로 저장하며, time은 자정부터의 초로 저장

- datetime은 따라서 1960.1.1 자정부터의 초수로 저장됨

ㅇ 그러므로 날짜/시간이 저장된 데이터셋을 그대로 조회하면 안되고, proc print에서 날짜/시간 관련 format을 적용해서 조회해야 함

< 날짜 관련 주요 함수 >

함수	활용 방법	결과
MDY	date=mdy(mon,day,yr)	SAS date
TODAY / DATE	now=today() / now=date()	오늘의 날짜를 now로
TIME	curtime=time()	현재 시간을 curtime으로
DAY	day=day(date)	날짜(1~31)
QTR	quarter=qtr(date)	분기(1~4)
WEEKDAY	wkday=weekday(date)	요일(1(일)~7(토))
MONTH	month=month(date)	월(1~12)
YEAR	yr=year(date)	연도(4자리)
INTCK	x=intck('day',d1,d2) x=intck('week',d1,d2) x=intck('month',d1,d2) x=intck('qtr',d1,d2) x=intck('year',d1,d2)	d1에서 d2까지의 일수 d1에서 d2까지의 주수 d1에서 d2까지의 월수 d1에서 d2까지의 분기수 d1에서 d2까지의 년수
INTNX	x=intnx('interval',start-from, increment)	date, time, datetime값
DATDIF / YRDIF	x=datdif(d1,d2,act/act) x=yrdif(d1,d2,act/act)	d1에서 d2까지의 일수 d1에서 d2까지의 년수

□ Weekday함수

ㅇ 일요일이 1, 토요일이 7임에 유의

□ MDY함수 (※mdy(1,1,1960) = 0임에 유의)

ㅇ 월, 일, 연 변수로부터 date 변수를 생성(mdy(월,일,연도)하는 함수

(※가능하면 연도는 4자리로 입력)

ㅇ mdy(6,17,2002)처럼 날짜를 직접 입력하면 그 날짜를 SAS형식의 숫자로 저장함(ex. 14232 등)

ㅇ mdy(15,31,2002)처럼 부적확한 값을 입력하면 error처리하여 결측값 처리

(∵ 15월은 없으므로)

□ Date함수와 Today함수

ㅇ 시스템 날짜를 산출하는 함수로, 결과는 같음

- date() = today()

ㅇ 두 함수는 인자가 필요 없으나, 괄호는 여전히 필요

□ INTCK함수

ㅇ INTCK함수는 실제 연/월/일 등의 구간 값이 아니라, 정해진 구간에 의해 계산 수행

- week는 7일이 아닌 일요일 기준

- month는 매달 1일 기준

- year는 매년 1월 1일 기준

< INTCK함수 예시 >

예시	값
intck('week', '31dec2000'd, '01jan2001'd);	0
intck('month','31dec2000'd,'01jan2001'd);	1
intck('year','31dec2000'd,'01jan2001'd);	1
intck('year','15jun1999'd,'15jun2001'd);	2
intck('year','01jan2002'd,'31dec2002'd);	0

.

※ 날짜(ddmmyyyy)에 따옴표 처리하고 뒤에 d를 붙이면 날짜 상수로 처리하는 것

□ INTNX함수

ㅇ INTCK함수와 유사하나, 주어진 일자/시간 등으로부터 주어진 조건 가감

- 1960.1.1 기준으로 계산되나, INTNX에 'b'/'m'/'e'를 붙임으로써   기간 초/중/말 설정 가능

< INTNX함수 예시 >

예시	값
intnx('year','05feb94'd,3)	01jan97
intnx('semiyear','01jan01'd,1)	01jul01
intnx('month',01jan95'd,'5','b')	01jun95
intnx('month',01jan95'd,'5','m')	15jun95
intnx('month',01jan95'd,'5','e')	30jun95

.

□ 함수를 활용한 문자 값 수정

<SAS의 주요 문자 함수>

함수	설명
SCAN	returns a specified word from a character value
SUBSTR	extracts a substring or replaces character values
TRIM	trims trailing blanks from character values
CATX	concatenates character strings, removes leading and trailing blanks, and inserts separators
INDEX	searches a character value for a specific string
FIND	searches for a specific substring of characters within a character string that you specify
UPCASE	converts all letters in a value to uppercase
LOWCASE	converts all letters in a value to lowercase
PROPCASE	converts all letters in a value to proper case
TRANWRD	replaces or removes all occurrences of a pattern of characters within a character string

ㅇ SCAN함수

- 변수에서 구분자를 기준으로 파트 추출

․ default 구분자에는 blank . , < ( + │ & ! $ * ) ; ^ - / % 등이 있음

- 예시) scan(name, 1, ',') : name에서 콤마를 기준으로 첫 번째 파트 추출

※ ,는 기본 구분자이므로 scan(name, 1) 이렇게 적어도 됨

ex) lastname = scan(name,1,',');

lastname = scan(name,1)

※ 구분자를 지정안하면 default로 blank와 콤마(,)가 지정됨

ㅇ 변수의 길이 설정

- scan 함수는 defalut로 200의 길이를 할당하므로, length 함수를 통해 변수의 길이를 지정하고, 시스템 저장 공간을 확보하는 것이 좋음

□ substr함수

ㅇ 문자 변수에서 특정 부분 추출하거나, 특정 부분의 내용을 대체

- 할당문의 오른쪽에 substr함수가 있으면 특정 부분 추출

· middleinitial = substr(middlename,1,1);

- 할당문의 왼쪽에 있으면 내용 대체

· substr(test,4,2) = '92';

※ scan과 substr의 차이는, scan은 구분자를 기준으로 부분을 추출하나, substr은 특정 위치를 기준으로 부분을 추출한다는 점

※ 그리고, B=substr(A,1,3) 했을 때, A의 길이가 12라면, B의 길이도 12

□ trim 함수

ㅇ 문자 변수에서 trailing blank 제거

※ SAS에서 문자 변수의 값이 그 변수의 길이에 맞지 않을 경우,   공백으로 채워짐에 유의. 예를 들어, test라는 변수의 length가 10인데, 어떤 변수 값이 sample(길이 6)이라면, 4개의 공백이 포함됨

- 또한, trim 함수는 변수가 저장되는 부분에 영향 미치는 것은 아니라는 점에 유의해야 함

ex) data temp;

set hrd.temp;

length street $ 20;

street = trim(address);

run;

→ address는 trim되어 공백이 없어졌으나, 할당된 street는 길이가 20이므로, trim(address)의 길이가 20이 안된다면, 차이나는  만큼은 공백으로 채워짐

□ CATX함수

ㅇ 문자 변수에서 trailing blank, leading blank, insert separator 제거하고 문자 부분을 결합

ㅇ 형식은, CATX(‘구분자’, 문자열1, 문자열2..)

ex) trim(address ‖ ', ' ‖ trim(city) ‖ ',' ‖ zip); = catx(',', address, city, zip);

□ Index 함수

ㅇ index 함수는 좌에서 우로 가며 특정 문자를 검색하고 발견시 그  문자의 첫 글자 위치를 제공

- 발견되지 않은 경우 0 표시

ex) if index(job, 'word processing') > 0;

→ job이라는 변수에서 'word processing'을 찾아서 있는 경우(즉, 결과값이 0이 아닌 경우)에만 처리)

※ index 함수는 대·소문자를 구분함에 유의

□ find 함수

ㅇ find는 index와 유사하나, find는 검색 조건을 직접 지정 가능하다는 점에서 더 강력

- ‘i'를 넣으면 대/소문자 무시하고, 안넣으면 구분함

· 즉, 'i'를 안넣으면 index처럼 정확한 값만 검색

- ‘t'를 넣으면 trailing blank 제거

trailing blank가 뒤의 공백인가?

ex) if find(job,'word processing','t') >0;  (※ 검색 조건은 따옴표 처리!)

□ 대/소문자 처리

ㅇ upcase함수 변수값을 모두 대문자로, lowcase함수는 변수값을 모두  소문자로 변경

ㅇ propcace함수는 변수값을 모두 소문자로 변경 후, 구분자로 구분된 문자의 맨 앞글자만 대문자 처리

※ 별도의 구분자를 지정하지 않는 경우, propcase함수는 default  구분자를 활용

default 구분자는 무엇인가?

ex) contact 변수의 값이 'ADMIN.ASST,'인 경우, propcate(contact)의 값은 ‘Admin.Asst')가 됨

□ tranwrd 함수

ㅇ 변수의 특정 값을 다른 값으로 대체(변환)

ex) name = tranwrd(name, 'Monroe', 'Manson');

→ name 변수에서 Monroe를 Manson으로 변경

□ 함수를 활용한 숫자 값 변경

ㅇ INT함수

- 숫자 변수에서 소수점 이하는 버림하고, 정수 부분만 가져 옴

ex) INT(326.54) = 326

ㅇ ROUND함수

- 특정 자리수에서 반올림

ex) ROUND(326.54, .2) ; 326.6

소수점 2자리에서 반올림하여, 소수점 1wkflRK지 표현한다는 것

- 반올림하는 부분이 안정해지면 정수로 반올림됨

Chapter 15 : Generating Data with DO Loops

□ Do Loops

ㅇ SAS 구문을 Do Loops에 위치시킴으로써 반복 실행 가능

□ Do loops의 일반 형식

ㅇ do rows=2 to 12 by 2

1) index variable 필요 : 위의 예시에서는 rows

2) Do loop를 실생시키는 조건 지정 : 위의 예시에서는 2 to 12

3) index variable에 대한 증가치 지정(선택적) : by를 지정안하면 default로 1씩 증가 : 위의 예시는 rows가 2에서 시작하여 12까지 2씩 증가

※ by -1이라고 하면 1씩 감소

- index variable 별도로 설정하고 data step에서 drop할 수도 있음

→ drop하든 안하든 아래의 예시는 최종 합계 한줄(year=20)만 표시됨

ex) data work.earn (drop =counter);

value =2000;

do counter=1 to 20;

interest = value*.075;

value+interest;               ※ sum statement인듯함

year+1;

end;

□ 명시적 Output statement

ㅇ 매 iteration별 관측치를 생성하기 위해서는 do loop 안에 output statement 지정

- default로 data step은 step의 마지막 부분에만 묵시적으로 output statement를 들고 가서 하나의 관찰값만을 생성하는데,   명시적으로 output statement를 적어주면 묵시적(자동) output에 우선시되어 모든 관찰값들이 저장됨

ex) data work.earn;

value =2000;

do counter=1 to 20;

interest = value*.075;

value+interest;

year+1;

output;

end;   → 위의 예시는 관측치 20개가 모두 표시됨

□ 항목의 시리즈 설정

ㅇ 콤마로 구분하며, 변수명은 따옴표로 묶지 않음

- do test = 2, 5, 9, 13, 27;

- do test = 'mon, 'tue', ' wed', 'thr', fri';

- do test = win, place, show;

※ win, place, show는 변수명임에 유의하고, 이들 변수들은 모두 문자변수이거나 혹은 모두 숫자변수이어야 함

□ 데이터셋으로부터 읽혀진 데이터에 대한 반복 처리

ㅇ do loop에서 stop value를 컬럼명으로 쓰면, 그 컬럼값대로 반복하여 do loop가 실행됨

ex) data work.compare(drop=i);

set finance.cdrates;

investment = 5000;

do i=1 to years;

investment+rate*investment;

end;

→ year 컬럼의 값이 5, 3, 4 3개라면, do loop의 결과는 year가 5일때까지, 3일때까지, 4일때까지를 각각 실행하여 3줄로 표시

□ do until과 do while

ㅇ do until은 loop의 가장 마지막 부분에 가서야 조건 평가하므로, do loop가 적어도 한번은 실행됨

ex) data work.invest;

do until(capital >=50000);

capital+2000;

capital+capital*.10;

year+1

end;

ㅇ do while은 loop의 시작 부분에서 조건이 평가되므로, 조건이 맞지   않으면 loop 미실행

ex) data work.invest;

do while(capital >=50000);

capital+2000;

capital+capital*.10;

year+1

end;

ㅇ index variable의 stop value 지정하고 do until/while을 쓰면, 두   조건 중 먼저 충족되는 조건 만큼만 실행됨

ex) data work.invest(drop=i);

do i=1 to 10 until(capital >=50000);

year+1

capital+2000;

capital+capital*.10;

end;

□ sample 생성

ㅇ data step의 set statement를 do loop 안에 사용하면, sample data set 생성 가능

ex) data work.subset;

do sample=10 to 5000 by 10;

set factory.widgets point=sample;

output;

end;

stop;

→ do loop 안에서 set statement 적용

→ do loop의 index variable로 point 옵션 적용

12장의 point 옵션은 무엇인지 확인 필요

· point 옵션 쓸 때 data step의 반복 loop를 피하기 위해 stop statement 적용

· stop statement는 data step의 마지막에서 관측치 표시를 막기 때문에, output statement 적용(?)

※ output statement를 do loop 바깥(end 뒤에) 적으면, 마지막 관측치만 저장될 것임에 유의

stop, output 등 직접 실습해봐야 알듯 함

Chapter 16. Processing Variables with Arrays

□ array의 정의

ㅇ array는 SAS 변수들을 임시로 같은 이름으로 묶은 것을 의미

- array는 data step 동안에만 유효

□ array의 일반적인 형식

ㅇ array weekday{7} mon tue wed thr fri sat sun;

→ mon~ sun까지의 7개 변수를 weekday라는 array로 지정한 것

- array명은 동일 data step 내의 변수명으로 지정하면 안됨

- array는 data step 내에서만 유효하므로, label, format, drop , keep, length statement에서는 적용 불가

- array의 적용 예시

· array sales{4} qtr1 qtr2 qtr3 qtr4;

· array sales{96:99} totals96 totals97, totals98 totals99;

· array sales{*} qtr1 qtr2 qtr3 qtr4;

→ *표(asterisk)로 지정하면 컬럼 개수를 자동으로 세어서 계산

· array sales{4} qtr1-qtr4;

□ array 항목으로서의 변수 목록

ㅇ array의 변수 항목은 아래의 표처럼 범위나 또는 성질에 따라 별도 지정 가능

< array의 변수 목록 >

구분	내용
변수의 범위	Var1-Varn
모든 숫자 변수	_numeric_
모든 문자 변수	_character_
모든 변수	_all_

□ DIM function

ㅇ dim 함수로 array 함수의 항목수를 자동 계산하고, 이를 Do 구문과 같이 활용 가능

ex) data hrd.convert;

set hrd.fitclass;

array wt{*} weight1-weight6;

do i=1 to dim(wt);

wt{i} = wt{i} * 2.2046;

end;

run;

→ array의 항목수가 6이므로, dim(wt)는 6이 되고, Do 구문의 stop value가 6이 됨

․ 만약, array의 항목수가 10이었다면, dim(wt)와 Do의 stop value는 10이 되었을 것

□ array 구문에서의 변수 생성

ex) data hrd.diff;

set hrd.convert;

array wt{6} weight1-weight6;

array wgtdiff{5};

- array에서 변수 생성할 때는 항목수만 적어주면 항목명을 따로 적을 필요 없음.

․ array wgtdiff{5};

․ array wgtdiff{5} wgtdiff1 wgtdiff1 wgtdiff1 wgtdiff1 wgtdiff1;

․ array wgtdiff{5} w1 w3 w3 w4 w5;

-> 즉, 위의 어떤 것을 써도 같은 결과가 나옴

- 문자 변수 생성시에는 변수명 뒤에 $ 표시 붙이고, Array에서 생성되는 문자변수의 기본길이는 8이 되므로, 필요시 별도 설정

문자 변수 및 숫자 변수의 기본길이 재확인 필요(컬럼명, 값 구분해서)

ex) array firstname{5} $ 24;

ㅇ 반복적인 do 구문에서의 array 구문 활용

ex) data hrd.diff;

set hrd.convert;

array wt{6} weight1-weight6;

array wgtdiff{5};

do i=1 to 5;

wgtdiff{i} = wt{i+1} - wt{i};

end;

run;

□ array의 초기값 설정

ㅇ array 정의시 항목에 대한 초기값을 설정하는 것이 유용할 수도 있음

ex) array goal{4} g1 g2 g3 g4 (9000 9300 9600 9900);

array col{3} $ color1-color3 ('red', 'green', 'blue;')

→ 문자의 경우에는 따옴표로 묶고 콤마로 구분함에 유의

array var{4} (1 2 3 4);

→ 이렇게 항목명을 하지 않아도 자동으로 변수 var1, var2, var3, var4에 대한 초기값이 설정됨

□ 임시 array 항목 생성

ㅇ 중간 계산 용도로만 필요하고, data set에 저장될 필요가 없는 경우, _temporary_를 적용

ex) data finance.report;

set finance.qsales;

array sale{4} sales1-sales4;

array goal{4} _temporary_ (9000 9300 9600 9900);

array achieved{4);

do i=1 to 4;

achieved{i}= sales{i} / goal{i} * 100;

end;

run;

→ _temporaray_ 없이 실행하면 sales1~4, goal 1~4, achieved1~4가 생성되는데, goal1~4는 계산에만 필요한 변수이므로, _temporay_ 적용해서 데이터셋에서 제외

□ 다차원의 array에 대한 이해

ㅇ 행렬의 개념으로 다차원의 array 생성 가능

ex) array new{3,4} x1-x12;

array new{3,4} x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12;

→ 둘다 같은 결과이고, x1~x4까지가 1행, x5~x8까지가 2행, x9~x12까지가 3행

→ 예시에서 new{2,3} = 0이라고 하면, x7이 0이 됨

ex) data finance.squrters(drop=i j);

set finance.monthly;

array m{4,3} month1-month12;

array qtr{4};

do i=1 to 4;

qtr{i} = 0;

do j=1 to 3;

qtr{i} + m{i,j};

sum statement 인듯

end;

end;

run;

→ m{1,j}는 1분기가 됨. 즉, j는 1~3까지이므로 1월에서 3월.

이런식으로 매분기 월별 합이 계산됨

□ 부가 기능

ㅇ array를 활용하여 엑셀의 피벗에서처럼 행 변수와 열 변수를 rotate 가능

rotate 예시 확인해볼 것

ex) data work.rotate(drop=qtr1-qtr4);

set _exp0_.funddrive;

array contrib{4} qtr1-qtr4;

do qtr=1 to 4

amount = contrib{qtr};

output

end

run

→ 행단위로 업체별, 분기별로 있는 데이터를 array를 활용하여 열단위로 전환

Chapter 17. Reading Raw Data in Fixed Fields

□ SAS가 raw data를 불러오는 방법에는 3가지가 있음

ㅇ column input

ㅇ formatted input

ㅇ List input

□ Column input에 대한 이해

ㅇ column input은 이미 5장에서 공부했음

ex) input item $ 1-13 idnum $ 15-19 instock 21-22;

- column input의 특징 중 하나는 변수 위치를 바꿀수 있다는 것

ex) input idnum $ 15-19 instock 21-22 item $ 1-13;

- embedded blanks를 포함한 문자 변수도 읽을 수 있음

ex) 「Jung Eui」처럼 공백이 포함된 문자 변수를 input name $ 1-10으로 읽을 수 있음

- missing data에 대한 자리를 별도로 지정할 필요 없으며,

(item $ 1-13이 비어있으면 비어있는대로 처리됨)

- 이미 읽은 위치의 일부분을 다시 읽을 수 있고

- 필드값들은 공백이나 다른 구분자로 구분될 필요 없음

□ 표준 숫자 데이터와 비표준 숫자 데이터

ㅇ 표준 숫자 데이터는 다음만을 포함

- 숫자

- 소수점

- 과학 기호 또는 E 표시(23E4등)

- 마이너스/플러스 표시

ㅇ 비표준 숫자 데이터는 다음을 포함

- %, $, 콤마(천단위표시) 등 특정 문자를 포함하는 값들

- 날짜와 시간

- 깨진 데이터, integer binary, real binary, hexadecimal 형식

□ input 스타일 선택

ㅇ 비표준 데이터는 column input보다 더 유연성 있는 input 스타일이 요구됨

- formatted input은 표준/비표준 데이터 모두에 적용 가능

※ fixed field로 이루어진 raw data는

· 표준 데이터는 column input으로,

· 표준 데이터/비표준 데이터를 formatted input으로 읽기 가능

□ formatted input의 일반 형식

ㅇ @n column pointer control

- @n은 절대위치 의미

ex) input @1 lastname $7.

→ lastname은 절대위치 1에서 시작

- @n은 default로 1이므로, 위의 예시는 input lastname $7.이라고 해도 됨

- 위치 바꿔도 됨

ex) input @9 firstname $5. @1 lastname $7.

ㅇ +n pointer control

- +n은 현재 포인터 위치로부터의 상대위치 의미

ex) input lastname $7. +1 firstname $5.

→ lastname은 절대위치 1에서 시작하고, 7자리이며

→ lastname 읽은 후 포인터는 다음 자리인 절대위치 8에 있으며, 한칸 뒤인(+1) 절대위치 9부터 5자리 동안 firstname 인식

※ @n과 +n을 같이 쓸수도 있음

ex) input lastname $7. +1 firstname $5. +5 salary  comma9.

@ 15 jobtitle 3.;

→ 절대위치 1에서 7까지 lastname, 절대위치 9에서 13까지 firstname, 절대위치 19에서 27까지 salary, 절대위치 15에서 17까지 jobtitle

□ informat의 활용

ㅇ informat은 SAS가 어떻게 raw data를 읽는지를 말해주는 지시사항임

- informat은 w.d의 형식이며, w는 자리수, 마침표(.)는 구분자, d는 소수자리를 의미

- 문자 data에는 $가 있어야 함

ㅇ $w.는 문자 데이터를 읽는 informat

ex) input @9 firstname $5.;

ㅇ w.d는 전체자리수가 w이며, 소수자리가 d인 숫자 데이터를 읽는 informat이며, 원 데이터가 소수점을 이미 포함하고 있다면, d는   지정하지 않아도 됨

ex) 34.0008를 7.4로 적용하나, 7.으로 적용하나 34.0008이 됨

※ 3.과 3의 차이에 유의

ex) input @7 jobtitle 3.; → jobtitle에 3. informat 적용

(소수점 포함 3자리)

input @7 jobtitle 3 → jobtitle의 length를 3번째 자리값으로 가져옴

ㅇ COMMAw.d는 비표준 숫자 데이터에서 공백, 콤마, -, $, %, 괄호를 제거하여 w자리, 소수자리가 d이도록 읽으며,

- dataset에 저장할 때는 공백, 콤마, -, $, %, 괄호 제외(소수점은 포함)

ex) raw data가 29,966.63인데 informat을 comma9.으로 한 경우, 읽어올 때는 9자리인 29,966.63으로 읽어오고, dataset에 저장할 때는 콤마를 제외하고 29966.63으로 저장

(Proc print 하면, 29966.63으로 조회됨)

※ SAS는 숫자 데이터를 default로 8자리수로 저장

이부분 이해 어려움. default로 8인데 informat으로 3.하면 3자리가 되나?

□ 변수로 구분된 레코드 읽기

ㅇ 변수로 구분된 fixed field 레코드는 informat이 실제 데이터의 길이보다 클 경우 불러오기 오류가 발생하므로, infile의 PAD옵션을 써서 빈칸을 공백으로 채워야 함

ex) input dept $ 1-11 @13 receipts comma8. 했는데 receipt자리에 들어가는 행 2의 실제 데이터가 5자리 밖에 안된다면, 행 3으로 가서 문자인 dept를 읽으려고 하기 때문에 error

→ 이 경우 infile receipt pad;해서 이 문제 처리 가능

Chapter 18. Reading Free-Format Data

□ list input

ㅇ 17장에서, 표준 데이터는 column input으로, 표준/비표준 데이터는 fixed field로 읽을 수 있음을 배웠음

- list input은 free format 데이터를 읽는데 쓰이며, 표준/비표준   데이터를 모두 읽을 수 있음

ㅇ list input은 컬럼 위치를 지정하지는 않으므로,

- 모든 필드는 공백이나 다른 구분자로 구분되어야 하고,

- 필드는 좌→우의 방향으로만 읽히며,

- 필드를 건너뛰거나 다시 읽을 수 없음

ex) input Gender $ age bankcard frqbank deptcard freqdept;

ㅇ 공백이 아닌 다른 구분자로 구분되어 있는 경우 infile statement의 DLM옵션을 활용해서 지정해야 함

ex) data perm.survey;

infile credit dlm=',';

input gender $ age bankcard freqbank deptcard freqdept;

run;

→ rawdata credit이 공백이 아닌 콤마(,)로 구분되어 있는 경우

※ 유의사항) 구분자는 컬럼값에 나오는 문자이면 안됨.

예를 들어, salary라는 필드에 24,456.09가 있는데, 콤마(,)를 구분자로 사용하면 안된다는 의미

□ 변수의 범위를 읽기

ㅇ ques1에서 ques5까지의 변수를 읽기

ex) input IDNUM $ ques1-ques5

ㅇ 범위로 읽은 변수가 문자형인 경우, 문자형임을 표시하는 $는 괄호로 표시되어야 함

ex) input age (store1-store3) ($);

ㅇ format 또한 범위로 지정가능하며, 괄호로 표시되어야 함

ex) input age (score1-score4) (6.);

□ list input의 한계

ㅇ 문자 및 숫자 변수 모두 default 길이는 8이므로, 유의 필요

ㅇ 데이터는 표준 숫자 또는 문자 형식이어야 함

앞에서는 비표준 데이터에도 쓸  수 있다고 했는데?

ㅇ 문자 변수는 구분자를 포함할 수 없음

ㅇ 결측치는 마침표나 다른 문자로 표시되어야 함

→ 수정된 list input으로 이런 한계점을 보완 가능

□ 결측치 읽기

ㅇ 결측치가 레코드의 마지막(끝)에 있는 경우

- list input에서 infile statement의 missover 옵션을 사용하면 SAS가 현재 레코드에서 결측치가 있는 경우 다음 레코드로 가지 않고  결측치 처리

ex) data perm.survey;

infile credit missover;

input gender $ age bankcard freqbank deptcard freqdept;

run;

→ 한 레코드의 끝에 있는 deptcard, freqdept가 둘다 결측치 이더라도 각각 결측치 처리

ㅇ 결측치가 레코드의 시작 또는 가운데에 있는 경우

- 레코드의 중간에 두 개의 쉼표(, ,)로 결측치가 구분되어 있는 경우, list input은 이를 하나의 구분자로 인식하고 바로 다음 값을 가져오므로 인식 오류 발생

- 이 경우 infile statement의 DSD 옵션을 활용하여 결측치 인식 가능

․ DSD 옵션은 default 구분자를 콤마로 하고,

․ 두 개의 연속적인 구분자가 있을 경우 결측치로 처리하며,

․ 데이터의 따옴표를 제거

ex) data perm.survey;

infile credit dsd;

input gender $ age bankcard freqbank deptcard freqdept;

run;

- 만약 데이터가 여러 개의 구분자를 사용한다면, dlm 옵션으로 반영 가능

ex) data perm.survey;

infile credit dsd dlm='*';

input gender $ age bankcard freqbank deptcard freqdept;

run;

→ 데이터가 콤마가 아닌 *로 구분된 경우

- DSD 옵션으로는 데이터의 처음에 결측치가 있는 경우에도 반영 가능

ex) data가 「, 27, 1」인 경우 첫 번째 컬럼값을 결측치로 인식

□ 문자 변수의 길이 설정

ㅇ 원 데이터를 읽기 위해 list input을 사용하는 경우, 문자 변수는 기본적으로 length 8로 설정

- 변수 속성은 변수가 data step에서 처음 나왔을 때 정해변수 8보다 긴 문자값을 지닌 문자변수를 읽기 위해서는 infile statement 바로 뒤에 length statement를 써야 함

ex) data perm.growth;

infile citydata;

length city $ 12;

input city $ pop70 pop80;

run;

※ length 구문에서 속성 및 길이를 지정했으며, input에서 다시 city의 속성($)를 지정해도 에러나지 않으며, 지정하지 않더라도 에러나지 않음

□ 수정된 list input

ㅇ 수정된 list input을 활용하여 list input 보완 가능

- &는 공백을 포함하는 문자값을 읽는데 활용됨

- ;는 비표준 데이터와 length가 8을 초과하는 문자 변수를 읽는데 활용됨(※ 공백은 없어야 함에 유의)

ㅇ 공백을 포함한 관측치 읽기

- & 구분자는 한 개의 공백을 포함한 문자를 읽을 수 있음. 연속적인 2개 이상의 공백이 나올때까지 관측치를 읽음

※ 단, & 구분자 사용을 위해서는, 두 개의 연속적인 공백으로 데이터가 구분되어 있어야 함에 유의!

ex) input rank city &;

- length statement 또는 informat과 같이 사용 가능

(아래 두 예시 모두 결과 같음)

ex) data perm.cityrank;

infile topten;

length city $ 12;             -> length 구문에 사용

input rank city &;

run;

ex) data perm.cityrank;

infile topten;

input rank city & $12.;       -> informat에 사용

run;

ㅇ 비표준 관측치 읽기

- : 구분자는 비표준 데이터(콤마 등을 포함한 경우 등)와 8글자를 초과하나 공백이 포함되지 않은 문자값을 읽을 수 있음

- : 구분자는 공백(또는 다른 구분자)가 나올때까지 값을 읽음

ex) data perm.cityrank;

infile topten;

input rank city & $12. pop86 : comma.;

run;

※ pop86의 informat이 COMMAw.d가 아닌 comma.임에 유의

→ 실제 데이터들이 모두 콤마 포함 8자리이라면, 숫자 변수의 default 길이가 8이므로 별도의 w 지정안해도 됨

→ 반면, formatted input에서는 읽어오는 컬럼의 길이인 w를 반드시 지정해야 함에 유의!

※ COMMAw.d informat은 데이터를 불러서 저장할 때 콤마를 제외. 즉, 생성된 perm.cityrank의 pop86 컬럼에는 콤마 없음

□ formatted input과 modified list input 비교

ㅇ informat이 다르게 적용됨에 유의

- formatted input에서는 informat은 문자 변수의 길이와 시작 위치를  결정하므로 그 위치에서 그 숫자만큼만 값을 불러오게 되나,

ex) input @3 city $12.;

-> 위치 3에서 12 길이만큼 데이터를 읽음

- modified list input에서는 변수의 길이만을 결정하므로 연속적인 공백 두 개가 나올때까지 값을 불러옴

ex) input city & $12.;

-> 읽혀지기 시작하는 위치는 지정되지 않았으며, 2개의 연속적인 공백을 만날 때까지 12 길이만큼 데이터를 읽음

□ free-format 데이터 생성

ㅇ Put statement는 free-format 데이터 파일을 생성하는 list output에 활용될 수 있음

ㅇ 목록 출력을 사용하는 put문의 일반적인 형식

- put 변수명 : format.;

ㅇ list ouput은 list input과 유사

ex) data _null_;

data _null_의 의미 확인 필요

set perm.finance;

file 'c:\data\findat';

put ssn name salary date : date9.;

run;

→ perm.finance의 데이터를 활용하여 findat이라는 파일을 생성  하는데, 원시데이터인 perm.finance의 date는 DDMMYYYY인 반면, findat의 date는 date9. format임

ㅇ 구분자 지정

- file statement의 dlm 옵션으로 구분자 지정 가능

ex) data _null_;;

set perm.finance;

file 'c:\data\findat2' dlm=',';

put ssn name salary date : date9.;

run;

→ 생성된 findat2 파일의 변수들이 콤마로 구분됨

※ 간단한 raw data 파일을 생성하기 위해서는 data step 대신 export 프로시져 사용 가능

ex) proc export data=perm.finance;

outfile='c:\data\findat2' delimiter=',';

경로에 따옴표 적용 여부 확인 필요

run;

ㅇ dsd 옵션 사용

- 콤마를 사용하는 값을 저장하면서 콤마로 구분된 파일을 생성하려면,

․ file statement의 dsd 옵션을 통해 콤마를 포함하는 변수들이  따옴표 처리되도록 할 수 있음

infile의 dsd 옵션은 따옴표를 제거하여 불러오며, file의 dsd 옵션은 콤마가 있는 경우 따옴표 처리하여 저장? 맞는 듯 함

․ dsd 옵션은 콤마를 구분자로 사용하므로, dlm=',' 옵션과 같이 쓸 필요 없음

ex) data _null_;;

set perm.finance;

file 'c:\data\findat2' dsd;

put ssn name salary : comma. date : date9.;

run;

- 반면, infile에 dsd 옵션을 쓰면 따옴표 처리된 변수에서 따옴표를 제거하여 불러옴에 유의

□ input 스타일 혼합

ㅇ raw data를 분석하여 가장 적합한 input 스타일을 선택하는 것은 매우 중요

ex) data perm.mixed;

infile rawdata;

input SSN $ 1-11 @13 hiredate date7. @21 salary comma6. department : $9. phone.;

중요 : 8 이상의 길이를 가지는 문자값이므로 informat에 : 구분자 기재한 것

run

→ SSN은 1에서 11(11자리)까지, hiredate는 13에서 19까지(7자리), salary는 21에서 26까지(6자리), department는 28에서 36까지(9자리), phone은 표시 안되었지만 4자리

< input 스타일 현황 >

input 스타일	읽어오는 것
column	fixed field로 된 표준 데이터
formatted	fixed field로 된 비표준 데이터
list	unfixed field이나 공백 또는 다른 구분자로 구분된 데이터

□ 부가 기능

ㅇ put statement를 활용하여 문자 string과 변수 값 저장 가능

ex) filename totaldat 'c:\records\junsales';

data_null_;

set work.total;

file totaldat;

put 'sales for salesrep ' salesrep

'totaled ' sales : dollar9.;

run;

→ 원래 work.total에는 salesrep과 sales 변수만 있으나, put을 활용하여 생성하는 totaldat 파일에는 salserep 앞에 sales for salesrep를, sales 앞에 totaled라는 값을 추가

(공간 처리 관계로 put의 따옴표 안에는 공백을 포함했음에 유의)

Chapter 19. Reading date and Time Values

□ SAS가 날짜값을 저장하는 방법

ㅇ SAS는 날자값을 1960.1.1로부터의 일수로 저장

□ SAS가 시간을 저장하는 방법

ㅇ SAS는 시간을 자정부터의 초수로 저장

※ datatime은 1960.1.1 자정부터의 초수로 저장됨

□ 날짜 및 시간 informat 읽기

ㅇ MMDDYYw. Informat

※ blank도 w에 포함됨에 유의

Date expression	SAS Date Informat
101599	MMDDYY6.
10/15/99	MMDDYY8.
10 15 99	MMDDYY8.
10-15-1999	MMDDYY10.

ㅇ DATEw. Informat

Date expression	SAS Date Informat
30May00	DATE7.
30May2000	DATE9.
30-May-2000	DATE11.

ㅇ TIMEw. Informat

※ w의 적용가능한 min 값은 5임에 유의

→ 아래의 세 번째 예시의 2:34는 4자리임에도 TIME5. 해야 에러나지 않음

Time expression	SAS Time Informat
17:00:01.34	TIME11.
17:00	TIME5.
2:34	TIME5.

ㅇ DATETIMEw. Informat

Date and Time expression	SAS Date and Time Informat
30May2000:10:03:17.2	DATETIME20.
30May00 10:03:17.2	DATETIME18.
30May2000/10:03	DATETIME15.

□ Yearcutoff 옵션

ㅇ 앞의 2장에서 봤듯이 SAS는 dafault로 yearcutoff=1920을 적용하여, 2자리의 연도를 처리할 경우에는 1920~2019 기간을 사용

- 아래의 세 번째 예시 참조

※ 2자리의 연도를 이용할 때는 yearcutoff의 default 값을 반드시  확인하고, 필요시 변경 필요

ex) options yearcutoff=1920;

Date Expression	SAS Date Informat	Interpreted As
06Oct59	DATE7.	06OCt1959
17Mar1783	DATE9.	17Mar1783
17Mar1783	DATE7.	17Mar1917

□ Informat과 format

ex) options yearcutoff=1920;

data perm.aprbills;

infile aprdata;

input lastname $8. @10 datein mmddyy8. +1 dateout      mmddyy8. +1 roomrate 6. @35 equipcost 6.;

days=dateout-datein+1;

roomcharge=days*roomrate;

total=roomcharge+equipcost;

run;

proc print date=perm.aprbills;

run;

→ informat은 aprdata를 불러오는데 적용되었으므로, proc print로 출력된 aprbill은 날짜와 시간이 SAS 형식으로 조회됨(14339..)

□ Date와 Time Format 적용

ㅇ proc print에서 변수에 format을 적용함으로써 사용자가 원하는 형식으로 날짜와 시간 조회 가능

ㅇ WEEKDATEw. Format

ex) proc print data=perm.aprbills;

format datein dateout weekdate17.;

Format Statement	Result
weekdate3.	Mon
weekdate6.	Monday
weekdate17.	Monday, Apr 5, 99
weekdate21.	Monday, April 5, 1999

※ w에는 공백도 포함됨에 유의

ㅇ WORDDATEw. Format

- weekday와 유사하나, 요일과 두자리 연도를 표시하지 않음

Format Statement	Result
worddate3.	Apr
worddate5.	April
worddate14.	April 15, 1999

※ format을 data step에 넣으면 permanent하게 적용됨

ex) options yearcutoff=1920;

data work.aprbills;

infile aprdata;

input lastname $8. @10 datein mmddyy8. +1 dateout mmddyy8. +1 roomrate 6. @35 equipcost 6.;

days=dateout-datein+1;

roomcharge=days*roomrate;

total=roomcharge+euipcost;

format datein dateout worddate12.;

run;

proc print data=work.aprbills;

run;

Chapter 20. Creating a Single Observation from Multiple Records

□ 여러 줄에 있는 record로부터 한 관측치(observation)을 불러와야할 경우, Line pointer Control을 활용

ㅇ / : 한 위치에서의 상대 위치 (연속적인 레코드로부터 불러올 경우)

ㅇ #n : n이라는 절대 위치 (비연속적인 레코드로부터 불러올 경우)

□ / line pointer cotrol

ㅇ 원데이터의 연속적인 여러 개의 레코드로부터 관측치를 읽을 경우,  즉, 한 관측치에 대한 레코드가 한 줄에 있지 않을 경우 /를 활용

(줄이 다를 때를 의미함)

ex) input lname $ 1-8 pname # 10-15 /

department $ 1-12 jobcode $ 15-19 /

salary comma10.;

→ 불러오는 데이터에서 lname과 pname, department와 jobcode, salary는 같은 줄에 있지 않음

※ 관측치의 레코드수와 불러오는 데이터의 레코드 수는 같아야 함에 유의. 즉, 위의 예시에서는 한 관측치로 3줄(레코드)을 불러오고 있으므로, 불러오는 데이터도 한 관측치당 3줄(레코드)씩 있어야 한다는 의미

□ #n line pointer control

ㅇ 비순차으로 여러 개의 레코드로부터 관측치를 읽어올 경우 #n을 활용

ex) input #2 department $ 1-12 jobcode $ 15-19

#1 lname $ fname $

#3 salary comma10.;

→ 불러오는 데이터의 2번째 줄에서 department와 jobcode를,  1번째 줄에서 lname과 fname을, 3번째 줄에서 salary를 불러옴

※ /과 #n을 같이 적용할 수도 있음

ex) data perm.patients;

infile patdata;

input #1 id $5.

#4 fname $ lname $ /

address #23. /

city $ state $ zip $ /

97 doctor $6.;

Chapter 21. Creating Multiple Observations from a Single Record

□ 20장에서와는 반대로, 때로는 원 데이터가 한 레코드에 여러 개의 관측치를 포함하는 경우도 있음

ㅇ 예를 들어, 원 데이터의 한 레코드(줄)가

‘120131 20 120229 30 120331 40‘ 처럼 월별 분기 판매량을 포함하고 있는 경우 등

ㅇ 이 경우 @ 또는 @@를 활용

□ Double trailing at sign(@@)은 다음 input statement 실행시까지 data step의 반복에도 불구하고 불러오는 레코드를 설정함

ex) data perm.april90;

infile tempdata;

input date : date. sales @@;

여기 왜 점만 있지? date.

run;

→ 위의 예시에서는 date와 sales를 반복적으로 다른 줄(관측치)로 불러옴

120131 20

120229 30

120430 40

□ Trailing at sign(@)은 다음 input statement 실행시까지 불러오는 레코드를 설정함

예를 들어, 'ID1 100 200 300 400

ID2 200 100 300 100

ID3 300 400 500 300'처럼 ID별 분기별 판매량이 있어,

ID가 중복되는 경우

ex) data perm.sales97;

infile data97;

input ID $ @;

input sales : comma. @;

output;

input sales : comma. @;

output;

input sales : comma. @;

output;

input sales : comma. @;

output;

run;

→ 첫 번째 input statement는 ID를 hold하고, 두 번째 input statement는 sales를 hold함..

※ COMMAw.d informat은 숫자를 읽으며 콤마를 제거

※ list input은 새로운 공백이 발견될 때까지 데이터를 읽고, 숫자는 default로 길이가 8이므로, w를 설정할 필요 없음에 유의

→ do-loop를 써서 간단히 표현할 수도 있음

ex) data perm.sales97;

infile data97;

input ID $ @;

do quarter=1 to 4;

input sales : comma. @;

output;

end;

run;

※ 이렇게 @를 활용해서 중복되는 컬럼(위의 예에서 ID) 기준으로 여러개의 관측치를 생성할 때, 값이 비어 있는 필드가 있으면 안됨에 유의.

즉, 위의 예시에서처럼 모든 분기별 매출액의 값이 있어야한다는 의미

□ Missover 옵션 활용

ㅇ 불러오는 데이터에 결측치가 있는 경우, missover 옵션을 활용해서 처리 가능

ex) data perm.sales97;

infile data97 missover;

input ID $ sales : comma. @;

→ 이 경우, 위의 예시에서 3Q의 매출액이 비어있더라도 처리 가능

□ 조건이 참일 경우에만 SAS 구문 실행

ㅇ do-while 구문을 활용하여 특정 조건 지정 가능

ex) data perm.sales97;

infile data97 missover;

input ID $ sales : comma. @;

do while(sales ne .);

→ sales가 결측치(.)가 아닌 경우에만 처리

□ counter variable 생성

ㅇ do-while 구문은 index 변수를 생성하지 않으므로, 사용자만의 counter 변수를 생성 하여 적용 가능

ex) data perm.sales97;

infile data97 missover;

input ID $ sales : comma. @;

quarter=0;

do while(sales ne .);

quarter+1;

output;

input sales : comma. @;

end;

run;

→ sales가 결측치(.)가 아닌 경우에만, 분기별로 처리되어 표시됨

ID1 130 1

ID1 230 2

ID2 140 1

ID3 130 1

ID3 143 2

ID3 140 3

ID3 230 4 등