MACRO 5 강
SAS 매크로개요 매크로 - SAS 시스템에서는 SAS 의활용도를높이고일상적인프로그램작성작업의효율성을높이기위해서매크로기능 (MACRO FACILITY) 을제공하고있다. 매크로기능 - 매크로기능은사용자가작성해야하는프로그램의양을줄이고 SAS 언어의활용도를높여주는강력한프로그램작성도구라고할수있는데프로그램의양이많든적든간에한번에실행하고싶은내용을간단히하나의단위로만들어필요할때마다프로그램내에서호출하여사용할수있다. 매크로기능은매크로언어 (MACRO LANGUAGE) 와매크로처리기 (MACRO PROCESSOR) 를포함하는개념이다. 매크로처리기 - 실제로작업을수행하는 SAS 시스템의일부로서매크로언어로작성된프로그램이 SAS 시스템에서제대로수행되게한다. 매크로언어 - 매크로처리기와의사소통을할수있게해주는프로그램언어로서매크로변수 (VARIABLE), 프로그램문장 (PROGRAM STATEMENT), 연산식 (EXPRESSION) 및함수 (FUNCTION) 로이루어진다. 2
매크로언어의목적 프로그램작성작업의간소화 ( 단순반복적인 SAS 코드의생성 ) EX) %macro prt(dsn); proc print data=&dsn; run; %mend prt; %prt(sashelp.class) SAS 시스템정보의추출 - 자동매크로변수를이용하여시스템정보를추출할수있다. %put sysdate is &sysdate; => sysdate is 06FEB98 (LOG 창 ) 3
SAS Processing 일반 SAS도프로그램 1 SAS 프로그램컴파일 2 실행 Macro 프로그램 1 Macro processor가 Macro 구문을일반 SAS 프로그램으로변환 2 프로그램컴파일 3 실행 4
Macro Processing 5
MACRO / MACRO variable Macro variable 1 %(percent) 로시작한다. 2 주로변수이름을나타낸다. 3 Local( 지역 ) macro variable : macro안에서선언, macro안에서만사용가능 4 global( 광역 ) macro variable : macro밖에서선언, 모든 sas program에서사용가능 5 숫자변수, 문자변수구분없이, 항상문자열로처리됨. 6 Macro Variable 의종류는두가지가있음 (i) AUTO Variables (ii) 사용자정의 Variables 6
AUTO Variables 사용자가별도로정의하지않아도 SAS 제어기또는시스템에의해서자동으로생성되는 Macro Variable 를의미. %PUT _AUTOMATIC_; 자동변수, 사용자정의변수를모두보여준다 이 름 기 능 SYSDATE 시스템의현재날짜 : 25JAN97 SYSDAY 시스템의현재요일 : Thursday SYSTIME 시스템의현재시간 : 10:45 SYSENV 실행모드 : fore,back SYSSCP 운영체제 : os,cms,dos,window,unix,mvs SYSVER SAS 시스템의버전 : 6.08, 6.11, 6.2 SYSJOBID SAS시스템을실행한사용자의 ID: sasdev SYSERR 마지막으로실행된 DATA/PROC스텝의리턴코드 : 0 SYSRC 마지막으로실행된운영체제명령어의리턴코드 : 0 SYSLIBRC 마지막으로실행된 LIBNAME문의리턴코드 : 0 7
사용자정의 Macro Variables Macro variable 생성 : %LET macro-variable-name = value; ( 예 ) %LET iterations = 10; %LET country = New Zealand; /* SAS문자변수와달리 가없다. */ Macro variable 사용 : & macro-variable ( 예 ) DO = i TO &iterations; TITLE Addresses in &country ; macro processor는위구문을다음과같이변환한다 : DO = i TO 10; TITLE Addresses in New Zealand ; 8
value : 문자값으로그대로저장. ( 해당매크로변수가호출되어졌을때, TYPE 이정해짐 ) 수학적식이계산되지않음. ( 예 ) %let total = 3+4; %put &total; => 3+4 사용자가 %LET 문을사용하여정의 %PUT _USER_ ; 선언한매크로변수와값을 Display 됨. ( 예 ) %Let Code = A B C D; %Let Desc = 100 200 300 400; %put _USER_; /* GLOBAL & LOCAL 사용자변수목록을출력 */ %put _GLOBAL_; /* GLOBAL 사용자변수목록을출력 */ %put _LOCAL_; /* LOCAL 사용자변수목록을출력 */ 9
DATA flowersales; LENGTH Variety $9; INPUT CustomerID $ SaleDate MMDDYY10. Variety $ Quantity @@; IF Variety = "&flowertype"; CARDS; 240W 02-07-2008 Ginger 120 240W 02-07-2008 Protea 180 356W 02-08-2008 Heliconia 60 356W 02-08-2008 Anthurium 300 188R 02-11-2008 Ginger 24 188R 02-11-2008 Anthurium 24 240W 02-12-2008 Heliconia 48 240W 02-12-2008 Protea 48 356W 02-12-2008 Ginger 240 10
%LET flowertype=ginger; /* Global macro variable */ DATA flowersales2; SET flowersales; IF Variety = "&flowertype"; PROC PRINT DATA = flowersales2; FORMAT SaleDate WORDDATE18.; TITLE "Sales of &flowertype"; 11
Macro 기본프로그래밍 %MACRO macro-name; * 매크로함수정의 ; %MEND; macro-text; - Macro 는기본적으로 Macro 를만드는부분과호출하는부분두개의구조로이루어짐 - Macro 는호출되어지기전에미리수행되고, 한번수행된것은반복해서사용가능 - %macro-name ; * 매크로함수호출 ; %MACRO mshow(lib, data); PROC PRINT data=&lib..&data; %MEND; %mshow(sashelp, class); 12
Macro Parameter %MACRO macro-name (Parameter list); * 매크로함수정의 ; %MEND ; text referencing parameter variables %macro-name(parameter value) ; * 매크로함수호출 ; - Macro 에서 Parameter 사용가능 %MACRO printdsn(dsn, vars); PROC PRINT DATA = &dsn; VAR &vars; title "Listing of %upcase(&dsn) data set"; %MEND; %printdsn(sashelp.class, name sex height weight); Macro Parameter 는 Local Symbol Table 에저장이되는데위의 DSN, VARS 의 Value 들이저장이되고 Macro 호출시에 Value 을참조. 13
DATA flowersales; LENGTH Variety $9; INPUT CustomerID $ SaleDate MMDDYY10. Variety $ Quantity @@; IF Variety = "&flowertype"; CARDS; 240W 02-07-2008 Ginger 120 240W 02-07-2008 Protea 180 356W 02-08-2008 Heliconia 60 356W 02-08-2008 Anthurium 300 188R 02-11-2008 Ginger 24 188R 02-11-2008 Anthurium 24 240W 02-12-2008 Heliconia 48 240W 02-12-2008 Protea 48 356W 02-12-2008 Ginger 240 %MACRO sample; PROC PRINT DATA = flowersales (OBS=5); FORMAT SaleDate WORDDATE18.; %MEND sample; %sample /* %LET을이용하면구문의일부변수를변경하여반복할수있다!!*/ 14
%MACRO select(customer=,sortvar=); PROC SORT DATA = flowersales OUT=salesout; BY &sortvar; WHERE CustomerID= "&CUSTOMER"; PROC PRINT DATA=salesout; TITLE "Orders for customer number &customer"; %MEND select; %select(customer = 356W, sortvar=quantity) %select(customer = 240W, sortvar=variety) 15
Macro Macro구문에 PARAMETER 넣기 : 유사한구문을반복해서사용할때 /* MACRO 구문선언 */ %MACRO macro-name (parameter-1=, parameter-2=, ); macro-text; %MEND macro-name; ( 예 ) %MACRO quarterlyreport (quarter=, salesrep=); Macro 호출 : %macro-name(parameter-1=a, parameter-2=b, ); ( 예 ) quarterlyreport(quarter=3, salesrep=smith) 16
매크로반복문 (%Do %END) %DO index-variable = start %TO stop %BY increment; text %END ; %MACRO roman(ds, start, stop, incr); data &ds; %DO i = &start %TO &stop %BY &incr; value = &i; output; %END; run; %MEND roman; %roman(roman, 1, 3, 1); 17
Macro 조건문 %IF %Then 1) %IF %THEN / %ELSE - %IF expression! %THEN text ; <%ELSE text ;> 2) %IF %THEN %DO%END / %ELSE %DO%END - %IF expression! %THEN %DO ; statement; statement;... %END; %ELSE %DO; statement; statement;... %END; %MACRO printit; %IF &syslast NE _NULL_ %THEN %DO; PROC PRINT data = _last_(obs=5); %END; %MEND; %printit; /*&syslast 는이전 DATA명 */ 18
%MACRO dailyreports; %IF &SYSDAY = MONDAY %THEN %DO; PROC PRINT DATA = flowersales; %END; %ELSE %IF &SYSDAY = Tuesday %THEN %DO; PROC MEANS DATA = flowersales MEAN MIN MAX; VAR quantity; %END; %MEND dailyreports; %dailyreports 19
CALL SYMPUT CALL SYMPUT( macro-variable, text ); CALL SYMPUT( macro-variable, DATA-Step-variable); CALL SYMPUT( macro-variable, expression!); -DATA Step 에서의 Macro Variable 생성하는것 DATA dusty; INPUT dept $ name $ salary @@; CARDS; bedding Watlee 18000 bedding Ives 16000 carpet Ray 12000 carpet Jones 9000 gifts Johnston 8000 gifts Matthew 19000 kitchen Marks 9000 kitchen Cannon 15000 tv Jones 9000 tv Smith 8000 tv Rogers 15000 tv Morse 16000 RUN ; 20
CALL SYMPUT PROC MEANS NOPRINT; CLASS dept; VAR salary; OUTPUT OUT=stats SUM=s_sal; DATA _NULL_; SET stats; IF _N_=1 THEN CALL SYMPUT('s_tot', trim(left(s_sal))); ELSE CALL SYMPUT('s' dept, trim(left(s_sal))); /* 여기서 는문자열접합 */ %put _user_; 21
CALL SYMPUT DATA _NULL_; SET flowersales; IF _N_=1 THEN CALL SYMPUT("selcustomer", customerid); ELSE STOP; PROC PRINT DATA = flowersales; WHERE CustomerID = "&selcustomer"; TITLE "customer &selcustomer had the single largest order"; 22
The %INCLUDE Statement External File 을호출하여실행시키는문장. /* external.sas 파일 */ DATA newclass; SET sashelp.class; newweight=weight*&tweight; /* SAS 코드 */ %LET tweight=1.1; %INCLUDE 'c:\external.sas' /SOURCE2; PROC PRINT; /*SOURCE2 라는옵션을붙이면 SAS Log 에소스가 Display 됩니다.*/ 23
Macro Functions %UPCASE %LOWCASE %SUBSTR %SCAN %LENGTH %SYSFUNC 24
%UPCASE 와 LOWCASE %UPCASE(argument); /* Argument 를대문자로변환하고자할때 */ %LOWCASE(argument); /* Argument 를소문자로변환하고자할때 */ %LET namevar=alfred; DATA class; SET sashelp.class; WHERE upcase(name) = "%UPCASE(&namevar)"; 25
%SUBSTR %SUBSTR(argument, position<,n>); /* 문자열중에일부만가져오고자할때 */ PROC PRINT DATA=sashelp.class; TITLE "Report Date : %SUBSTR(&sysday,1,3) &sysdate"; 26
%SCAN %SCAN(argument, n, <delimiters>); /*n 번째문자를가져오고자할때 */ Delimiters 의디폴트값 : blank. < ( + &! $ * ) ; ^ - /, % %LET deli=abc*def*gh; %PUT %SCAN(&deli, 1, *); /* 구분자를 * 로한다 */ 27
%INDEX %SCAN(argument1, argument1); /*searches the first argument (ARGUMENT1) for the first occurrence of the text string which is contained in the second argument (ARGUMENT2).*/ %LET X=LONG TALL SALLY; %LET Y=%INDEX(&X,TALL); %PUT TALL CAN BE FOUND AT POSITION &Y; 28
%LENGTH %LENGTH(argument); /* 매크로변수가몇개의글자로이루어졌는지알고자할때 */ %LET M1 = KOREA TEAM FIGHTING; %LET M2 = WORLD BASEBALL CLASSIC; %PUT %LENGTH(&M1); /* 로그창에 19출력 */ %PUT %LENGTH(&M2); /* 로그창에 22출력 */ 29
%SYSFUNC %SYSFUNC(function(argument(s))<,format>); - Macro 에서 SAS Function 을 Macro Function 처럼이용 - 모든 SAS Functions 들이 %sysfunc 를사용할수는없음 ex) DIF, DIM, HBOUND, IORCMSG, INPUT, LAG, LBOUND, MISSING, PUT, etc %LET fmttime = %SYSFUNC(time(), timeampm14.2); %LET fmt2 = %SYSFUNC(time(), time5.); %LET currdate = %SYSFUNC(today(), worddate.); DATA _NULL_; PUT "today's date: &currdate"; PUT "systime is : &systime = when SAS started"; PUT "using sysfunc, time is : &fmttime"; PUT "another format for time is &fmt2"; 30