KM<#252 3 %2016_09_10_WUSS_5Macro_Skills_in_7_examples 1 332 1 296 /******MACROS Five Essential Skills in Seven Examples--and some Hints ********************************************************************* * %2016_09_10_WUSS_5Macro_Skills_in_7_examples ; This program uses Seven examples to give an overview of four MACRO learning tasks. Use these for goals/motivation. They illustrate how to macro-ize common tasks and can provide structure to, and examples for, your self-learning. Sometimes, the code below can be pasted into a program and modified. Skills to learn are: skill 1) Wrap a block of code (several procs/datasteps) in a macro, and then call it repeatedly with different parameters Skill 2a) Automate a process (several procs/datasteps) using a macro and Proc SQL and %scan- NEW WAY Skill 2b) Automate a process (several procs/datasteps) using a %do loop and && - old way; *Skill 3 - conditionally execute code with an %if; *Skill 4a - use a macro to create a code snippet (saving some typing and annoying your co-workers) - generate a list of numbers; *Skill 4b - use a macro to create a code snippet (saving some typing and annoying your co-workers)- re-order variables alphabetically; *Skill 5 - Call execute and a driver file **********************************************************************************/ /***************************************************************** Skill 1_: Wrap a block of code (several procs/datasteps) in a macro and call it repeatedly with different parameters ; ******************************************************************/ /*Manually submit a macro*/ %macro call_me(whereCL= /*a where clause without a semicolon */ ); /**wrap a bunch of code, with some common theme, inside a macro. Call it manually!!*/ proc means data=sashelp.class; where &whereCL; run; proc chart data=sashelp.class; vbar height; where &whereCL; run; Proc plot data=sashelp.class; plot age*height; where &whereCL; run; Proc reg data=sashelp.class; model height=age; where &whereCL; run; %mend call_me; %call_me(whereCL=%str(sex="M") /*a where clause without a semicolon */ ); %call_me(whereCL=%str(Age GT 14) /*a where clause without a semicolon */ ); %call_me(whereCL=%str(1=1) /*a where clause without a semicolon **A TIRC to remove a wher clause*/ ); /***************************************************************** *Skill 2a) Automate a process (several procs/datasteps) using a macro and Proc SQL and %scan- NEW WAY ; ******************************************************************/ /***************automate with sql**************************************/ options mlogic mprint symbolgen; %macro automated(CoolVar= /*a numeric variable*/ ); Proc SQL; title "we will print for the following values"; select distinct &CoolVar into :maclist separated by " " from SAShelp.class order by &coolvar ; quit; title ""; %put _user_; %let counter=1; %do %while(%Qscan(&maclist,&counter,%str( )) NE); %let ThisValue=%scan(&maclist,&counter,%str( )); proc print data=sashelp.class; where &CoolVar=&ThisValue; run; %let counter=%eval(&counter+1); %end; %mend automated; %automated(CoolVar=age /*a numeric variable*/ ); %automated(CoolVar=height /*a numeric variable*/ ); /***************************************************************** *Skill 2b) Automate a process (several procs/datasteps) using a %do loop and && - old way; ******************************************************************/ Proc freq data=sashelp.class; tables sex/out=sexfl(DROP= PERCENT COUNT ); run; Data _null_; set sexfl END=eof; call symput("Sex"||put(_n_,1.),sex); IF eof =1 THEN DO; call symput("MAXn",_n_); END; run; %put _user_; %put _ALL_; %macro showMe; options nomprint nomlogic nosymbolgen; %do I=1 %to &MaxN; %put &&sex&i ; %end; %mend showMe; %showme; %macro Looper; %do i=1 %to &mAXn; options nocenter; Proc Print data=sashelp.class; where sex="&&Sex&i"; run; options nocenter; Proc MEANS data=sashelp.class; where sex="&&Sex&i"; run; %END; %mend Looper; OPTIONS SYMBOLGEN; %Looper; /***************************************************************** *Skill 3 - conditionally execute code with an % if; ******************************************************************/ options mlogic mprint symbolgen; %macro Use_an_if(CoolVar= /*a variable*/ ,NumVarYN= /*Numeric variable Yes or no? Value as Y or N */ ); %let NumVarYN=%upcase(&NumVarYN) ; Proc SQL; title "we will print for the following values"; select distinct &CoolVar into :maclist separated by " " from SAShelp.class order by &coolvar ; quit; title ""; %put _user_; %let counter=1; %do %while(%Qscan(&maclist,&counter,%str( )) NE); %let ThisValue=%scan(&maclist,&counter,%str( )); proc print data=sashelp.class; %if &NumVarYN=Y %then %do; where &CoolVar=&ThisValue; %end; %else %if &NumVarYN=N %then %do; where &CoolVar="&ThisValue"; %end; run; %let counter=%eval(&counter+1); %end; %mend Use_an_if; %Use_an_if(CoolVar=age /*a variable*/ ,NumVarYN=Y /*Numeric variable Yes or no? Value as Y or N */ ); %Use_an_if(CoolVar=Sex /*a variable*/ ,NumVarYN=N /*Numeric variable Yes or no? Value as Y or N */ ); /***************************************************************** *Skill 4a - use a macro to create a code snippet (saving some typing and annoying your co-workers) - generate a list of numbers; ******************************************************************/ options NOCENTER mlogic mprint symbolgen source2; %macro lazy(start=1985, end=1991); /*THIS IS REALY SILLY- I COULD HAVE WRITTEN THE MACRO TO GENERATE A NUMERIC SERIES, BUT THIS IS MORE COMPLEX and a better goal/example*/ "&start" %let looplim=%eval(&start+1); %do i=&looplim %to &end; ,"&i" %end; %mend lazy; %lazy(start=1985, end=1991) data FILTEREDctiyear; set sashelp.Citiyr; cDATE=PUT(DATE,year.); /*THIS IS REALY SILLY- i COULD HAVE WRITTEN THE MACRO TO GENERATE A NUMERIC SERIES, BUT THIS IS MORE COMPLEX and a better goal/example*/ if cdate in(%LAZY()); /*the snippet is just a little bit of code imbedded in a program- by itself it will not run*/ run; PROC PRINT DATA=FILTEREDctiyear; RUN; /***************************************************************** *Skill 4b - use a macro to create a code snippet (saving some typing and annoying your co-workers)- re-order variables alphabetically; ******************************************************************/ proc print data=sashelp.vcolumn; title "just look at vcolumn, in case it is new to you"; where libname="SASHELP" and memname="CLASS" ; run; proc sql; select distinct name into :varlist separated by ", " from SASHELP.vcolumn where upcase(name) NE "NAME" and libname="SASHELP" and memname="CLASS" order by name; %put &varlist; proc sql; /*create table VarInOrder as*/ select name, &varlist /*the snippet is just a little bit of code imbedded in a program- by itself it will not run*/ from sashelp.class; quit; /************ call execute example*********************/ options mprint mlogic symbolgen mcompilenote=all; %macro Print10(Lib= ,DSN= ,VarList= ); title '%macro Print10'; Proc print data= &lib..&dsn (obs=10); var &VarList ; run; %mend Print10; /* run this as QC --> %Print10(lib=SASHelp, dsn=class,VarList=name age sex) */ %macro M_Means(Lib= ,DSN= ,ClassVars= ,VarList= ); title '%macro M_Means'; Proc means data= &lib..&dsn; class &ClassVars ; var &VarList ; run; title ""; %mend M_Means; /* run this as QC --> %M_Means(lib=SASHelp, dsn=shoes, ClassVars=region, VarList=sales returns) */ data Driver_file; infile DataLines missover firstobs=4; input @1 RptType $char8. @10 libr $char7. @20 DSNm $char5. @30 Vlist $char13. @45 Param1 $char6.; DataLines; 1 2 3 4 5 6 123456789012345678901234567890123456789012345678901234567890 RptType Libr DSNm Vlist Param1 Param2 look at firstobs Print_10 SASHelp Class name age sex M_Means SASHelp Shoes Sales returns Region ; run; proc print; run; Data _null_; set Driver_file; if RptType="Print_10" then call execute('%Print10(lib='||Libr||', dsn='||DSNm||',VarList='||Vlist||')'); Else if RptType="M_Means" then call execute('%M_Means(lib='||Libr||', dsn='||DSNm||',ClassVars='||PARAM1||',VarList='||Vlist||')'); Else put "ERRROR WAARNING :-( :-( :-( :-("; run; 1 1 Û252 3 %DECILE 1 332 1 154 /*** Program: Deciling Dev/Active/Inactive: XXXXXXX Programmer: GA Program Owner: Glenn Abrahamsen Business Owner: Glenn Abrahamsen Date Pgm. Started: long ago Date Pgm. Finished: long ago Client: utility macro Study : N/A Purpose: to bucket a file by the sum of a variable *********** Preceeding: Programs that must be run before this can be run N/A Concurrent: Programs that can be run concurrent with this N/A Following: Programs that Can only be run after this finishes N/A Driver files: External files containg metadata to control program execution N/A Infiles: perm files USED by this program MacroParameter Outfiles: perm files CREATED by this program MacroParameter Macros called: perm macros called by this program N/A Formats called: perm formats called by this program N/A Maintenance: N/A *******************************************************************************/ %let InDSN=sashelp.Stocks; /*Input data set*/ %let AnVar=Volume ;/*Variable we wish to "bucket"*/ %let OutDSN=TradingDays_Deciled; /*Output data set w/ variables: decile_&anvar. Semi_decile_&anvar. Quartile_&anvar. */ %macro decile (InDSN= /*Input data set*/ ,AnVar= /*Variable we wish to "bucket"*/ ,OutDSN= /*Output data set w/ variables: decile_&anvar. Semi_decile_&anvar. Quartile_&anvar. */ ); PROC OPTSAVE out=ToRestore; run; options nocenter ls=200 ps=70 MPRINT ; /* this macro creates decile_&anvar. semi_decile_&anvar. quintile_&anvar. */ /*~10 percent of the total for &AnVar will go into each decile, not ~10% of the obs*/ proc sort data = &InDSN. out = sorted; /*SORTING IS IMPORTANT TO ALLOW 10% OF VAR TOTAL TO GO INTO EACH BUCKET*/ by &AnVar.; run; proc sql NoPrint; /*WE NEED THE TOTAL TO CALCULATE THE CUTPOINTS*/ select sum(&AnVar.) ,sum(&AnVar in (.,0)) ,sum(&AnVar in (.,0))/count(*) ,count(*) into :DataSetTot , :NoOfMissing , :PctOfMissing , :NoOfRows from sorted; quit; %let DataSetTot = &DataSetTot; %let NoOfMissing = &NoOfMissing; %let PctOfMissing = &PctOfMissing; %let NoOfRows = &NoOfRows; data &OutDSN (drop =DataSetTot_&anvar. Var4ThisObs CumlVarTot ); retain DataSetTot_&anvar. &DataSetTot CumlVarTot; set sorted; Var4ThisObs = &anvar.; CumlVarTot + Var4ThisObs; /*We are reading the file from small values of anVar to large*/ /*assign Decile based on Pct of total of ANVar for the data set*/ decile_&anvar. = Min(10,ceil(CumlVarTot /DataSetTot_&anvar. *10 )); semi_decile_&anvar. = Min(20,ceil(CumlVarTot /DataSetTot_&anvar. /.5 *10 )); quintile_&anvar. = Min(5,ceil(decile_&anvar./2)); run; /*lets see how well we did in our deciling?*/ proc summary data = &OutDSN nway missing; class decile_&anvar.; var &anvar.; output out = crunch (drop = _type_) sum=;run; proc print data = crunch; title "The variable &AnVar has &NoOfMissing rows containing zero or missing in the &NoOfRows rows in &InDSN"; title2 "So &PctOfMissing.% of the rows do not contribute to the total of the variable &AnVar"; sum _Freq_ &anvar.; format _Freq_ &anvar. comma20.; run; proc tabulate data=&OutDSN missing /*Noseps *& format crams more data on a page*/; class decile_&anvar. Semi_decile_&anvar. Quintile_&anvar.; var &anvar.; table decile_&anvar. all ,&anvar.*(N*format=comma9.0 Sum*format=comma20.2 colpctN*format=7.2 colpctsum*format=7.2 range*format=comma16.2 mean*format=comma16.2 min*format=comma16.2 max*format=comma16.2 P1*format=comma16.2 P5*format=comma16.2 P95*format=comma16.2 P99*format=comma16.2 ) / rts=15 box="Deciling &InDSN - Checking that the sum of &AnVar is evenly distributed in the decile and count of rows is skewed"; table Semi_decile_&anvar. all ,&anvar.*(N*format=comma9.0 Sum*format=comma20.2 colpctN*format=7.2 colpctsum*format=7.2 range*format=comma16.2 mean*format=comma16.2 min*format=comma16.2 max*format=comma16.2 P1*format=comma16.2 P5*format=comma16.2 P95*format=comma16.2 P99*format=comma16.2 ) / rts=15 box="Deciling &InDSN - Checking that the sum of &AnVar is evenly distributed in the Semi-Decile and count of rows is skewed"; table Quintile_&anvar. all ,&anvar.*(N*format=comma9.0 Sum*format=comma20.2 colpctN*format=7.2 colpctsum*format=7.2 range*format=comma16.2 mean*format=comma16.2 min*format=comma16.2 max*format=comma16.2 P1*format=comma16.2 P5*format=comma16.2 P95*format=comma16.2 P99*format=comma16.2 ) / rts=15 box="Deciling &InDSN - Checking that the sum of &AnVar is evenly distributed in the Quartile and count of rows is skewed"; KEYLABEL N = "Count of Rows in &InDsn in this level of grouping" Sum ="Sum of the variable &AnVar in this level of grouping" colpctN ="% of the rows in the data set total in this level of grouping" colpctsum="% of the data set total for &AnVar in this level of grouping" Range="Range of the variable &AnVar in this level of grouping" mean="Mean average for value of the variable &AnVar in this level of grouping" Min="Min value of the variable &AnVar in this level of grouping" Max="Max value of the variable &AnVar in this level of grouping" P1="1% from smallest value of the variable &AnVar in this level of grouping" P5="5% from smallest value of the variable &AnVar in this level of grouping" P95="95% from smallest value of the variable &AnVar in this level of grouping" P99="99% from smallest value of the variable &AnVar in this level of grouping" ; run; PROC OPTLoad data=ToRestore; run; %mend decile; /*An example so you can see output*/ %decile (InDSN=sashelp.Stocks /*Input data set*/ ,AnVar=Volume /*Variable we wish to "bucket"*/ ,OutDSN=TradingDays_Deciled /*Output data set w/ variables: decile_&anvar. Semi_decile_&anvar. Quartile_&anvar. */ ); 15 1 ‘m252 3 %Write2Excel 1 332 1 577 /********************************************************************************** NOTE: NOTE: NOTE: NOTE: NOTE: What you see in DOS windows in not what DOS sees. C:\Program Files\Microsoft Office\Office10\EXCEL.EXE" is seen, by DOS, as : C:\Program Files\Microsoft Office 15\Office10\EXCEL.EXE; The command x "C:\Program Files\Microsoft Office97\Office\EXCEL.EXE"; WILL NOT START EXCEL The real DOS path can not contain directory names longer than 8 characters. The real DOS path often has ~ in it. Your path may differ from the ones in this paper. YOU MUST FIND THE PATH TO YOUR OWN EXCEL.EXE use the dos window and run dir /X to see the names that DOS sees ***********************************************************************************/ /********************************************************************************** NOTE: NOTE: NOTE: NOTE: This, at the last call, writes some information to a "summary sheet" Please see the section that starts with %if (&SaveNowYN =Y) %then This is an illustration of a common task - writing to a summary sheet. The code in this section of the program does not useful work, but is for illustration only. It is very unlikely that this code, as is stands, meets your needs. Please feel free to delete this if it is not needed or to modify the code to meet your needs ***********************************************************************************/ /******************************************************************************* NOTE: NOTE: NOTE: NOTE: NOTE: An earlier AND SIMPLER version of this code, without paramter checking, is described in a paper that can be found at: http://www.lexjansen.com/phuse/2010/cc/cc01.pdf Frankly, since ive used this enough to fix it, I prefer the code without the error checking ***********************************************************************************/ /******************************************************************************* Program: %Write2ExcelV4 Dev/Active/Inactive: Active Programmer: rl Program Owner: TheSASCommunity Business Owner: TheSASCommunity Date Pgm. Started: XXXXXXXXXX Date Pgm. Finished: XXXXXXXXXX Client: TheSASCommunity Study : XXXXXXXXXX Purpose: Write SAS files to Excel using DDE - automatically dimension writing area *********** Preceeding: Programs that must be run before this can be run N/A Concurrent: Programs that can be run concurrent with this N/A Following: Programs that Can only be run after this finishes N/A Driver files: External files containg metadata to control program execution Parameters Infiles: perm files USED by this program Parameters Outfiles: perm files CREATED by this program Parameters Macros called: perm macros called by this program none Formats called: perm formats called by this program none Maintenance: Date: XX/XX/XXXX Programmer: XX Issue: XXXXXXXXXXXXXXXXXXX Date: XX/XX/XXXX Programmer: XX Issue: XXXXXXXXXXXXXXXXXXX Date: XX/XX/XXXX Programmer: XX Issue: XXXXXXXXXXXXXXXXXXX *******************************************************************/ %macro skip; /*Use these lines for createing global macro values debugging or learning the code*/ options mprint mcompilenote=all source source2; /*Set global macro variables so a new user can step throught The code*/ %let FirstWrite=Y; /*A Y here will cause SAS to start Excel. AND MUST be valued as Y for the Macro to open an Excel template - used for first call fo XLS sheet*/ %let SASFile=SASHelp.class; /*File to send to the XLSDataTab Xls sheet*/ %let whereClause=%str(where Sex="F";); /*a complete where statement with semicolon*/ /*eg: %str(where 1=1;) */ %let DropVars=%str((drop=sex)); /*a complete "drop data set option" with /* ()and withOUT semicolon eg; (drop=SortOrder4Prod) */ %let XLSDataTab=Sheet2; /*Tab to which to write the table in SASFile*/ %let XLSSmryTab=Sheet1; /*Often,at the end of loading a template, we write one or two pieces of info to a summary tab*/ %let StartRowNo=5; /*You do not have to start writing in R1C1 -Look at the template-*/ /*See where the data section starts*/ %let StartColNo=1; /*You do not have to start writing in R1C1 -Look at the template-*/ /*See where the data section starts- sometimes we start at column 2*/ %let templateLoc=; %let templateLoc=%str(C:\test\template.xls); /*path to the template. If you value this AND set firstWrite to Y */ /*, the macro will open the template*/ %let SaveNowYN=Y; /*Saves & Closes Excel. After writing last tab in a multi-tab SS, */ %let NewName= ; /*change to Y & enter path in NewName*/ %let NewName=C:\Test\Girls.xls; /*save the XLS sheet under this name. */ %mend skip; %MACRO Write2XlsV4( /*Write ONE SAS file to ONE Tab of an Excel Workbook*/ FirstWrite= /*A Y here will cause SAS to start Excel. AND MUST be valued as Y for the Macro to open an Excel template - used for first call fo XLS sheet*/ ,SASFile= /*File to send to the XLSDataTab Xls sheet*/ ,whereClause= /*a complete where statement eg: %str(where 1=1;) */ ,DropVars= /*a complete "drop data set option" with and withOUT semicolon eg; (drop=SortOrder4Prod) */ ,XLSDataTab= /*Tab to which to write the table in SASFile*/ ,XLSSmryTab= /*Often,at the end of loading a template, we write one or two pieces of info to a summary tab*/ ,StartRowNo=5 /*You do not have to start writing in R1C1 -Look at the template-*/ /*See where the data section starts*/ ,StartColNo=1 /*You do not have to start writing in R1C1 -Look at the template-*/ /*See where the data section starts- sometimes we start at column 2*/ ,templateLoc= /*path to the template. If you value this AND set firstWrite to Y*/ /*, the macro will open the template*/ ,SaveNowYN=N /*Saves & Closes Excel. After writing last tab in a multi-tab SS,*/ /*change to Y & enter path in NewName*/ ,NewName=C:\Temp\DashBoard.xls /*save the XLS sheet under this name. Saving only happens when SaveNowYN=Y */ ,DebugYN=Y /*If DebugYN is Y, then files are not deleted and additaion output is sent to the log*/ ); /*many parameters are not required and do not need flags*/ %local FirstWriteFL SASFileFl XLSDataTabFl StartRowNoFl StartColNoFl TemplateLocFl SaveNowYNFl FrstAndTempFl SaveAndNameFl DebugYNFl; %let FirstWrite=%upcase(&FirstWrite); %let SaveNowYN =%upcase(&SaveNowYN); %let DebugYN =%upcase(&DebugYN); /*Initialize local macro variables*/ %let FirstWriteFL =N; %let SASFileFL =N; %let XLSDataTabFl =N; %let StartRowNoFl =N; %let StartColNoFl =N; %let TemplateLocFl=N; %let SaveNowYNFl =N; %let FrstAndTempFl=N; %let SaveAndNameFl=N; %let DebugYNFl =N; /***************************************************************** Section: Check Parameter Section ******************************************************************/ /*Check FirstWrite Y N */ %if (&FirstWrite NE Y) And (&FirstWrite NE N) %then %do;/*A data set name was not entered - it should be*/ %let FirstwriteFL=Y; %end; /*WhereClause is not needed. Check might be included in future release*/ /*Dropvars are not needed. Check might be included in future release */ %if %sysfunc(exist(&SASFile)) =0 %then %let SASFileFl=Y; /*Does SAS file exist*/ %if &XLSDataTab = %then %do;/*An XLS tab was not entered - it should be*/ %let XLSDataTabFl=Y; %end; /*Check XLSSmryTab Is optional at any particular call. Check might be included in future release*/ %if &StartRowNo = %then %do;/*A starting row was not entered - it should be*/ %let StartRowNoFl=Y; %end; %if &StartColNo = %then %do;/*A starting Column was not entered - it should be*/ %let StartColNoFl=Y; %end; /*if no template specified, write to the sheet that opens when we open excel*/ %if (%length(&TemplateLoc) NE 0 ) %then %do;/*ONLY If a template location is entered, the template must exist*/ %if %sysfunc(FileExist(&TemplateLoc)) =0 %then %let TemplateLocFl=Y; %end; %if &SaveNowYN = Y or &SaveNowYN = N %then %do;/*Should be Y or N */ %let SaveNowYNFl=N; %end; %Else %let SaveNowYNFl=Y; /*If FirstWrite =Y , then templateloc must be valued*/ %if (&FirstWrite = Y ) and (&templateloc = ) %then %let FrstAndTempFl=Y; /*If SaveNowYN is Y then NewName must be valued*/ %if ( (&SaveNowYN = Y) and (&NewName = ) ) %then %let SaveAndNameFl=Y; /*Check DebugYN Y N */ %if (&DebugYN NE Y) And (&DebugYN NE N) %then %do;/*A data set name was not entered - it should be*/ %let DebugYNFL=Y; %end; %macro ExtraInfo; %Put ***********************************************************************************; %put FirstWriteFL =&FirstWriteFL ; %put SASFileFL =&SASFileFL ; %put XLSDataTabFl =&XLSDataTabFl ; %put StartRowNoFl =&StartRowNoFl ; %put StartColNoFl =&StartColNoFl ; %put TemplateLocFl =&TemplateLocFl ; %put SaveNowYNFl =&SaveNowYNFl ; %put FrstAndTempFl =&FrstAndTempFl ; %put SaveAndNameFl =&SaveAndNameFl ; %let DebugYNFl =&DebugYNFl; %Put ***********************************************************************************; %mend ExtraInfo; %if &debugYN = Y %then %do; %ExtraInfo %end; %put ***************************************************************************************************************; %If &FirstWriteFL =Y or &SASFileFL =Y or &XLSDataTabFl=Y or &StartRowNoFl =Y or &StartColNoFl =Y or &TemplateLocFl=Y or &SaveNowYNFl =Y or &FrstAndTempFl=Y or &SaveAndNameFl=Y or &&DebugYNFl =Y %THEN %DO; %put _user_; data _null_; /*lines go out about 135 columns - sorry about that*/ Put "***********************************************************************************************************************"; Put "In &SysMacroName, execution is terminating due to problems with parameters." ; %if &FirstWriteFL =Y %then put "ER" "ROR: The parameter (FirstWrite) should be Y or N. It is: &FirstWrite"; ; %if &SASFileFL =Y %then put "ER" "ROR: The parameter (SASFileFL) could not be found. Does &SASFile exist?"; ; %if &XLSDataTabFl=Y %then put "ER" "ROR: The parameter (XLSDataTabFl) is valued as: &XLSDataTabFl"; ; %if &StartRowNoFl =Y %then put "ER" "ROR: The parameter (StartRowNo) must exist. It is incorrectly valued as: &StartRowNo"; ; %if &StartColNoFl =Y %then put "ER" "ROR: The parameter (StartColNo) must exist. It is incorrectly valued as: &StartColNo"; ; %if &TemplateLocFl=Y %then put "ER" "ROR: Can not file the file in the parameter (TemplateLoc) Check: &TemplateLoc"; ; %if &SaveNowYNFl =Y %then put "ER" "ROR: The parameter (SaveNowYN) should be Y or N. It is: &SaveNowYN"; ; %if &FrstAndTempFl=Y %then put "ER" "ROR: If FirstWrite is Y, then TemplateLoc must be valued"; ; %if &SaveAndNameFl=Y %then put "ER" "ROR: If SaveNowYN is Y, then NewName must be valued; "; ; %if &DebugYNFl =Y %then put "ER" "ROR: The parameter (DebugYN) should be Y or N. It is: &DebugYN"; ; Put "***********************************************************************************************************************"; run; %goto SkipCode; /*Skip the code - no need to run anything*/ %End; %else %do; data _null_; Put "*****************************************************************"; Put "In &SysMacroName, the parameters passed the implemented checks"; put " Executing code "; put " FirstWrite = &FirstWrite"; put " SASFile = &SASFile "; put " WhereClause=%NRBQuote(&whereClause)"; put " DropVars = &DropVars"; put " XLSDataTab = &XLSDataTab"; put " XLSSmryTab = &XLSSmryTab "; put " StartRowNo = &StartRowNo "; put " StartColNo = &StartColNo"; put " TemplateLoc= &TemplateLoc"; put " SaveNowYN = &SaveNowYN"; put " NewName = &NewName"; put " DebugYN = &DebugYN"; Put "*****************************************************************"; run; %end; /***************************************************************** Section: Save environment so it can be restored ******************************************************************/ PROC OptSave out=_M_OptsBefore ; /*save environment (most options)*/ run; /*Save titiles and footnotes and restore then when you close*/ options mcompilenote=all mlogic mprint source source2 nocenter; Proc SQL;/*If you really want to be fussy, be sure that _M_titles does not already exist- see below*/ Create table _M_titles as select Type, number, text from sashelp.vtitle where upcase(type)="T"; Proc SQL;/*If you really want to be fussy, be sure that _M_footers does not already exist- see below*/ Create table _M_footers as select Type, number, text from sashelp.vtitle where upcase(type)="F"; quit; %if &DebugYN = Y %then %do; options Mprint Mlogic Symbolgen nocenter LS=120 source source2; %end; %Else %do; options Mprint NoMlogic NoSymbolgen; %end; /*this program is written in many Sub-macros so you can step through the program*/ /***************************************************************** Section : Do actual work Below ******************************************************************/ %macro OpenExcel; %if (&FirstWrite =Y)%then /*This is the first time we write to the XLS sheet - we need to open it*/ %do; options noxwait noxsync; /*Tells SAS not to wait for DOS commans to execute*/ /* NOTE: A command like the one below will not start excel! x "C:\Program Files\Microsoft Office97\Office\EXCEL.EXE"; You Must use the command dir /X to see the real paths that DOS uses */ *x "C:\Progra~1\MIFF2D~1\Office\EXCEL.EXE"; /*Path to excel on one of my laptops - Likely NOT to your Excel*/ * X "C:\Program Files\Microsoft Silverlight\MICROS~3.lnk"; /*Path to excel on a different one of my laptops - Likely NOT to your Excel*/ * "C:\Program Files\Microsoft Office\Office10\EXCEL.EXE" TURNS INTO: C:\Program Files\Microsoft Office 15\Office10\EXCEL.EXE; x "C:\Program Files\Microsoft Office 15\Office10\EXCEL.EXE"; DATA _NULL_; Rc = SLEEP(5); RUN; %end; %mend OPenExcel; %OpenExcel; %macro OpenTemplate; /*This macro can be used to write to several pages to a new SS, or template, and we ONLY open the Template under tow coinditions: 1) on the first call and 2) if it the user has specified a template - We Must tell the macro if this is the first call and if the template was specified*/ /*If you ask Excel to open the template and it does not exist, Excel will tell you via a message box*/ %if ( (%length(&templateLoc) GT 0 ) /*if GT 0, User has specified a template*/ and ( &FirstWrite =Y ) ) %then %do; /*if above is true, user has specified a template to which he wants to write*/ /*if no template specified, write to the sheet that opens when we open excel*/ Filename Excel dde 'EXCEL|SYSTEM'; data _null_; file excel; put "[open(""&TemplateLoc"")]"; run; %end; %else %do; %put No template specified; %end; %mend OpenTemplate; %OpenTemplate; %macro CleanUp; /*If they exist, remove working files before running again - defensive coding*/ %if %sysfunc(exist(GoodObs))NE 0 %then %do; Proc SQL; Drop table _M_GoodObs; Drop table _M_VarsToExport; quit; %end; %else %do; %put NO table cleanup required - no table to drop; %end; %mend CleanUp; %cleanUp; /*We might want to filter observations on a variable we do not want to send to Excel*/ /*So we filter observations ASAP and drop variables in the next step*/ Data _M_GoodObs&DropVars; /* the parameter might be: DropVars=%str((drop=sex));*/ set &SASFile; &whereClause; /*<----- Drop rows you do NOT want to print*/ /*This, and multiple calls of the macro, can be used to split files that are too large (GT 66K rows) to fit on an XLS sheet into smaller files that can we written to different sheets */ run; /*For the DDE, we need to know how many obs and variables are in the file we are exporting. Put the number of rows and columns we want to write into macro variables so we can dimension the DDE writing area*/ /*Note &DropVars above. You do not have to export all the variables */ Proc Contents data=_M_GoodObs varnum noprint out=_M_VarsToExport ; run;/* create data set with variables info--*/ Proc Sort data=_M_VarsToExport ; by varnum; run; Data _null_; /*put # of vars. to export in a macro var- This number is used to dimension the DDE "writing" area*/ if 0 then set _M_VarsToExport Nobs=NOfObs; call symput("NoOfVars",Strip((put(NOfObs,best12.)))); run; %put We have &NoOfVars Variables to export from &&SASFile ; Data _null_; /*in the DDE, We need to be able to loop and "write" the names of the variables*/ set _M_VarsToExport(keep=name); /*create an array of macro variables*/ call symput("vn"||left(Put(_n_,7.)),name); /*DANGER! hardcode of format*/ run; %macro LeaveRecord; /*As a debugging tool, write the variables we want to export in the log*/ %put ; %put We are going to use a macro loop to write variables in a put statement for DDE; %do QC=1 %to &NoOfVars; %put for loop number &qc the variable we write is &&vn&QC; %end; %mend LeaveRecord; %if &debugYN =Y %then %do; %LeaveRecord; /*leave a record of what we plan to do*/ %end; Data _null_; /*Put # of rows in macro- This number is used to dimension the DDE "writing" area */ if 0 then set _M_GoodObs Nobs=NOfObs; call symput("NoOfRows",Strip(NOfObs)); If NOfObs GT 3 then do; /*DANGER HARDCODED NOTE*/ put "*************************"; put "WA" "RNING ** some version of Excel can hold only 66,000 rows"; put "There are " NOfObs " rows in this file."; put " Check to see if this might fill up an XLS sheet"; put "*************************"; end; run; %put After applying the where clause, we want to print &NoOfRows rows from the file &SASFile; /*Immediately below is the main trick of the program - use macro vars & %eval to dim the writing area*/ filename blah dde "excel|&XLSDataTab!R&StartRowNo.C&StartColNo.:R%eval(&StartRowNo+&NoOfRows)C%eval(&StartColNo+&NoOfVars)" NOTAB; /* in statement above, we dimensioned the DDE "writing" area */ Data _null_; /*this data null reads the GoodObs table and does the writing to excel*/ set _M_GoodObs; file blah LRECL=2050; /*The value of Lrecl can range from 1 to 1,048,576 (1 megabyte). According to the experience of SAS experts, an Lrecl of 8192 covers 99% of the cases that most SAS programmers encounter. */ %macro LoopOverVars; /*use a loop to list all the variable names in the DDE statement*/ put %do k=1 %to &NoOfVars; &&vn&k "09"X /*This writes the put statement*/ %end ; %mend LoopOverVars; %LoopOverVars; run; %if (&SaveNowYN =Y) %then %do; /*If you tell the macro you have written the last data tab, it will 1)** Write any information to the "summary sheet" 2)** Put the date in Cell A2 of Sheet 1 3)** Save the file under a new name */ Filename Sumry dde "excel|&XLSSmryTab!R1C1:R3C2" NOTAB; /*HARDCODED range*/ /*This writing should not â€Overlap" the range where we write data*/ Data _null_; /*HARDCODE -AS EXAMPLE *We write the 6 cells below into a 3 by 2*/ file Sumry LRECL=2050; Put "Put in Cell A1" "09"X "Put in Cell A2" "09"X ; Put "Run On:" "09"X "%sysfunc(Date(),worddate18.)" "09"X ; Put "Put in Cell A3" "09"X "Put in Cell B3" "09"X ; run; Filename Final dde "excel|&XLSSmryTab!R1C1:R1C1" NOTAB; /*HARDCODE*/ /*(above) Make &XLSSmryTab active before saving then (below)Save and rename*/ filename outexcel dde "EXCEL|SYSTEM"; data _null_; file outexcel; put "[save.as(""&NewName"")]"; put "[close]"; put "[quit]"; run; %end; /*Restore environment************************************************************/ PROC OptLoad Data=_M_OptsBefore ; run; data _Null_; set _M_titles; call execute("title"||Strip(number)||" "||'"'||strip(text)||'";'); run; data _null_; set _M_footers; call execute("Footnote"||Strip(number)||" "||'"'||strip(text)||'";'); run; %if &DebugYN = N %then %do; /*Delete the working files*/ proc sql Noprint; select memname into :MacroTables separated by ' ' from dictionary.tables where libname="WORK" and substr(memname,1,3) = "_M_" ; quit; Proc datasets lib=work; delete &MacroTables; quit; %end; %SkipCode: /*This line is the destination if there is a problem wiht parameters*/ %Put The macro (&sysmacroname) is ending at %sysfunc(Date(),worddate18.); %Mend Write2XlsV4; /*EXAMPLE MACRO CALLS TO ILLUSTRATE USE OF MACRO*/ %Write2XlsV4( /*Write ONE SAS file to ONE Tab of an Excel Workbook*/ FirstWrite=Y /*A Y here will cause SAS to start Excel. AND MUST be valued as Y for the Macro to open an Excel template - used for first call fo XLS sheet*/ ,SASFile=SASHelp.class /*File to send to the XLSDataTab Xls sheet*/ ,whereClause=%str(where sex="F";) /*a complete where statement eg: %str(where 1=1;) */ ,DropVars=%str((drop=sex)) /*a complete "drop data set option" with ()*/ /*and withOUT semicolon eg; (drop=SortOrder4Prod) */ ,XLSDataTab=Sheet2 /*Tab to which to write the table in SASFile*/ ,XLSSmryTab= /*Often,at the end of loading a template, */ /*we write one or two pieces of info to a summary tab*/ ,StartRowNo=5 /*You do not have to start writing in R1C1 */ /* -Look at the template- See where the data section starts*/ ,StartColNo=1 /*You do not have to start writing in R1C1 -Look at the template- */ /*See where the data section starts- sometimes we start at column 2*/ ,templateLoc=%str(C:\test\template.xls) /*path to the template. If you value this AND set firstWrite to Y*/ /* the macro will open the template*/ ,SaveNowYN=N /*Saves & Closes Excel.*/ /*After writing last tab in a multi-tab SS,*/ /*change to Y & enter path in NewName*/ ,NewName= /*save the XLS sheet under this name.*/ /*Saving only happens when SaveNowYN=Y */ ,DebugYN=N ); /*EXAMPLE MACRO CALLS TO ILLUSTRATE USE OF MACRO*/ %Write2XlsV4( /*Write ONE SAS file to ONE Tab of an Excel Workbook*/ FirstWrite=N /*A Y here will cause SAS to start Excel. AND MUST be valued as Y for the Macro to open an Excel template - used for first call fo XLS sheet*/ ,SASFile=SASHelp.class /*File to send to the XLSDataTab Xls sheet*/ ,whereClause= /*a complete where statement eg: %str(where 1=1;) */ ,DropVars= /*a complete "drop data set option" with ()*/ /*and withOUT semicolon eg; (drop=SortOrder4Prod) */ ,XLSDataTab=Sheet1 /*Tab to which to write the table in SASFile*/ ,XLSSmryTab= /*Often,at the end of loading a template, */ /*we write one or two pieces of info to a summary tab*/ ,StartRowNo=10 /*You do not have to start writing in R1C1 */ /* -Look at the template- See where the data section starts*/ ,StartColNo=2 /*You do not have to start writing in R1C1 -Look at the template- */ /*See where the data section starts- sometimes we start at column 2*/ ,templateLoc= /*path to the template. If you value this AND set firstWrite to Y*/ /* the macro will open the template*/ ,SaveNowYN=N /*Saves & Closes Excel.*/ /*After writing last tab in a multi-tab SS,*/ /*change to Y & enter path in NewName*/ ,NewName= /*save the XLS sheet under this name.*/ /*Saving only happens when SaveNowYN=Y */ ,DebugYN=N ); %Write2XlsV4( /*Write ONE SAS file to ONE Tab of an Excel Workbook*/ FirstWrite=N /*A Y here will cause SAS to start Excel. AND MUST be valued as Y for the Macro to open an Excel template - used for first call fo XLS sheet*/ ,SASFile=SASHelp.class /*File to send to the XLSDataTab Xls sheet*/ ,whereClause=%str(where sex="M";) /*a complete where statement eg: %str(where 1=1;) */ ,DropVars=%str((drop=sex)) /*a complete "drop data set option"*/ /* with () and withOUT semicolon eg; (drop=SortOrder4Prod) */ ,XLSDataTab=Sheet3 /*Tab to which to write the table in SASFile*/ ,XLSSmryTab=Sheet1 /*Often,at the end of loading a template, we write one or two pieces of info to a summary tab*/ ,StartRowNo=5 /*You do not have to start writing in R1C1 -Look at the template-*/ /*See where the data section starts*/ ,StartColNo=1 /*You do not have to start writing in R1C1 -Look at the template-*/ /*See where the data section starts- sometimes we start at column 2*/ ,templateLoc= /*path to the template. If you value this AND set firstWrite to Y */ /*, the macro will open the template*/ ,SaveNowYN=Y /*Saves & Closes Excel. After writing last tab in a multi-tab SS,*/ /*change to Y & enter path in NewName*/ ,NewName=C:\Test\GirlsAndBoys.xls /*save the XLS sheet under this name.*/ /* Saving only happens when SaveNowYN=Y */ ); 270 1 ÿ252 3 airy( 1 332 1 5 AIRY(x) The AIRY function returns the value of the airy function (Abramowitz and Stegun 1964; Amos, Daniel and Weston 1977) (See References). It is the solution of a differential equation x=airy(2.0); 0.0349241304 207 1 z252 3 anyalnum( 1 332 1 31 ANYALNUM(string <,start>) Searches a character string for an alphanumeric character and returns the first position at which it is found string specifies the character expression to search. start is an optional (integer) position at which the search should start and the direction in which to search. data _null_;/*scanning let to right*/ string='Next = Last + 1;'; j=0; do until(j=0); j=anyalnum(string,j+1); if j=0 then put +3 "That's all"; else do; c=substr(string,j,1); put +3 j= c=; end; end; run; data _null_;/*scanning right to left*/ string='Next = Last + 1;'; j=999999; do until(j=0); j=anyalnum(string,1-j); if j=0 then put +3 "That's all"; else do; c=substr(string,j,1); put +3 j= c=; end; end; run; 95 1 ş252 3 anyalpha( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 96 1 =252 3 anycntrl( 1 332 1 1 anyCntrl( string< , start> ) 97 1 ş252 3 anydigit( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 98 1 =252 3 anyfirst( 1 332 1 1 anyFirst( string< , start> ) 99 1 >252 3 anygraph( 1 332 1 1 anyGraph( string< , start> ) 100 1 ÿ252 3 anylower( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 101 1 ı252 3 anyname( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 33 1 <252 3 anyprint( 1 332 1 1 anyPrint( string< , start> ) 0 1 ı252 3 anypunct( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 3 1 ı252 3 anyspace( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 5 1 ı252 3 anyupper( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 6 1 ?252 3 anyxdigit( 1 332 1 1 anyXDigit( string< , start> ) 48 1 ,252 3 arcos( 1 332 1 1 arcos(number) 308 1 H252 3 array 1 332 1 153 /*array Lbound Hbound Dim _temporary_*/ /* This example is weak on multi-dimensional arrays - DIM always returns a total count of the number of elements in an array dimension. HBOUND returns the literal value of the upper bound of an array dimension. The LBOUND function returns the lower bound of a one-dimensional array or the lower bound of a specified dimension of a multidimensional array. temporaty arrays are faster than "regular" arrays*/ data ClassCount; /*Count the number of students in each age*/ /*Lets assume students are between 1 and 20 years old for one array and 0 and 25 for the other array*/ retain age1-age20 NoOfMales NoOfFemales /*temp arrays are automatically retianed*/; /*So we do NOT need a retain for the temp array variables*/ set sashelp.class end=EOF; /*an array statement will create new variables*/ array NumAgCt(20) age1-age20; /*varaibles in this array have two "names"*/ array TempAgCt(0:25) _temporary_; /*temp array variables only have one "name"*/ array NumSexCt(2) NoOfMales NoOfFemales; /*varaibles in this array have two "names"*/ /*Initialize the array elements to zero*/ if _n_=1 then Do; Do LoopCntr=Lbound(NumAgCt) to Hbound(NumAgCt); NumAgCt(LoopCntr)=0; put "initializing the smaller array " LoopCntr= " is the value of the index counter and " NumAgCt(LoopCntr)=; end; put "1 "; Do LoopCntr=Lbound(TempAgCt) to Hbound(TempAgCt); TempAgCt(LoopCntr)=0; put "initializing the larger array " LoopCntr= " is the value of the index counter and " TempAgCt(LoopCntr)=; End; put "2 "; NumSexCt(1)=0; /*access the variable through the array "name" */ NoOfFemales=0; /*access the variable through the variable "name" */ End; /*Perm variables-Count students in age buckets - the age of the student is the bucket/cell number*/ NumAgCt(age)=NumAgCt(age)+1 ; put "Loading a student with " age= " so " NumAgCt(age)= ; /*Temp variables-Count students in ages - the age of the student is the bucket/cell number*/ TempAgCt(age)=TempAgCt(age)+1 ; if sex="M" then NumSexCt(1)+1; else if sex="F" then NoOfFemales+1; else put "Er" "ror in the gender value"; if EOF=1 then do; put "3"; do LoopPrm= Lbound(NumAgCt) to Hbound(NumAgCt) ; put "values from the perm array (with fewer cells:) " LoopPrm= "and the value is " NumAgCt(LoopPrm)=; end; put "4"; do loopTmp= Lbound(TempAgCt) to Hbound(NumAgCt) ; put "Printing values from the temp Un-Retained array: " LoopTmp= "and the value is " TempAgCt(loopTmp)=; end; put "5"; do LoopSex=1 to 2 by 1; put "Printing counts of the genders: " LoopSex= "and the value is " NumSexCt(LoopSex)=; end; end; run; proc print data= ClassCount; title "note that we do not have any of the temp variables"; run; title ""; /*Dim and char and num arrays*/ /*In this example, DIM returns a value of 5. Therefore, SAS repeats the statements in the DO loop five times. */ data C_and_N_arrays; set sashelp.class; /*We will copy from some source arrays to destination arrays*/ array NumSrcA{3} age--weight; /*Note double dash to get all vara on the PDV between listed vars*/ array ChrSrcA{2} $ name sex ; array NumDstA{3} DAge DHeight Dweight; /*Note double dash to get all vara on the PDV between listed vars*/ array ChrDstA{2} $ Dname Dsex ; /*do some silly transforms below*/ do ChCntr=1 to dim(ChrSrcA); ChrDstA(ChCntr) =ChrSrcA(ChCntr); /*copy from source to destination*/ substr(ChrDstA{ChCntr},1,1)="X"; /*A silly transform*/ end; do NmCntr=1 to dim(NumDstA); NumDstA(NmCntr)=NumSrcA(NmCntr); /*copy from source to destination*/ NumDstA(NmCntr)=NumDstA(NmCntr)+(NmCntr*1000);/*A silly transform*/ end; /*Show stuff in the log*/ do i=1 to dim(NumSrcA); Put "the value is: " NumSrcA(i)=; end; run; proc print data= C_and_N_arrays; title "note that we do not have any of the temp variables"; run; title ""; /*Examples of Character Arrays and inputting into an array - useful for creating an array from a table*/ data CharArray; /*Character arrays*/ array names{*} $ n1-n10; array capitals{*} $ c1-c10; input names{*}; do i=1 to 10; capitals{i}=upcase(names{i}); end; do PutLoop=1 to 10; put names(PutLoop)= " and " capitals(PutLoop)= ; end; datalines; smithers michaels gonzalez hurth frank bleigh rounder joseph peters sam ; proc print data=CharArray; title "Note only one observation -you can merge to all obs or retain but consider a hash object"; run; title ""; /*To create a temporary array, use the _TEMPORARY_ argument. The following example creates a temporary array named TEST: */ /**/ options nodate pageno=1 linesize=80 pagesize=60 nocenter; data score2(drop=i); array test{3} Avg4Test1-Avg4Test3 (87 77 80); /*Perm array of class average scores - assign initial values*/ *array test{3} _temporary_ (87 77 80); /*Temp array of class average scores - assign initial values*/ array score{3} StudGrade1-StudGrade3; input StudentId Score{*}; CountAboveAve=0; /*initialize ofr eash student*/ do i=1 to 3; if score{i}>=test{i} then do; CountAboveAve+1; end; end; datalines; 7777 99 60 82 5678 80 85 75 8888 86 76 79 ; proc print noobs data=score2; title 'Data Set SCORE2'; run; 259 1 ,252 3 arsin( 1 332 1 1 arsin(number) 309 1 *252 3 atan( 1 332 1 1 atan(number) 310 1 L252 3 band( 1 332 1 1 bAnd( nonnegativeInteger , nonnegativeInteger ) 90 1 3252 3 beta( 1 332 1 1 beta( shape , shape ) 208 1 f 252 3 Binary_BigFileSortedWithDuplicates 1 332 1 111 /**************************************************************** Section: 0- Create data sets *****************************************************************/ Options nocenter; Proc SQL; create table WantInfo ( SID Char(4) , Sex Char(1) ); insert into WantInfo values("0001","F") values("3999","F") values("2222","M") values("3134","F") /*values("6090","M")*/ values("7777","M"); proc print data=Wantinfo; title "Wantinfo"; run; Proc SQL; Create table SWantInfo as select * from WantINfo Order by SID; proc print data=swantinfo; title "swantinfo"; run; proc SQL; Create table BigLookIn (SID char(4) , ARM Char(1) ); insert into BigLookIn values("8811","A") values("9033","B") values("9099","A") values("2999","B") values("3453","A") values("3999","B") values("4444","A") values("4766","A") values("5020","B") values("0001","A") values("0099","B") values("1005","B") values("1087","B") values("2111","A") values("5111","A") values("6090","A") values("6888","B") values("7666","A") values("7777","B") values("8188","A"); /*Proc Print data=BigLookIn;*/ /*run;*/ Create table SBigLookIn as select * from BigLookIn order by SID; Create table SDupIn (SID char(4) , test Char(1) ); insert into SDupIn values("0001","N") /*match*/ values("2222","A") /*match*/ values("2222","N") /*match*/ values("2222","A") /*match*/ values("2999","N") values("3453","A") values("3453","N") values("3999","A"); /*match*/ quit; proc print data=SBigLookIn; title "SBigLookIn"; run; /**************************************************************** Section:_6_ example 6 *****************************************************************/ /*below is binary search of a sorted BIG FILE that has duplicates - for ID in samll file, can we find match in Large*/ data Example6 ; set SWantInfo ; L = 1 ; H = n ; /*low starts at first obs, high at last obs*/ do until ( L > H | MatchF ) ; pntr = floor ((L + H) * .5) ; /*pointer for the Binary search */ set SDupIn (rename=(SID = SIDBig)) point=pntr nobs=n ; if Sid < SIDBig then H = pntr - 1 ; else if Sid > SIDBig then L = pntr + 1 ; else MatchF = 1 ; end ; if matchF ; /*if match=0/missing -.delete*/ /*IF there are dupes in big- check UP/DOWN from 1st "match"*/ /*Since we will need to search up AND down from where we matched*/ /*Save the current pointer where we found a match in FoundAt*/ FoundAT = Pntr ; do Pntr = (FoundAt - 0) by -1 while ( pntr >= 1 ) ; /*Read DOWN big file*/ set SDupIn (rename=(SID = SIDBig)) point=pntr ; /*read "prev"*/ if SIDbig < SID then leave ;/*IDs <>, stop reading "downâ€*/ output ; end ; do Pntr = (FoundAT + 1) by +1 while ( pntr <= n ) ; /*read UP big file*/ set SDupIn (rename=(SID = SIDBig)) point=pntr ; /*read "next"*/ if SIDbig > SID then leave ; /*IDs <>, stop reading "upâ€*/ output /*output for "up"*/; end ; run ; options nocenter; proc print data=example6; run; 383 1 , 252 3 Binary_DoNot DeleteMismatches 1 332 1 103 /**************************************************************** Section: 0- Create data sets *****************************************************************/ Options nocenter; Proc SQL; create table WantInfo ( SID Char(4) , Sex Char(1) ); insert into WantInfo values("0001","F") values("3999","F") values("2222","M") values("3134","F") /*values("6090","M")*/ values("7777","M"); proc print data=Wantinfo; title "Wantinfo"; run; Proc SQL; Create table SWantInfo as select * from WantINfo Order by SID; proc print data=swantinfo; title "swantinfo"; run; proc SQL; Create table BigLookIn (SID char(4) , ARM Char(1) ); insert into BigLookIn values("8811","A") values("9033","B") values("9099","A") values("2999","B") values("3453","A") values("3999","B") values("4444","A") values("4766","A") values("5020","B") values("0001","A") values("0099","B") values("1005","B") values("1087","B") values("2111","A") values("5111","A") values("6090","A") values("6888","B") values("7666","A") values("7777","B") values("8188","A"); /*Proc Print data=BigLookIn;*/ /*run;*/ Create table SBigLookIn as select * from BigLookIn order by SID; Create table SDupIn (SID char(4) , test Char(1) ); insert into SDupIn values("0001","N") /*match*/ values("2222","A") /*match*/ values("2222","N") /*match*/ values("2222","A") /*match*/ values("2999","N") values("3453","A") values("3453","N") values("3999","A"); /*match*/ quit; proc print data=SBigLookIn; title "SBigLookIn"; run; /**************************************************************** Section:_5_ Example5 - Third Binary search Simple code so that you do not have to delete “small†observations that do not match *****************************************************************/ data Example5; set WantInfo; l=1; h = n; /*If we reset L to 1 each time, we do not need to sort Small*/ /*if No-Match: we will loop through arrays/pdv- to make variables missing */ Array Big_C(*) $ arm; /*list of char vars in Large file*/ /*array Big_N(*)*/ /*List_of_num_vars in Large file;*/ do until (L > H or matchF); pntr = floor((L + H) * .5); /*Big must be sorted ofr binary search to work*/ set SBigLookIn (rename=(SID=SIDBig)) nobs=n point=pntr; if SID < SIDBig then H = pntr - 1; else if SID > SIDBig then L = pntr + 1; else matchF = 1 ; end; if matchF NE 1 then do; /*On Fail to match: Clean PDV-Null NLL vars. from BigFL*/ do i= 1 to dim(Big_C); Big_C(i)=""; end; /*do i= 1 to dim(Big_N);*/ Big_N(i)=. ; end; /*uncomment arrays as needed*/ end; * if matchF; /*Commented out to keep no_matches; run;*/ run; Proc Print data=example5; Run; 382 1 ; 252 3 Binary_SmallAndLargeSortedNoDupes 1 332 1 99 /**************************************************************** Section: 0- Create data sets *****************************************************************/ Options nocenter; Proc SQL; create table WantInfo ( SID Char(4) , Sex Char(1) ); insert into WantInfo values("0001","F") values("3999","F") values("2222","M") values("3134","F") /*values("6090","M")*/ values("7777","M"); proc print data=Wantinfo; title "Wantinfo"; run; Proc SQL; Create table SWantInfo as select * from WantINfo Order by SID; proc print data=swantinfo; title "swantinfo"; run; proc SQL; Create table BigLookIn (SID char(4) , ARM Char(1) ); insert into BigLookIn values("8811","A") values("9033","B") values("9099","A") values("2999","B") values("3453","A") values("3999","B") values("4444","A") values("4766","A") values("5020","B") values("0001","A") values("0099","B") values("1005","B") values("1087","B") values("2111","A") values("5111","A") values("6090","A") values("6888","B") values("7666","A") values("7777","B") values("8188","A"); /*Proc Print data=BigLookIn;*/ /*run;*/ Create table SBigLookIn as select * from BigLookIn order by SID; Create table SDupIn (SID char(4) , test Char(1) ); insert into SDupIn values("0001","N") /*match*/ values("2222","A") /*match*/ values("2222","N") /*match*/ values("2222","A") /*match*/ values("2999","N") values("3453","A") values("3453","N") values("3999","A"); /*match*/ quit; proc print data=SBigLookIn; title "SBigLookIn"; run; /**************************************************************** Section:_4 Example 4 small and large file are sorted NO Duplicatres *****************************************************************/ data example4 ; set SWantInfo; retain L 1; *set initial lower value to 1, Since small is sorted keep old Lower limit using RETAIN ; h = n; * for each obs in small, we reset the upper limit to N; do until (L > H or matchF); /*do until limits converge or we find a match */ pntr = floor((L + H) * .5); /*set P (obs to read) via a binary search*/ set SBigLookIn (rename=(SID=SIDBg)) /*IDL is ID in Large*/ nobs=n point=pntr; if SID < SIDBg then h =pntr - 1; /*If ID in Large is higher than desired, reset Upper to P-1*/ else if SID > SIDBg then l =pntr + 1; /*If ID in Large is Lower than desired, reset Lower to P-1*/ else matchF = 1; end; if matchF; run; proc print data=example4; run; 380 1 % 252 3 Binary_SmallNotSortedLargeSortedNoDupes 1 332 1 100 /**************************************************************** Section: 0- Create data sets *****************************************************************/ Options nocenter; Proc SQL; create table WantInfo ( SID Char(4) , Sex Char(1) ); insert into WantInfo values("0001","F") values("3999","F") values("2222","M") values("3134","F") /*values("6090","M")*/ values("7777","M"); proc print data=Wantinfo; title "Wantinfo"; run; Proc SQL; Create table SWantInfo as select * from WantINfo Order by SID; proc print data=swantinfo; title "swantinfo"; run; proc SQL; Create table BigLookIn (SID char(4) , ARM Char(1) ); insert into BigLookIn values("8811","A") values("9033","B") values("9099","A") values("2999","B") values("3453","A") values("3999","B") values("4444","A") values("4766","A") values("5020","B") values("0001","A") values("0099","B") values("1005","B") values("1087","B") values("2111","A") values("5111","A") values("6090","A") values("6888","B") values("7666","A") values("7777","B") values("8188","A"); /*Proc Print data=BigLookIn;*/ /*run;*/ Create table SBigLookIn as select * from BigLookIn order by SID; Create table SDupIn (SID char(4) , test Char(1) ); insert into SDupIn values("0001","N") /*match*/ values("2222","A") /*match*/ values("2222","N") /*match*/ values("2222","A") /*match*/ values("2999","N") values("3453","A") values("3453","N") values("3999","A"); /*match*/ quit; proc print data=SBigLookIn; title "SBigLookIn"; run; /**************************************************************** Section:3 Example 3 Binary search of large file: Small file: Sorted/Not sorted and duplicates allowed large file: Sorted - not indexed - no duplicates *****************************************************************/ *** Binary search ; proc print data=wantinfo; run; data Example3 ; set WantInfo; l = 1; h = n; do until (l > h or matchF); pntr = floor((l + h) * .5); set SBigLookIn (rename=(SID=SIDBg)) nobs=n point=pntr; if SID < SIDBg then h = pntr - 1; else if SID > SIDBg then l = pntr + 1; else matchF = 1; end; if matchF; run; Proc Print data=example3; Run; 377 1 A 252 3 Binary_SmallSortedLargeSortedNoDupes 1 332 1 100 /**************************************************************** Section: 0- Create data sets *****************************************************************/ Options nocenter; Proc SQL; create table WantInfo ( SID Char(4) , Sex Char(1) ); insert into WantInfo values("0001","F") values("3999","F") values("2222","M") values("3134","F") /*values("6090","M")*/ values("7777","M"); proc print data=Wantinfo; title "Wantinfo"; run; Proc SQL; Create table SWantInfo as select * from WantINfo Order by SID; proc print data=swantinfo; title "swantinfo"; run; proc SQL; Create table BigLookIn (SID char(4) , ARM Char(1) ); insert into BigLookIn values("8811","A") values("9033","B") values("9099","A") values("2999","B") values("3453","A") values("3999","B") values("4444","A") values("4766","A") values("5020","B") values("0001","A") values("0099","B") values("1005","B") values("1087","B") values("2111","A") values("5111","A") values("6090","A") values("6888","B") values("7666","A") values("7777","B") values("8188","A"); /*Proc Print data=BigLookIn;*/ /*run;*/ Create table SBigLookIn as select * from BigLookIn order by SID; Create table SDupIn (SID char(4) , test Char(1) ); insert into SDupIn values("0001","N") /*match*/ values("2222","A") /*match*/ values("2222","N") /*match*/ values("2222","A") /*match*/ values("2999","N") values("3453","A") values("3453","N") values("3999","A"); /*match*/ quit; proc print data=SBigLookIn; title "SBigLookIn"; run; /**************************************************************** Section:4 Binary search of large file: Small file: Sorted - duplicates allowed large file: Sorted - not indexed - no duplicates *****************************************************************/ Data example4 ; set SWantInfo; *Since small is sorted retain old Lower; retain L 1; * for each obs in small, reset upper to N; h = n; do until (L > H or matchF); pntr = floor((L + H) * .5); set SBigLookIn (rename=(SID=SIDBg)) nobs=n point=pntr; if SID < SIDBg then H =pntr - 1; else if SID > SIDBg then L =pntr + 1; else matchF = 1; end; if matchF; run; PROC PRINT DATA=EXAMPLE4; RUN; 381 1 R252 3 blshift( 1 332 1 1 bLShift( nonnegativeInteger , nonnegativeInteger ) 13 1 5252 3 bnot( 1 332 1 1 bNot(nonNegativeInteger) 56 1 J252 3 bor( 1 332 1 1 bOr( nonnegativeInteger , nonnegativeInteger ) 14 1 L252 3 bxor( 1 332 1 1 bXOr( nonnegativeInteger , nonnegativeInteger ) 17 1 W252 3 call allperm( 1 332 1 1 Call allPerm( k , variable1<, variabel2<...>> ) ; 209 1 \252 3 call cats( 1 332 1 1 Call catS( resultVariable< , string1< , string2< ... >> ) ; 4 1 ]252 3 call catt( 1 332 1 1 Call catT( resultVariable< , string1< , string2< ... >> ) ; 10 1 i252 3 call catx( 1 332 1 1 Call catX( separator , resultVariable< , string1< , string2< ... >> ) ; 16 1 l252 3 call compcost( 1 332 1 1 Call compCost( operation1 , value1< , operation2 , value2( , ...>> ) ; 20 1 A252 3 call execute( 1 332 1 25 /*Call execute*/ options mprint symbolgen; %macro PrintIt(DSN= ,Optn=); proc print data=&dsn &optn; run; %mend PrintIt; data Driver; infile datalines truncover firstobs=2; Input @1 VarMacName $char8. @10 VarDSN $char13. @25 VarOptn $char8. ; Datalines; 123456789012345678901234567890 PrintIt sashelp.class (Obs=10) PrintIt sashelp.Shoes (Obs=5) PrintIt sashelp.air ; run; data _null_; set Driver; call execute('%'||VarMacName||'(dsn='||Vardsn||',Optn='||VarOptn||');'); run; 198 1 R252 3 call label( 1 332 1 1 Call label( varName , charVariableForLabel ) ; 326 1 s252 3 call missing( 1 332 1 1 Call missing( commaDelimitedVariableList | of sasVariableListSpecification ) ; 34 1 n252 3 call module( 1 332 1 1 Call module( moduleName< , argument1< , argument2<...> ) ; 192 1 p252 3 call modulei( 1 332 1 1 Call moduleI( moduleName< , argument1< , argument2<...> ) ; 193 1 ª252 3 call prxchange( 1 332 1 1 Call prxChange( regularExpressionId , times , oldString< , new-string< , resultLength< , truncationValue< , numberOfChanges>>>> ) ; 11 1 =252 3 call prxdebug( 1 332 1 1 Call prxDebug(on|off) ; 12 1 H252 3 call prxfree( 1 332 1 1 Call prxFree(regularExpressionId) ; 18 1 v252 3 call prxnext( 1 332 1 1 Call prxNext( regularExpressionId , start , stop , source , position , length ) ; 19 1 m252 3 call prxposn( 1 332 1 1 Call prxPosn( regularExpressionId , captureBuffer , start< , length> ) ; 21 1 m252 3 call prxsubstr( 1 332 1 1 Call prxSubstr( regularExpressionId , source , position< , length> ) ; 27 1 ‚252 3 call ranperk( 1 332 1 1 Call ranPerK( seed , K , numericVariable1< , numericVariable2< , numericVariable3<...>>> ) ; 271 1 ~252 3 call ranperm( 1 332 1 1 Call ranPerm( seed , numericVariable1< , numericVariable2< , numericVariable3<...>>> ) ; 272 1 S252 3 call ranpoi( 1 332 1 1 Call ranPoi( seed , mean , numericVariable ) ; 273 1 [252 3 call rantbl( 1 332 1 1 Call ranTbl( seed , variableList , numericVariable ) ; 274 1 Y252 3 call rantri( 1 332 1 1 Call ranTri( seed , modalValue , numericVariable ) ; 275 1 L252 3 call ranuni( 1 332 1 1 Call ranUni( seed , numericVariable ) ; 276 1 n252 3 call rxchange( 1 332 1 1 Call rxChange( regularExpressionId , times , oldString< , newString> ) ; 29 1 F252 3 call rxfree( 1 332 1 1 Call rxFree(regularExpressionId) ; 35 1 u252 3 call rxsubstr( 1 332 1 1 Call rxSubstr( regularExpressionId , string , position< , length< , score>> ) ; 36 1 w252 3 call scan( 1 332 1 1 Call scan( string , wordNumber , positionOfWord , lengthOfWord< , wordDelimiters> ) ; 59 1 y252 3 call scanq( 1 332 1 1 Call scanQ( string , wordNumber , positionOfWord , lengthOfWord< , wordDelimiters> ) ; 57 1 7252 3 call set( 1 332 1 1 Call set(datasetId) ; 327 1 b252 3 call softmax( 1 332 1 1 Call softMax( numericVariable1< , numericVariable2<...>> ) ; 211 1 |252 3 call stdize( 1 332 1 1 Call stdize( > , numericVariable1< , numericVariable2<...>> ) ; 212 1 252 3 call symput( 1 332 1 14 /*Call Symput, symget, resolve */ data _null_; length CVarInPDV1 $6; call symput ("DogName","spot"); call Symput ("DogAge",5); put "Before Symget " CVarInPDV1= ; CVarInPDV1=symget("DogName"); put "After Symget " CVarInPDV1= ; NVarInPDV1=symget("DogAge"); put "After Symget " NVarInPDV1= ; /*I do not know anyone who uses resolve*/ /*see The RESOLVE Function - What Is It Good For?*/ /*http://www.nesug.org/proceedings/nesug98/code/p088.pdf*/ run; 199 1 a252 3 call symputx( 1 332 1 1 Call symPutX( 'macroVariableName' , sasCode< , 'g|l|f'> ) ; 200 1 Q252 3 call vname( 1 332 1 1 Call vName( varName , charVAriableForName ) ; 328 1 T252 3 call vnext( 1 332 1 1 Call vNext( varName<, varType< , varLength>> ) ; 329 1 252 3 cat( 1 332 1 68 /***********************************************************************/ /*CAT Function CATQ Function CATS Function CATT Function CATX Function The results of the CAT, CATS, CATT, and CATX functions are usually equivalent to those that are produced by certain combinations of the concatenation operator (||) and the TRIM and LEFT functions. However, using the CAT, CATS, CATT, and CATX functions IS FASTER than using TRIM and LEFT, and you can use them with the OF syntax for variable lists in calling environments that support variable lists. CAT(OF X1-X4) is the same as X1||X2||X3||X4 CATS(OF X1-X4) is the same as TRIM(LEFT(X1))||TRIM(LEFT(X2))||TRIM(LEFT(X3))||TRIM(LEFT(X4)) CATT(OF X1-X4) is the same as TRIM(X1)||TRIM(X2)||TRIM(X3)||TRIM(X4) CATX(SP, OF X1-X4) is the same as TRIM(LEFT(X1))||SP||TRIM(LEFT(X2))||SP||TRIM(LEFT(X3))||SP||TRIM(LEFT(X4)) CatQ Concatenates character or numeric values by using a delimiter to separate items and by adding quotation marks to strings that contain the delimiter.*/ data _null_; result1=CATQ(' ', 'noblanks', 'one blank', 12345, ' lots of blanks '); result2=CATQ('CS', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result3=CATQ('BCQT', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result4=CATQ('ADT', '#=#', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result5=CATQ('N', 'ABC_123 ', '123 ', 'ABC 123'); put (result1-result5) (=/); run; data _null_; separator='%%$%%'; x='The Olympic '; y=' Arts Festival '; z=' includes works by '; a='Dale Chihuly.'; ResultCat=cat(x,y,z,a); ResultCatS=catS(x,y,z,a); ResultCatT=catT(x,y,z,a); resultCatX=catX(separator,x,y,z,a); resultCatXCool=catx(" ",x,y,z,a); put "concatinates: " ResultCat= $char.; put "Strips and then concatinates: " ResultCatS= $char.; put "Trims and then concatinates: " ResultCaTT= $char.; put "Strips, adds separator & concatinates: " ResultCatX= $char.; put "Useful -> " resultCatXCool= ; run; 7 1 252 3 catq( 1 332 1 68 /***********************************************************************/ /*CAT Function CATQ Function CATS Function CATT Function CATX Function The results of the CAT, CATS, CATT, and CATX functions are usually equivalent to those that are produced by certain combinations of the concatenation operator (||) and the TRIM and LEFT functions. However, using the CAT, CATS, CATT, and CATX functions IS FASTER than using TRIM and LEFT, and you can use them with the OF syntax for variable lists in calling environments that support variable lists. CAT(OF X1-X4) is the same as X1||X2||X3||X4 CATS(OF X1-X4) is the same as TRIM(LEFT(X1))||TRIM(LEFT(X2))||TRIM(LEFT(X3))||TRIM(LEFT(X4)) CATT(OF X1-X4) is the same as TRIM(X1)||TRIM(X2)||TRIM(X3)||TRIM(X4) CATX(SP, OF X1-X4) is the same as TRIM(LEFT(X1))||SP||TRIM(LEFT(X2))||SP||TRIM(LEFT(X3))||SP||TRIM(LEFT(X4)) CatQ Concatenates character or numeric values by using a delimiter to separate items and by adding quotation marks to strings that contain the delimiter.*/ data _null_; result1=CATQ(' ', 'noblanks', 'one blank', 12345, ' lots of blanks '); result2=CATQ('CS', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result3=CATQ('BCQT', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result4=CATQ('ADT', '#=#', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result5=CATQ('N', 'ABC_123 ', '123 ', 'ABC 123'); put (result1-result5) (=/); run; data _null_; separator='%%$%%'; x='The Olympic '; y=' Arts Festival '; z=' includes works by '; a='Dale Chihuly.'; ResultCat=cat(x,y,z,a); ResultCatS=catS(x,y,z,a); ResultCatT=catT(x,y,z,a); resultCatX=catX(separator,x,y,z,a); resultCatXCool=catx(" ",x,y,z,a); put "concatinates: " ResultCat= $char.; put "Strips and then concatinates: " ResultCatS= $char.; put "Trims and then concatinates: " ResultCaTT= $char.; put "Strips, adds separator & concatinates: " ResultCatX= $char.; put "Useful -> " resultCatXCool= ; run; 290 1 252 3 cats( 1 332 1 68 /***********************************************************************/ /*CAT Function CATQ Function CATS Function CATT Function CATX Function The results of the CAT, CATS, CATT, and CATX functions are usually equivalent to those that are produced by certain combinations of the concatenation operator (||) and the TRIM and LEFT functions. However, using the CAT, CATS, CATT, and CATX functions IS FASTER than using TRIM and LEFT, and you can use them with the OF syntax for variable lists in calling environments that support variable lists. CAT(OF X1-X4) is the same as X1||X2||X3||X4 CATS(OF X1-X4) is the same as TRIM(LEFT(X1))||TRIM(LEFT(X2))||TRIM(LEFT(X3))||TRIM(LEFT(X4)) CATT(OF X1-X4) is the same as TRIM(X1)||TRIM(X2)||TRIM(X3)||TRIM(X4) CATX(SP, OF X1-X4) is the same as TRIM(LEFT(X1))||SP||TRIM(LEFT(X2))||SP||TRIM(LEFT(X3))||SP||TRIM(LEFT(X4)) CatQ Concatenates character or numeric values by using a delimiter to separate items and by adding quotation marks to strings that contain the delimiter.*/ data _null_; result1=CATQ(' ', 'noblanks', 'one blank', 12345, ' lots of blanks '); result2=CATQ('CS', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result3=CATQ('BCQT', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result4=CATQ('ADT', '#=#', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result5=CATQ('N', 'ABC_123 ', '123 ', 'ABC 123'); put (result1-result5) (=/); run; data _null_; separator='%%$%%'; x='The Olympic '; y=' Arts Festival '; z=' includes works by '; a='Dale Chihuly.'; ResultCat=cat(x,y,z,a); ResultCatS=catS(x,y,z,a); ResultCatT=catT(x,y,z,a); resultCatX=catX(separator,x,y,z,a); resultCatXCool=catx(" ",x,y,z,a); put "concatinates: " ResultCat= $char.; put "Strips and then concatinates: " ResultCatS= $char.; put "Trims and then concatinates: " ResultCaTT= $char.; put "Strips, adds separator & concatinates: " ResultCatX= $char.; put "Useful -> " resultCatXCool= ; run; 8 1 252 3 catt( 1 332 1 68 /***********************************************************************/ /*CAT Function CATQ Function CATS Function CATT Function CATX Function The results of the CAT, CATS, CATT, and CATX functions are usually equivalent to those that are produced by certain combinations of the concatenation operator (||) and the TRIM and LEFT functions. However, using the CAT, CATS, CATT, and CATX functions IS FASTER than using TRIM and LEFT, and you can use them with the OF syntax for variable lists in calling environments that support variable lists. CAT(OF X1-X4) is the same as X1||X2||X3||X4 CATS(OF X1-X4) is the same as TRIM(LEFT(X1))||TRIM(LEFT(X2))||TRIM(LEFT(X3))||TRIM(LEFT(X4)) CATT(OF X1-X4) is the same as TRIM(X1)||TRIM(X2)||TRIM(X3)||TRIM(X4) CATX(SP, OF X1-X4) is the same as TRIM(LEFT(X1))||SP||TRIM(LEFT(X2))||SP||TRIM(LEFT(X3))||SP||TRIM(LEFT(X4)) CatQ Concatenates character or numeric values by using a delimiter to separate items and by adding quotation marks to strings that contain the delimiter.*/ data _null_; result1=CATQ(' ', 'noblanks', 'one blank', 12345, ' lots of blanks '); result2=CATQ('CS', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result3=CATQ('BCQT', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result4=CATQ('ADT', '#=#', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result5=CATQ('N', 'ABC_123 ', '123 ', 'ABC 123'); put (result1-result5) (=/); run; data _null_; separator='%%$%%'; x='The Olympic '; y=' Arts Festival '; z=' includes works by '; a='Dale Chihuly.'; ResultCat=cat(x,y,z,a); ResultCatS=catS(x,y,z,a); ResultCatT=catT(x,y,z,a); resultCatX=catX(separator,x,y,z,a); resultCatXCool=catx(" ",x,y,z,a); put "concatinates: " ResultCat= $char.; put "Strips and then concatinates: " ResultCatS= $char.; put "Trims and then concatinates: " ResultCaTT= $char.; put "Strips, adds separator & concatinates: " ResultCatX= $char.; put "Useful -> " resultCatXCool= ; run; 60 1 252 3 catx( 1 332 1 68 /***********************************************************************/ /*CAT Function CATQ Function CATS Function CATT Function CATX Function The results of the CAT, CATS, CATT, and CATX functions are usually equivalent to those that are produced by certain combinations of the concatenation operator (||) and the TRIM and LEFT functions. However, using the CAT, CATS, CATT, and CATX functions IS FASTER than using TRIM and LEFT, and you can use them with the OF syntax for variable lists in calling environments that support variable lists. CAT(OF X1-X4) is the same as X1||X2||X3||X4 CATS(OF X1-X4) is the same as TRIM(LEFT(X1))||TRIM(LEFT(X2))||TRIM(LEFT(X3))||TRIM(LEFT(X4)) CATT(OF X1-X4) is the same as TRIM(X1)||TRIM(X2)||TRIM(X3)||TRIM(X4) CATX(SP, OF X1-X4) is the same as TRIM(LEFT(X1))||SP||TRIM(LEFT(X2))||SP||TRIM(LEFT(X3))||SP||TRIM(LEFT(X4)) CatQ Concatenates character or numeric values by using a delimiter to separate items and by adding quotation marks to strings that contain the delimiter.*/ data _null_; result1=CATQ(' ', 'noblanks', 'one blank', 12345, ' lots of blanks '); result2=CATQ('CS', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result3=CATQ('BCQT', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result4=CATQ('ADT', '#=#', 'Period (.) ', 'Ampersand (&) ', 'Comma (,) ', 'Double quotation marks (") ', ' Leading Blanks'); result5=CATQ('N', 'ABC_123 ', '123 ', 'ABC 123'); put (result1-result5) (=/); run; data _null_; separator='%%$%%'; x='The Olympic '; y=' Arts Festival '; z=' includes works by '; a='Dale Chihuly.'; ResultCat=cat(x,y,z,a); ResultCatS=catS(x,y,z,a); ResultCatT=catT(x,y,z,a); resultCatX=catX(separator,x,y,z,a); resultCatXCool=catx(" ",x,y,z,a); put "concatinates: " ResultCat= $char.; put "Strips and then concatinates: " ResultCatS= $char.; put "Trims and then concatinates: " ResultCaTT= $char.; put "Strips, adds separator & concatinates: " ResultCatX= $char.; put "Useful -> " resultCatXCool= ; run; 22 1 ;252 3 cdf( 1 332 1 1 cdf( 'Bernoulli|beta|binomial|Cauchy|chiSquare|exponential|F|gamma|geometric|hyperGeometric|LaPlace|logistic|logNormal|negBinomial|normal|Gauss|normalMix|Pareto|Poissont|uniform|Wald|iGauss|Weibull' , quantile< , shapeLocationOrScaleParameter1< , shapeLocationOrScaleParameter2<...>>> ) 241 1 !252 3 ceil( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 315 1 252 3 ceilz( 1 332 1 2 ceilZ(number) Returns the smallest integer that is greater than or equal to the argument, using zero fuzzing. 316 1 Æ252 3 CharFormatLookup 1 332 1 55 *********************************** ** this is the code for a CHARACTER version of figure 1- not in sleds; *character table lookup SEE APPENDIX; data CH_small; infile datalines missover; Input @1 Char_zip $char5.; datalines; 23116 12554 08443 ; run; data CH_large; infile datalines; input @1 pat_id @7 state $ @10 zip_cd $char5.; datalines; 12554 PA 19003 11121 NJ 08554 44444 MD 21332 99999 NJ 08443 23116 MA 62231 99332 PA 19104 33333 DE 23116 22222 WA 00000 33333 WY 99999 ; run; *make zipcodes from small file into a format; data NwCHFmt(keep= fmtname start label type hlo); retain FMTNAME "ZIP_CH" TYPE "C" LABEL "YES"; set CH_small (rename=(Char_ZIP=start )) end=last; output; if last=1 then do; Hlo="O"; label="Other" ; start= .; output; end; run; proc format cntlin= NwCHFmt; run; /* see the internal file proc format cntlout= CH_look; select $ZIP_CH; run; proc print data=CH_look; title "Character format - note that the data is now in ascending order"; run; */ DATA IN_SML_CH; SET CH_large; If PUT(ZIP_cd,$ZIP_CH.)="YES";/*Uncomment this line 2 select only obs in small*/ RUN; proc print data=IN_Sml_CH; run; 294 1 252 3 choosec( 1 332 1 43 /*ChooseC ChooseN Returns a character value that represents the results of choosing from a list of arguments. CHOOSEN Function Returns a numeric value that represents the results of choosing from a list of arguments. */ data _null_; /*Returns a character value that represents the results of choosing from a list of arguments. CHOOSEC (index-expression, selection-1 <,...selection-n>) index-expression specifies a numeric constant, variable, or expression. selection specifies a character constant, variable, or expression. The value of this argument is returned by the CHOOSEC function. */ Fruit =chooseC(1,'apple','orange','pear','fig'); Color =chooseC(3,'red','blue','green','yellow'); Planet=chooseC(2,'Mars','Mercury','Uranus'); /*And counitng from right to left*/ Sport =chooseC(-3,'soccer','baseball','gymnastics','skiing'); put Fruit= Color= Planet= ; /*Fruit=apple Color=green Planet=Mercury Sport=baseball */ put "We can count from Right to left" Sport=; /*CHOOSEN (index-expression, selection-1 <,...selection-n>) index-expression specifies a numeric constant, variable, or expression. selection specifies a numeric constant, variable, or expression. The value of this argument is returned by the CHOOSEN function. The CHOOSEN function uses the value of index-expression to select from the arguments that follow. For example, if index-expression is 3, CHOOSEN returns the value of selection-3. If the first argument is negative, the function counts backwards from the list of arguments, and returns that value. */ ItemNumber=choosen(5,100,50,3784,498,679); Rank=choosen(-2,1,2,3,4,5); Score=choosen(3,193,627,33,290,5); Value=choosen(-5,-37,82985,-991,3,1014,-325,3,54,-618); put ItemNumber= Rank= Score= Value=; /*ItemNumber=679 Rank=4 Score=33 Value=1014*/ run; 25 1 252 3 choosen( 1 332 1 43 /*ChooseC ChooseN Returns a character value that represents the results of choosing from a list of arguments. CHOOSEN Function Returns a numeric value that represents the results of choosing from a list of arguments. */ data _null_; /*Returns a character value that represents the results of choosing from a list of arguments. CHOOSEC (index-expression, selection-1 <,...selection-n>) index-expression specifies a numeric constant, variable, or expression. selection specifies a character constant, variable, or expression. The value of this argument is returned by the CHOOSEC function. */ Fruit =chooseC(1,'apple','orange','pear','fig'); Color =chooseC(3,'red','blue','green','yellow'); Planet=chooseC(2,'Mars','Mercury','Uranus'); /*And counitng from right to left*/ Sport =chooseC(-3,'soccer','baseball','gymnastics','skiing'); put Fruit= Color= Planet= ; /*Fruit=apple Color=green Planet=Mercury Sport=baseball */ put "We can count from Right to left" Sport=; /*CHOOSEN (index-expression, selection-1 <,...selection-n>) index-expression specifies a numeric constant, variable, or expression. selection specifies a numeric constant, variable, or expression. The value of this argument is returned by the CHOOSEN function. The CHOOSEN function uses the value of index-expression to select from the arguments that follow. For example, if index-expression is 3, CHOOSEN returns the value of selection-3. If the first argument is negative, the function counts backwards from the list of arguments, and returns that value. */ ItemNumber=choosen(5,100,50,3784,498,679); Rank=choosen(-2,1,2,3,4,5); Score=choosen(3,193,627,33,290,5); Value=choosen(-5,-37,82985,-991,3,1014,-325,3,54,-618); put ItemNumber= Rank= Score= Value=; /*ItemNumber=679 Rank=4 Score=33 Value=1014*/ run; 24 1 [252 3 cinv( 1 332 1 1 cInv( numericProbability , degreesOfFreedom , nonCentrality ) 260 1 L252 3 cnonct( 1 332 1 1 cNonCt( x , degreesOfFreedom , probability ) 214 1 ³252 3 coalesce( 1 332 1 24 /*Coalesce */ /*coalesceC( string1< , string2<...>> )*/ /*Returns the first non-missing value from a list of character arguments. */ data _null_; x = COALESCE(42, .); Put "x = COALESCE(42, .); " x= ; y = COALESCE(.A, .B, .C); Put "y = COALESCE(.A, .B, .C); " y= ; z = COALESCE(., 7, ., ., 42); Put "z = COALESCE(., 7, ., ., 42); " z= ; run; data _null_; ItemNumber=choosen(5,100,50,3784,498,679); Rank=choosen(-2,1,2,3,4,5); Score=choosen(3,193,627,33,290,5); Value=choosen(-5,-37,82985,-991,3,1014,-325,3,54,-618); put ItemNumber= Rank= Score= Value=; run; /*ItemNumber=679 Rank=4 Score=33 Value=1014*/ 215 1 G252 3 coalescec( 1 332 1 1 coalesceC( string1< , string2<...>> ) 61 1 o252 3 collate( 1 332 1 1 collate( startPosition< , endPosition>) | collate( startPosition< , , length> ) 28 1 A252 3 comb( 1 332 1 1 comb( sizeOfUniverse , sampleSize ) 216 1 š252 3 compare( 1 332 1 9 /*compare Returns the position of the leftmost character by which two strings differ, or returns 0 if there is no difference.*/ data test2; pad1=compare('abc','abc '); pad2=compare('abc','abcdef '); truncate1=compare('abc','abcdef',':'); truncate2=compare('abcdef','abc',':'); blank=compare('','abc', ':'); run; 30 1 .252 3 compbl( 1 332 1 11 compBl(string) Removes multiple blanks from a character string. data _null_; string='Hey Diddle Diddle'; string2=compbl(string); put string= String2=; address='125 E Main St'; address2=compbl(ADDRESS); put address= ADDRESS2=; RUN; 62 1 Ï 252 3 compged( 1 332 1 106 /*Compged Complev soundex Speedis*/ /*CompGed Returns the generalized edit distance between two strings. */ /*Soundex Encodes a string to facilitate searching. */ /*Speedis Determines the likelihood of two words matching,*/ data test; infile datalines missover; input String1 $char8. +1 String2 $char8. +1 Operation $40.; GED=CompGed(string1, string2); datalines; baboon baboon match baXboon baboon insert baoon baboon delete baXoon baboon replace baboonX baboon append baboo baboon truncate babboon baboon double babon baboon single baobon baboon swap bab oon baboon blank bab,oon baboon punctuation bXaoon baboon insert+delete bXaYoon baboon insert+replace bXoon baboon delete+replace Xbaboon baboon finsert aboon baboon trick question: swap+delete Xaboon baboon freplace axoon baboon fdelete+replace axoo baboon fdelete+replace+truncate axon baboon fdelete+replace+single baby baboon replace+truncate*2 balloon baboon replace+insert ; proc print data=test label; label GED='Generalized Edit Distance'; var String1 String2 GED Operation; run; /*COMPLEV Function Returns the Levenshtein edit distance between two strings. */ options pageno=1 nodate ls=80 ps=60; data test; infile datalines missover; input string1 $char8. string2 $char8. modifiers $char8.; result=CompLev(string1, string2, modifiers); datalines; 1234567812345678 abc abxc ac abc aXc abc aXbZc abc aXYZc abc WaXbYcZ abc XYZ abcdef aBc abc aBc AbC i abc abc abc abc l AxC 'abc'n AxC 'abc'n n ; proc print data=test; run; /*The SOUNDEX function encodes a character string according to an algorithm that was originally developed */ /*by Margaret K. Odell and Robert C. Russel (US Patents 1261167 (1918) and 1435663 (1922)). */ /*The algorithm is described in Knuth, The Art of Computer Programming, Volume 3. (See References.) */ /*Note that the SOUNDEX algorithm is English-biased and is less useful for languages other than English.*/ data _Null_; x=soundex('Paul'); put x; word='amnesty'; x=soundex(word); put x; ; run; /*Speedis Determines the likelihood of two words matching, expressed as the asymmetric spelling distance between the two words.*/ data words; input Operation $ Query $ Keyword $; Distance = spedis(query,keyword); Cost = distance * length(query); datalines; match fuzzy fuzzy singlet fuzy fuzzy doublet fuuzzy fuzzy swap fzuzy fuzzy truncate fuzz fuzzy append fuzzys fuzzy delete fzzy fuzzy insert fluzzy fuzzy replace fizzy fuzzy firstdel uzzy fuzzy firstins pfuzzy fuzzy firstrep wuzzy fuzzy several floozy fuzzy ; proc print data = words; run; 31 1 Z252 3 compled( 1 332 1 1 compLED( string1 , string2< , cutoff>< , '<:>'> ) 32 1 X252 3 compress( 1 332 1 20 compress( source<, charsToRemove><, '

'> ) Returns a character string with specified characters removed from the original string. Syntax COMPRESS(<, chars><, modifiers>) source specifies a character constant, variable, or expression from which specified characters will be removed. chars specifies a character constant, variable, or expression that initializes a list of characters. By default, the characters in this list are removed from the source argument. If you specify the K modifier in the third argument, then only the characters in this list are kept in the result. Number of Arguments Result only the first argument, source The argument has all blanks removed. If the argument is completely blank, then the result is a string with a length of zero. If you assign the result to a character variable with a fixed length, then the value of that variable will be padded with blanks to fill its defined length. The first two arguments, source and chars All characters that appear in the second argument are removed from the result. Three arguments, source, chars, and modifier(s) The K modifier (specified in the third argument) determines whether the characters in the second argument are kept or removed from the result. 37 1  252 3 Compressed_Index_Basic 1 332 1 103 /**************************************************************** Section: 0- Create data sets *****************************************************************/ Options nocenter; Proc SQL; create table WantInfo ( SID Char(4) , Sex Char(1) ); insert into WantInfo values("0001","F") values("3999","F") values("2222","M") values("3134","F") /*values("6090","M")*/ values("7777","M"); proc print data=Wantinfo; title "Wantinfo"; run; Proc SQL; Create table SWantInfo as select * from WantINfo Order by SID; proc print data=swantinfo; title "swantinfo"; run; proc SQL; Create table BigLookIn (SID char(4) , ARM Char(1) ); insert into BigLookIn values("8811","A") values("9033","B") values("9099","A") values("2999","B") values("3453","A") values("3999","B") values("4444","A") values("4766","A") values("5020","B") values("0001","A") values("0099","B") values("1005","B") values("1087","B") values("2111","A") values("5111","A") values("6090","A") values("6888","B") values("7666","A") values("7777","B") values("8188","A"); /*Proc Print data=BigLookIn;*/ /*run;*/ Create table SBigLookIn as select * from BigLookIn order by SID; Create table SDupIn (SID char(4) , test Char(1) ); insert into SDupIn values("0001","N") /*match*/ values("2222","A") /*match*/ values("2222","N") /*match*/ values("2222","A") /*match*/ values("2999","N") values("3453","A") values("3453","N") values("3999","A"); /*match*/ quit; proc print data=SBigLookIn; title "SBigLookIn"; run; /**************************************************************** Section:_7A_ First use of compressed index Mark Keintz *****************************************************************/ Data CmprIndx; /*Create the comprtessed index on the large file*/ RETAIN SID StartAt EndAt; SET SDupIn; by SID; IF FIRST.sid=1 THEN StartAt=_N_; if last.SID=1 then DO; EndAt=_N_; Output; END; run; proc SQL; drop index SID from CmprIndx; run; data Example7A/DEBUG; Merge SWantInfo(in=SWant) CmprIndx(In=Cmp); by SID; if SWant * Cmp; /*SET CmprsdIndx key=SID / unique; */ do Pointer=StartAt to EndAt; set SDupIn point=Pointer; output; end; run; Proc Print data=Example7A; RUN; 384 1 p 252 3 CompressedIndex_IndexedCompressedINdex 1 332 1 111 /**************************************************************** Section: 0- Create data sets *****************************************************************/ Options nocenter; Proc SQL; create table WantInfo ( SID Char(4) , Sex Char(1) ); insert into WantInfo values("0001","F") values("3999","F") values("2222","M") values("3134","F") /*values("6090","M")*/ values("7777","M"); proc print data=Wantinfo; title "Wantinfo"; run; Proc SQL; Create table SWantInfo as select * from WantINfo Order by SID; proc print data=swantinfo; title "swantinfo"; run; proc SQL; Create table BigLookIn (SID char(4) , ARM Char(1) ); insert into BigLookIn values("8811","A") values("9033","B") values("9099","A") values("2999","B") values("3453","A") values("3999","B") values("4444","A") values("4766","A") values("5020","B") values("0001","A") values("0099","B") values("1005","B") values("1087","B") values("2111","A") values("5111","A") values("6090","A") values("6888","B") values("7666","A") values("7777","B") values("8188","A"); /*Proc Print data=BigLookIn;*/ /*run;*/ Create table SBigLookIn as select * from BigLookIn order by SID; Create table SDupIn (SID char(4) , test Char(1) ); insert into SDupIn values("0001","N") /*match*/ values("2222","A") /*match*/ values("2222","N") /*match*/ values("2222","A") /*match*/ values("2999","N") values("3453","A") values("3453","N") values("3999","A"); /*match*/ quit; proc print data=SBigLookIn; title "SBigLookIn"; run; /**************************************************************** Section:_7B_ Condensed index V1 - Mark Kentz - WORDS UPenn s *****************************************************************/ Options nocenter; /*Build index on all of big file*/ Data CmprsdIndx(index=(SID)); /*create an indexed "compressed index" file*/ RETAIN SID StartAt EndAt; SET SDupIn; by SID; IF FIRST.sid=1 THEN StartAt=_N_; if last.SID=1 then DO; EndAt=_N_; Output; END; run; /*We do not want to read ALL of the compressed index, only rows in WantINfo*/ Proc SQL; select quote(SID) into :WantThese separated by "," from WantInfo; /*Options are good*/ quit; %put _user_; options mlogic mprint symbolgen fullstimer msglevel=i; data Example7B /DEBUG; SET CmprsdIndx(where=(SID in (&WantThese))); /*let SAS decide if it should use the index*/ /*read the file that tells us what obs we want - likely to be small*/ do Pointer=StartAt to EndAt; set SDupIn point=Pointer; output; end; run; Proc Print data=Example7B; run; 385 1 Â252 3 CompressedIndex_ReadAheadManagedBy SAS 1 332 1 53 /*Compressed Index_Hierarchical With Read Ahead managed by SAS*/ /*Courtesy of Mark Keintx www.nesug.org/Proceedings/nesug08/bb/bb10.pdf */ /*If SAS knows it is reading a seriess of obs in Sequence*/ /*,it will guess where you want the next read to happen*/ /*and pre-position the hard drive head - reading ahead of your request for data*/ /*this can make for a very fast read*/ proc sort data=sashelp.class out=SortedClass; by sex age; /*data set must be sorted*/ run; /*Create Hierarchcal Compressed Index ONCE - in the middle of the night?*/ data HCompInd(keep= sex age ReadFrom ReadTo); retain ReadFrom readTo; set SortedClass; by sex age; if first.age then ReadFrom=_n_; if last.age then do; ReadTo=_n_; output; end; run; Proc print data=HCompINd; run; /*Use the compressed index to generate macro variable*/ /*This is the key to having SAS manage the read ahead*/ data _null_; retain RangeList ; length RangeList $ 32700; /*This will hold the syntax for the read and be loaded into a macro*/ set HCompInd end=EOF; ** Read the parts of the Hierarchcal Compressed Index file that are of interest**; where Age=12 or Sex="M"; Thisrange= catx(" ",cats("(firstobs=",ReadFrom),cats("obs=",ReadTo,")")); RangeList=catx(" ",RangeList,"SortedClass",Thisrange); /*concatinate the */ if EOF=1 then do; call symput("ThisRange",trim(ThisRange)); /*just for checking*/ call symput("RangeList",trim(RangeList)); end; run; %put &ThisRange; %put &RangeList; data SubsetOfSortedClass; set &RangeList open=defer; run; proc print data=subsetOfSortedClass; run; 386 1 Â252 3 CompressedIndexWReadAhead 1 332 1 26 /***CompressedINdexWReadAdhead***/ /*Courtesy of Mark Keintz*/ /*Use a data step to put out set statements into macro variables*/ data _null_; retain RangeList ; length RangeList $ 32700; set SexAgeComprIndxOnClass end=EOF; where age=12 or Sex="M"; /*select rows from compressed index*/ range=catx(" ",cats('(Firstobs=',StartHere),cats('obs=',Endhere,')')); RangeList=catx(' ',RangeList,'ClassBySexNAge',range); if EOF then call symput('SetList', trim(Rangelist)); run; %put &SetList; data ReadAheadDataPull; set &setlist open=Defer; /*SAS only opens one infle buffer*/ run; proc print data=ReadAheadDataPull; run; 295 1 ´252 3 CompressedIndexwWPoint 1 332 1 27 /*Compressed Index W Point**/ /*Courtesy of Make Keintz*/ /*build the compressed Index on Age;*/ data ComprIndxonClass; retain StartHere; set ClassByAge(keep=age); by age; /*this creates first.name and last.name*/ if first.age=1 then StartHere=_n_; if last.age=1 then do; EndHere =_n_; output; end; run; proc print data=ComprIndxonClass; run; data ObsPulledUsingPointer; /*bring in first and last obs for this age*/ set ComprIndxonClass(where=(age=13)); do p=StartHere to EndHere; set classByAge point=p;/*Use point= control to read obs*/ output; end; run; proc print data=ObsPulledUsingPointer; run; 291 1 Ê252 3 constant( 1 332 1 1 constant( 'e'|'Euler'|'pi'|'exactInt'< , nBytes>|'big'|'logBig'< , base>|'sqRtBig'|'small'|'logSmall'< , base>|'sqRtSmall'|'macEps'|'logMacEps'< , base >|'sqRtMacEps' ) 217 1 (252 3 cos( 1 332 1 1 cos(number) 312 1 V252 3 count( 1 332 1 142 /*FIND FINDC FINDW Count CountW CountC (These might eb better than Verify , index , indexc and indexw) The find Function returns the character position of a specific substring of characters within a character string. The FINDC function returns the character position of the first encountered character from a group of individual characters The FindW Funcion returns the character position of a word in a string, The FIND group of functions and the INDEX group of functions both search for substrings of characters in a character string. However, the INDEX functions do not have the modifiers nor the startpos arguments. The FINDC function searches for individual characters in a character string, whereas the FIND function searches for substrings of characters in a character string. The FINDC function and the INDEXC function both search for individual characters in a character string. However, the INDEXC function does not have the modifier nor the startpos arguments. The FINDC function searches for individual characters in a character string, whereas the VERIFY function searches for the first character that is unique to an expression. The VERIFY function does not have the modifier nor the startpos arguments. Count Counts the number of times that a specified substring appears within a character string. CountW Counts the number of words in a character string. CountC Counts the number of characters in a string that appear or do not appear in a list of characters. */ data _null_; /*Find FIND function searches for substrings of characters in a character string*/ WhereIsShe=find('She sells seashells? Yes, she does.','she '); put WhereIsShe; variable1='She sells seashells? Yes, she does.'; variable2='she '; variable3='i'; WhereIsShe_i=find(variable1,variable2,variable3); put WhereIsShe_i; expression1='She sells seashells? '||'Yes, she does.'; expression2=kscan('he or she',3)||' '; expression3=trim('t '); WhereIsShe_t=find(expression1,expression2,expression3); put WhereIsShe_t; xyz='She sells seashells? Yes, she does.'; startposvar=22; WhereIsShe_22=find(xyz,'she',startposvar); /*FindW Returns the character position of a word in a string, or returns the number of the word in a string. */ WhereIsShe_W1=findw('She sells sea shells? Yes, she does.','she'); put WhereIsShe_W1=; /*Only the second occurrence is found by FINDW because the search begins in position 25. The chars argument specifies a space as the delimiter. */ result = findw('At least 2.5 meters of rain falls in a rain forest.', 'rain', ' ', 25); put result=; /*FindC Searches a string for any character in a list of characters. */ /*count*/ xyz='This is a thistle? Yes, this is a thistle.'; HowManyThis=count(xyz,'this'); put HowManyhis; xyz='This is a thistle? Yes, this is a thistle.'; HowManyIs=count(xyz,'is'); put HowManyIs; HowManyhis_i=count('This is a thistle? Yes, this is a thistle.' ,'this','i'); put HowManyhis_i; variable1='This is a thistle? Yes, this is a thistle.'; variable2='is '; variable3='i'; HowManyIs_i=count(variable1,variable2,variable3); put HowManyIs_i; expression1='This is a thistle? '||'Yes, this is a thistle.'; expression2=kscan('This is',2)||' '; expression3=compress('i '||' t'); howmanyis_it=count(expression1,expression2,expression3); put howmanyis_it; put WhereIsShe_22; xyz='She sells seashells? Yes, she does.'; startposexp=1-23; whereisShe_ineg22=find(xyz,'She','i',startposexp); put whereisShe_ineg22; Run; /*CountW*/ /*The following example shows how to use the COUNTW function with the M and P modifiers. */ options ls=64 pageno=1 nodate; data test; length default blanks mp 8; input string $char60.; default = CountW(string); blanks = CountW(string, ' '); mp = CountW(string, 'mp'); datalines; The quick brown fox jumps over the lazy dog. Leading blanks 2+2=4 /unix/path/names/use/slashes \Windows\Path\Names\Use\Backslashes ; run; proc print noobs data=test; run; /*CountC*/ /*The following example uses the COUNTC function with and without modifiers to count the number of characters in a string. */ data test; string = 'Baboons Eat Bananas '; a = countc(string, 'a'); b = countc(string,'b'); b_i = countc(string,'b','i'); abc_i = countc(string,'abc','i'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, (and include blanks). */ abc_iv = countc(string,'abc','iv'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, and trim trailing blanks. */ abc_ivt = countc(string,'abc','ivt'); run; options pageno=1 ls=80 nodate; proc print data=test noobs; run; 43 1 W252 3 countc( 1 332 1 142 /*FIND FINDC FINDW Count CountW CountC (These might eb better than Verify , index , indexc and indexw) The find Function returns the character position of a specific substring of characters within a character string. The FINDC function returns the character position of the first encountered character from a group of individual characters The FindW Funcion returns the character position of a word in a string, The FIND group of functions and the INDEX group of functions both search for substrings of characters in a character string. However, the INDEX functions do not have the modifiers nor the startpos arguments. The FINDC function searches for individual characters in a character string, whereas the FIND function searches for substrings of characters in a character string. The FINDC function and the INDEXC function both search for individual characters in a character string. However, the INDEXC function does not have the modifier nor the startpos arguments. The FINDC function searches for individual characters in a character string, whereas the VERIFY function searches for the first character that is unique to an expression. The VERIFY function does not have the modifier nor the startpos arguments. Count Counts the number of times that a specified substring appears within a character string. CountW Counts the number of words in a character string. CountC Counts the number of characters in a string that appear or do not appear in a list of characters. */ data _null_; /*Find FIND function searches for substrings of characters in a character string*/ WhereIsShe=find('She sells seashells? Yes, she does.','she '); put WhereIsShe; variable1='She sells seashells? Yes, she does.'; variable2='she '; variable3='i'; WhereIsShe_i=find(variable1,variable2,variable3); put WhereIsShe_i; expression1='She sells seashells? '||'Yes, she does.'; expression2=kscan('he or she',3)||' '; expression3=trim('t '); WhereIsShe_t=find(expression1,expression2,expression3); put WhereIsShe_t; xyz='She sells seashells? Yes, she does.'; startposvar=22; WhereIsShe_22=find(xyz,'she',startposvar); /*FindW Returns the character position of a word in a string, or returns the number of the word in a string. */ WhereIsShe_W1=findw('She sells sea shells? Yes, she does.','she'); put WhereIsShe_W1=; /*Only the second occurrence is found by FINDW because the search begins in position 25. The chars argument specifies a space as the delimiter. */ result = findw('At least 2.5 meters of rain falls in a rain forest.', 'rain', ' ', 25); put result=; /*FindC Searches a string for any character in a list of characters. */ /*count*/ xyz='This is a thistle? Yes, this is a thistle.'; HowManyThis=count(xyz,'this'); put HowManyhis; xyz='This is a thistle? Yes, this is a thistle.'; HowManyIs=count(xyz,'is'); put HowManyIs; HowManyhis_i=count('This is a thistle? Yes, this is a thistle.' ,'this','i'); put HowManyhis_i; variable1='This is a thistle? Yes, this is a thistle.'; variable2='is '; variable3='i'; HowManyIs_i=count(variable1,variable2,variable3); put HowManyIs_i; expression1='This is a thistle? '||'Yes, this is a thistle.'; expression2=kscan('This is',2)||' '; expression3=compress('i '||' t'); howmanyis_it=count(expression1,expression2,expression3); put howmanyis_it; put WhereIsShe_22; xyz='She sells seashells? Yes, she does.'; startposexp=1-23; whereisShe_ineg22=find(xyz,'She','i',startposexp); put whereisShe_ineg22; Run; /*CountW*/ /*The following example shows how to use the COUNTW function with the M and P modifiers. */ options ls=64 pageno=1 nodate; data test; length default blanks mp 8; input string $char60.; default = CountW(string); blanks = CountW(string, ' '); mp = CountW(string, 'mp'); datalines; The quick brown fox jumps over the lazy dog. Leading blanks 2+2=4 /unix/path/names/use/slashes \Windows\Path\Names\Use\Backslashes ; run; proc print noobs data=test; run; /*CountC*/ /*The following example uses the COUNTC function with and without modifiers to count the number of characters in a string. */ data test; string = 'Baboons Eat Bananas '; a = countc(string, 'a'); b = countc(string,'b'); b_i = countc(string,'b','i'); abc_i = countc(string,'abc','i'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, (and include blanks). */ abc_iv = countc(string,'abc','iv'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, and trim trailing blanks. */ abc_ivt = countc(string,'abc','ivt'); run; options pageno=1 ls=80 nodate; proc print data=test noobs; run; 44 1 Œ252 3 countw 1 332 1 89 count( string , substring< , ''> ) Counts the number of times that a specified substring appears within a character string. The COUNT function counts substrings of characters in a character string, whereas the COUNTC function counts individual characters in a character string. data _null_; xyz='This is a thistle? Yes, this is a thistle.'; howmanythis1=count(xyz,'this'); put xyz= "**->" howmanythis1=; howmanyis=count(xyz,'is'); put howmanyis=; howmanythis_i=count('This is a thistle? Yes, this is a thistle.','this','i'); put xyz= "**->" howmanythis_i=; variable1='This is a thistle? Yes, this is a thistle.'; variable2='is '; variable3='i'; howmanyis_i=count(variable1,variable2,variable3); put howmanyis_i=; expression1='This is a thistle? '||'Yes, this is a thistle.'; expression2=kscan('This is',2)||' '; expression3=compress('i '||' t'); howmanyis_it=count(expression1,expression2,expression3); put howmanyis_it=; run; countC( string , characters< , ''> ) data test; string = 'Baboons Eat Bananas '; a = countc(string, 'a'); b = countc(string,'b'); b_i = countc(string,'b','i'); abc_i = countc(string,'abc','i'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, (and include blanks). */ abc_iv = countc(string,'abc','iv'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, and trim trailing blanks. */ abc_ivt = countc(string,'abc','ivt'); run; COUNTW(<, chars><, modifiers>) Counts the number of words in a character string. modifier specifies a character constant, variable, or expression in which each non-blank character modifies the action of the COUNTW function. a or A adds alphabetic characters to the list of characters. b or B counts from right to left instead of from left to right. Right-to-left counting makes a difference only when you use the Q modifier and the string contains unbalanced quotation marks. c or C adds control characters to the list of characters. d or D adds digits to the list of characters. f or F adds an underscore and English letters (that is, the characters that can begin a SAS variable name using VALIDVARNAME=V7) to the list of characters. g or G adds graphic characters to the list of characters. h or H adds a horizontal tab to the list of characters. i or I ignores the case of the characters. k or K causes all characters that are not in the list of characters to be treated as delimiters. If K is not specified, then all characters that are in the list of characters are treated as delimiters. l or L adds lowercase letters to the list of characters. m or M specifies that multiple consecutive delimiters, and delimiters at the beginning or end of the string argument, refer to words that have a length of zero. If the M modifier is not specified, then multiple consecutive delimiters are treated as one delimiter, and delimiters at the beginning or end of the string argument are ignored. n or N adds digits, an underscore, and English letters (that is, the characters that can appear after the first character in a SAS variable name using VALIDVARNAME=V7) to the list of characters. o or O processes the chars and modifier arguments only once, rather than every time the COUNTW function is called. Using the O modifier in the DATA step (excluding WHERE clauses), or in the SQL procedure, can make COUNTW run faster when you call it in a loop where chars and modifier arguments do not change. p or P adds punctuation marks to the list of characters. q or Q ignores delimiters that are inside of substrings that are enclosed in quotation marks. If the value of string contains unmatched quotation marks, then scanning from left to right will produce different words than scanning from right to left. s or S adds space characters (blank, horizontal tab, vertical tab, carriage return, line feed, and form feed) to the list of characters. t or T trims trailing blanks from the string and chars arguments. u or U adds uppercase letters to the list of characters. w or W adds printable characters to the list of characters. x or X adds hexadecimal characters to the list of characters. data test; length default blanks mp 8; input string $char60.; default = countw(string); blanks = countw(string, ' '); mp = countw(string, 'mp'); datalines; The quick brown fox jumps over the lazy dog. Leading blanks 2+2=4 /unix/path/names/use/slashes \Windows\Path\Names\Use\Backslashes ; run; proc print noobs data=test; run; 206 1 <252 3 css( 1 332 1 1 css( number1< , number2<...>> ) 165 1 :252 3 cv( 1 332 1 1 cv( number1< , number2<...>> ) 166 1 ,252 3 dairy( 1 332 1 1 dAiry(number) 218 1 Y252 3 datdif( 1 332 1 1 datdif( datDif( startDate , endDate , '30/360'|'ACT/ACT' ) 49 1 %252 3 date( 1 332 1 123 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ /* Pretty dates all in a row Dianne Rhodes For my reports, which I usually run on Monday, I want to find last Friday’s date. The Week interval starts with Sunday, so Friday is week.6. ReportDate= intnx(‘week.6’, today(),0) The Start Date of the period will be the Saturday of the week before StartDate = intnx(‘week.7’, ReportDate, 0) http://www2.sas.com/proceedings/sugi30/055-30.pdf*/ /* INTNX('interval', start,from , increment, <,alignment>) INTCK('interval',from_date, to_date)*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ This_Day_Time=DateTime(); /*Reads system clock*/ A_date_part=DatePart(This_Day_Time); A_time_part=TimePart(This_Day_Time); ThisTime=time(); put TodayDate= TodayToday= ; put This_Day_Time= A_date_part= A_time_part=; put ThisTime= ; break=repeat("*",40); put / break /; put"The DAY function produces an integer from 1 to 31 that represents the day of the month."; Bday='05may97'd; DOM_BDay=day(Bday); TodayDate=today(); DOM_TodayDate=day(TodayDate); put Bday= DOM_BDay= TodayDate= DOM_TodayDate= ; break=repeat("*",40); put / break; thisInstant=DateTime(); DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put DayFromDateTime= ThisInstant=; TimeFromDateTime=TimePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put TimeFromDateTime= ThisInstant=; break=repeat("*",15)||" MDY "||repeat("*",15); put / break /; put"The MDY function converts MONTH, DAY, and YEAR values to a SAS date value." ; put "For example, MDY(01,21,2010) returns the SAS date value for 21Jan2010 "; month=01; day=21; year=2010; DateFromNum=MDY(month,day,year); Put DateFromNum= DateFromNum= yymmdd10.; *MDY When month, day, and year are char; Cmonth="01"; Cday ="05"; Cyear ="2010"; DateFromChar=MDY(input(Cmonth,2.),input(Cday,2.),input(Cyear,4.)); Put DateFromChar= DateFromChar= yymmdd10.; break=repeat("*",15)||" INTCK "||repeat("*",15); put / break /; /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; break=repeat("*",15)||" INTNX "||repeat("*",15); put / break /; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; string="Aligning a date to prev or following Friday"; DASH = REPEAT("-",length(string) - 1); PUT /DASH/ STRING / DASH; *Align to friday of previous week; TheDate=today(); PrevFriday= intnx('week.6', today(),0); put TheDate= EURDFWKX21. PrevFriday= EURDFWKX21.; *what if the date IS a friday and we want to align to that date; AFriday=20692; put /"What if the date IS already a friday?"; AlignedFriday= intnx('week.6', AFriday,0); put AFriday= EURDFWKX21. AlignedFriday= EURDFWKX21.; *align to next friday; TheDate=today(); NextFriday= intnx('week.6', today(),+1); put /TheDate= EURDFWKX21. NextFriday= EURDFWKX21.; run; 50 1 4252 3 datejul( 1 332 1 1 dateJul(numericDate) 52 1 )252 3 datepart( 1 332 1 123 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ /* Pretty dates all in a row Dianne Rhodes For my reports, which I usually run on Monday, I want to find last Friday’s date. The Week interval starts with Sunday, so Friday is week.6. ReportDate= intnx(‘week.6’, today(),0) The Start Date of the period will be the Saturday of the week before StartDate = intnx(‘week.7’, ReportDate, 0) http://www2.sas.com/proceedings/sugi30/055-30.pdf*/ /* INTNX('interval', start,from , increment, <,alignment>) INTCK('interval',from_date, to_date)*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ This_Day_Time=DateTime(); /*Reads system clock*/ A_date_part=DatePart(This_Day_Time); A_time_part=TimePart(This_Day_Time); ThisTime=time(); put TodayDate= TodayToday= ; put This_Day_Time= A_date_part= A_time_part=; put ThisTime= ; break=repeat("*",40); put / break /; put"The DAY function produces an integer from 1 to 31 that represents the day of the month."; Bday='05may97'd; DOM_BDay=day(Bday); TodayDate=today(); DOM_TodayDate=day(TodayDate); put Bday= DOM_BDay= TodayDate= DOM_TodayDate= ; break=repeat("*",40); put / break; thisInstant=DateTime(); DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put DayFromDateTime= ThisInstant=; TimeFromDateTime=TimePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put TimeFromDateTime= ThisInstant=; break=repeat("*",15)||" MDY "||repeat("*",15); put / break /; put"The MDY function converts MONTH, DAY, and YEAR values to a SAS date value." ; put "For example, MDY(01,21,2010) returns the SAS date value for 21Jan2010 "; month=01; day=21; year=2010; DateFromNum=MDY(month,day,year); Put DateFromNum= DateFromNum= yymmdd10.; *MDY When month, day, and year are char; Cmonth="01"; Cday ="05"; Cyear ="2010"; DateFromChar=MDY(input(Cmonth,2.),input(Cday,2.),input(Cyear,4.)); Put DateFromChar= DateFromChar= yymmdd10.; break=repeat("*",15)||" INTCK "||repeat("*",15); put / break /; /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; break=repeat("*",15)||" INTNX "||repeat("*",15); put / break /; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; string="Aligning a date to prev or following Friday"; DASH = REPEAT("-",length(string) - 1); PUT /DASH/ STRING / DASH; *Align to friday of previous week; TheDate=today(); PrevFriday= intnx('week.6', today(),0); put TheDate= EURDFWKX21. PrevFriday= EURDFWKX21.; *what if the date IS a friday and we want to align to that date; AFriday=20692; put /"What if the date IS already a friday?"; AlignedFriday= intnx('week.6', AFriday,0); put AFriday= EURDFWKX21. AlignedFriday= EURDFWKX21.; *align to next friday; TheDate=today(); NextFriday= intnx('week.6', today(),+1); put /TheDate= EURDFWKX21. NextFriday= EURDFWKX21.; run; 53 1 y252 3 datetime 1 332 1 51 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ ThisInstant=DateTime(); /*Reads system clock*/ put TodayDate= TodayToday= ThisInstant=; break=repeat("*",40); put break; DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; run; 146 1 )252 3 datetime( 1 332 1 123 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ /* Pretty dates all in a row Dianne Rhodes For my reports, which I usually run on Monday, I want to find last Friday’s date. The Week interval starts with Sunday, so Friday is week.6. ReportDate= intnx(‘week.6’, today(),0) The Start Date of the period will be the Saturday of the week before StartDate = intnx(‘week.7’, ReportDate, 0) http://www2.sas.com/proceedings/sugi30/055-30.pdf*/ /* INTNX('interval', start,from , increment, <,alignment>) INTCK('interval',from_date, to_date)*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ This_Day_Time=DateTime(); /*Reads system clock*/ A_date_part=DatePart(This_Day_Time); A_time_part=TimePart(This_Day_Time); ThisTime=time(); put TodayDate= TodayToday= ; put This_Day_Time= A_date_part= A_time_part=; put ThisTime= ; break=repeat("*",40); put / break /; put"The DAY function produces an integer from 1 to 31 that represents the day of the month."; Bday='05may97'd; DOM_BDay=day(Bday); TodayDate=today(); DOM_TodayDate=day(TodayDate); put Bday= DOM_BDay= TodayDate= DOM_TodayDate= ; break=repeat("*",40); put / break; thisInstant=DateTime(); DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put DayFromDateTime= ThisInstant=; TimeFromDateTime=TimePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put TimeFromDateTime= ThisInstant=; break=repeat("*",15)||" MDY "||repeat("*",15); put / break /; put"The MDY function converts MONTH, DAY, and YEAR values to a SAS date value." ; put "For example, MDY(01,21,2010) returns the SAS date value for 21Jan2010 "; month=01; day=21; year=2010; DateFromNum=MDY(month,day,year); Put DateFromNum= DateFromNum= yymmdd10.; *MDY When month, day, and year are char; Cmonth="01"; Cday ="05"; Cyear ="2010"; DateFromChar=MDY(input(Cmonth,2.),input(Cday,2.),input(Cyear,4.)); Put DateFromChar= DateFromChar= yymmdd10.; break=repeat("*",15)||" INTCK "||repeat("*",15); put / break /; /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; break=repeat("*",15)||" INTNX "||repeat("*",15); put / break /; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; string="Aligning a date to prev or following Friday"; DASH = REPEAT("-",length(string) - 1); PUT /DASH/ STRING / DASH; *Align to friday of previous week; TheDate=today(); PrevFriday= intnx('week.6', today(),0); put TheDate= EURDFWKX21. PrevFriday= EURDFWKX21.; *what if the date IS a friday and we want to align to that date; AFriday=20692; put /"What if the date IS already a friday?"; AlignedFriday= intnx('week.6', AFriday,0); put AFriday= EURDFWKX21. AlignedFriday= EURDFWKX21.; *align to next friday; TheDate=today(); NextFriday= intnx('week.6', today(),+1); put /TheDate= EURDFWKX21. NextFriday= EURDFWKX21.; run; 54 1 $252 3 day( 1 332 1 123 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ /* Pretty dates all in a row Dianne Rhodes For my reports, which I usually run on Monday, I want to find last Friday’s date. The Week interval starts with Sunday, so Friday is week.6. ReportDate= intnx(‘week.6’, today(),0) The Start Date of the period will be the Saturday of the week before StartDate = intnx(‘week.7’, ReportDate, 0) http://www2.sas.com/proceedings/sugi30/055-30.pdf*/ /* INTNX('interval', start,from , increment, <,alignment>) INTCK('interval',from_date, to_date)*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ This_Day_Time=DateTime(); /*Reads system clock*/ A_date_part=DatePart(This_Day_Time); A_time_part=TimePart(This_Day_Time); ThisTime=time(); put TodayDate= TodayToday= ; put This_Day_Time= A_date_part= A_time_part=; put ThisTime= ; break=repeat("*",40); put / break /; put"The DAY function produces an integer from 1 to 31 that represents the day of the month."; Bday='05may97'd; DOM_BDay=day(Bday); TodayDate=today(); DOM_TodayDate=day(TodayDate); put Bday= DOM_BDay= TodayDate= DOM_TodayDate= ; break=repeat("*",40); put / break; thisInstant=DateTime(); DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put DayFromDateTime= ThisInstant=; TimeFromDateTime=TimePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put TimeFromDateTime= ThisInstant=; break=repeat("*",15)||" MDY "||repeat("*",15); put / break /; put"The MDY function converts MONTH, DAY, and YEAR values to a SAS date value." ; put "For example, MDY(01,21,2010) returns the SAS date value for 21Jan2010 "; month=01; day=21; year=2010; DateFromNum=MDY(month,day,year); Put DateFromNum= DateFromNum= yymmdd10.; *MDY When month, day, and year are char; Cmonth="01"; Cday ="05"; Cyear ="2010"; DateFromChar=MDY(input(Cmonth,2.),input(Cday,2.),input(Cyear,4.)); Put DateFromChar= DateFromChar= yymmdd10.; break=repeat("*",15)||" INTCK "||repeat("*",15); put / break /; /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; break=repeat("*",15)||" INTNX "||repeat("*",15); put / break /; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; string="Aligning a date to prev or following Friday"; DASH = REPEAT("-",length(string) - 1); PUT /DASH/ STRING / DASH; *Align to friday of previous week; TheDate=today(); PrevFriday= intnx('week.6', today(),0); put TheDate= EURDFWKX21. PrevFriday= EURDFWKX21.; *what if the date IS a friday and we want to align to that date; AFriday=20692; put /"What if the date IS already a friday?"; AlignedFriday= intnx('week.6', AFriday,0); put AFriday= EURDFWKX21. AlignedFriday= EURDFWKX21.; *align to next friday; TheDate=today(); NextFriday= intnx('week.6', today(),+1); put /TheDate= EURDFWKX21. NextFriday= EURDFWKX21.; run; 58 1 /252 3 dequote( 1 332 1 1 dequote(string) 63 1 š252 3 deviance( 1 332 1 1 deviance( 'Bernoulli|binomial|gamma|iGauss|Wald|normal|Gaussian|Poisson' , numericVariable , shapeParameters , epsilon ) 219 1 [252 3 dhms( 1 332 1 1 dhms( sasDate , numericHour , numericMinute , numericSecond ) 120 1 0252 3 digamma( 1 332 1 1 digamma(number) 220 1 Ø 252 3 dim( 1 332 1 93 /*array Lbound Hbound Dim _temporary_*/ /* this example is weak on multi-dimensional arrays - DIM always returns a total count of the number of elements in an array dimension. HBOUND returns the literal value of the upper bound of an array dimension. The LBOUND function returns the lower bound of a one-dimensional array or the lower bound of a specified dimension of a multidimensional array. temporaty arrays are faster than "regular" arrays*/ data ClassCount; retain age1-age20 /*temp arrays are automatically retianed*/; set sashelp.class end=EOF; array BigAgCt(0:25) _temporary_; array SmlAgCt(20) age1-age20; /*Initialize*/ if _n_=1 then Do; Do S=Lbound(SmlAgCt) to Hbound(SmlAgCt); SmlAgCt(S)=0; put "initializing" S=; end; Do B=Lbound(BigAgCt) to Hbound(BigAgCt); BigAgCt(B)=0; End; End; /*Count students in ages*/ SmlAgCt(age)=SmlAgCt(age)+1 ; put "Loading " age= SmlAgCt(age)= ; /* Count students in ages*/ BigAgCt(age)=BigAgCt(age)+1 ; if EOF=1 then do loopS= Lbound(SmlAgCt) to Hbound(SmlAgCt) ; put "Printing values from the small array: " LoopS= "and the value is " SmlAgCt(LoopS); end; do loopB= Lbound(BigAgCt) to Hbound(BigAgCt) ; put "Printing values from the UntRetained array: " LoopB= "and the value is " BigAgCt(LoopB); end; run; /*Dim*/ /*In this example, DIM returns a value of 5. Therefore, SAS repeats the statements in the DO loop five times. */ data _null_; array big{5} weight sex height state city; do i=1 to dim(big); Put "the value is" Bif(i); end; run; /*Examples of arrays*/ data text; /*Character arrays*/ array names{*} $ n1-n10; array capitals{*} $ c1-c10; input names{*}; do i=1 to 10; capitals{i}=upcase(names{i}); end; datalines; smithers michaels gonzalez hurth frank bleigh rounder joseph peters sam ; /*To create a temporary array, use the _TEMPORARY_ argument. The following example creates a temporary array named TEST: */ options nodate pageno=1 linesize=80 pagesize=60; data score2(drop=i); /*array test{3} t1-t3 (90 80 70);*/ /*Perm array and assign initial values*/ array test{3} _temporary_ (90 80 70); /*Temp array and assign initial values*/ array score{3} s1-s3; input id score{*}; do i=1 to 3; if score{i}>=test{i} then do; NewScore=score{i}; output; end; end; datalines; 1234 99 60 82 5678 80 85 75 ; proc print noobs data=score2; title 'Data Set SCORE2'; run; 51 1 252 3 DOCBLOCK 1 332 1 53 /******************************************************************************* ** Start entries after the *. Start in col 31 or 32 Program: 1* X_Required_45CharMax_X Dev/Active/Inactive/AH: 2* X_Required_45CharMax_X Programmer: 3* X_Required_45CharMax_X Program Owner: 4* X_Required_45CharMax_X Business Owner: 5* X_Required_45CharMax_X Date Pgm. Started: 6* X_Required_ISO8601_EG1997-07-16_X Date First Into Production: 7* X_Required_ISO8601_or DEV_X Most Recent Into Production:8* X_Required_ISO8601_EG1997-07-16_X Client: 9* X_Required_45CharMax_X Study: 10* X_Required_45CharMax_X Purpose:11** X___Required_60CharMax___X *********** Preceeding: 12 (prog name or NONE) Programs that must be run before this can be run (prog name or NONE) X_Optional_45CharMax_X X_Optional_45CharMax_X X_Optional_45CharMax_X Concurrent: 13 (prog name or NONE) Programs that can be run concurrent with this X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X Following: 14 (prog name or NONE) Programs that Can only be run after this finishes X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X Driver files: 15 (file name or NONE) External files containg metadata to control program execution X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X Infiles: 16(table name or NONE) perm files USED by this program X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X Outfiles: 17(table name or NONE) perm files CREATED by this program X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X Macros Called: 18(macro name or NONE) perm macros called by this program X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X Formats Called: 19(format name or NONE) perm formats called by this program X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X X_Name/NONE_45CharMax_X Maintenance: this is not currently poarsed Date: XX/XX/XXXX Programmer: XX Issue: XXXXXXXXXXXXXXXXXXX Date: XX/XX/XXXX Programmer: XX Issue: XXXXXXXXXXXXXXXXXXX [a-zA-Z1-9 _]\.[a-zA-z_] *******************************************************************************/ 363 1 ¥252 3 dow_loop 1 332 1 226 /***************************************************************** This shows a few ways to apportion volumes of product (here they are rx) We have different numbers of reps calling on chains We want to apportion the rx to the reps who called on that chain CID= 1 ; Qtr=1; Rx=20;output; CID= 1 ; Qtr=2; Rx=30;output; CID= 1 ; Qtr=3; Rx=40;output; CID rep 1 Amy 1 Bo 1 Cheng ******************************************************************/ Data Accounts2Reps; infile datalines firstobs=2 truncover; input @1 CID 1. @5 RepName $char10.; datalines; 1234567890123456789012345678901234567890 1 Amy 1 Bo 1 Cheng 2 AnLei 2 Betty 2 Cathy 2 Juan 3 Adam 3 Barb 3 Charlie 3 Debbie 3 Erle ; run; data Rx; CID= 1 ; Qtr=1; Rx=20; Cust="Cust 1"; output; CID= 1 ; Qtr=2; Rx=30; Cust="Cust 1"; output; CID= 1 ; Qtr=3; Rx=40; Cust="Cust 1"; output; CID= 1 ; Qtr=4; Rx=50; Cust="Cust 1"; output; CID= 2 ; Qtr=1; Rx=10; Cust="Cust 2"; output; CID= 2 ; Qtr=2; Rx=20; Cust="Cust 2"; output; CID= 2 ; Qtr=3; Rx=30; Cust="Cust 2"; output; CID= 2 ; Qtr=4; Rx=40; Cust="Cust 2"; output; CID= 3 ; Qtr=1; Rx=20; Cust="Cust 3"; output; CID= 3 ; Qtr=2; Rx=15; Cust="Cust 3"; output; CID= 3 ; Qtr=3; Rx=10; Cust="Cust 3"; output; CID= 3 ; Qtr=4; Rx=5; Cust="Cust 3"; output; run; /***************************************************************** Section __: DOW LOOP Apportioning in Several Steps A way to do a Cartesian product in a data step is shown below: ******************************************************************/ /*get number of chains*/ proc SQL; Create table NmbrOfreps as select Cid , count(*) as NmbrOfreps from Accounts2Reps group by CID; /*CID=Customer ID*/ quit; data Rx_n_N; merge Rx NmbrOfReps; by cid; run; data DOWapportioned /*/debug*/; retain pointer; If _n_=1 then Pointer=1; set Rx_n_N (rename=(CID=RxCID)) End=EndOuter; by RxCid; do Count=Pointer by 1 Until ((RxCID NE CID) or Count=NobsInner); set accounts point=count end=EOFInner nobs=NobsInner; if RXCid = CID then do; ApportionedRx=Rx/NmbrOfreps; output; *put _all_; end; end; /*Count=Pointer by 1 Until (RxCID NE CID or eof2=1 );*/ if last.RxCid then pointer=Count; if EndOuter =1 then stop; run; proc sql; select "the total in the raw data is: ", sum(rx) from rx union select "the total in the DOW final data is: ", sum(apportionedRX) from DOWApportioned; quit; proc sql; select r.CID ,cust ,RawRx ,AppRx ,AppRx-RawRx as delta from (select CID, cust , sum(rx) as RawRx from Rx group by CID, cust) as R Inner join (select CID , sum(apportionedRX) as AppRx from DOWApportioned group by CID) as A on R.cid=A.cid order by delta desc; quit; options nocenter; Proc print data=DOWapportioned ; run; /***************************************************************** Section __: Apportioning using SQL ******************************************************************/ proc SQL; create table SQL_apportioned as select Rx.cid , qtr , rx , NC.NmbrOfReps , RepName , rx /NmbrOfreps as apportioned from ( select Cid , count(*) as NmbrOfreps from Accounts2Reps group by CID ) as NC , Accounts2Reps as A , rx Where NC.cid=A.cid and NC.cid=rx.cid order by CId, Qtr, RepName; quit; proc sql; select "the total in the raw data is: ", sum(rx) from rx union select "the total in the SQL final data is: ", sum(apportioned) from SQL_apportioned; quit; options ls=120; proc sql; select r.CID ,RawRx ,AppRx ,Qtr ,rx ,apportioned ,NmbrOfreps ,RepName ,AppRx-RawRx as delta ,case when calculated delta GT 0 then "<-------" else " " end as flag from (select CID , sum(rx) as RawRx from Rx group by CID) as R Inner join (select CID ,RepName ,rx, qtr, NmbrOfreps, apportioned, sum(apportioned) as AppRx from SQL_Apportioned group by CID) as A on R.cid=A.cid order by CID ,qtr, RepName, delta desc; quit; /***************************************************************** Section __: Using several Different procs and steps ******************************************************************/ proc summary data=Accounts2Reps nway missing; class CID; output out=NmbrOfRepsInAnAccount(drop= _type_ _freq_) n(CID)=NmbrOfReps; quit; data Rx_N_N; merge rx NmbrOfRepsInAnAccount; by cid; run; /*use SQL for the cartesian merge*/ proc sql; create table RXApportioned as select RX.CID ,cust ,qtr ,rx ,NmbrOfReps ,rx/NmbrOfReps as ApportionedRX ,RepName from Rx_N_N as Rx left join Accounts2Reps as A on rx.cid=a.cid order by cid, qtr,RepName ; quit; proc sql; select "the total in the raw data is: ", sum(rx) from rx union select "the total in the multi step final data is: ", sum(apportionedRX) from RXApportioned; quit; proc sql; select r.CID ,cust ,r.qtr ,RawRx ,apportionedRX ,AppRx-RawRx as delta from (select CID, qtr, cust , sum(rx) as RawRx from Rx group by CID, qtr) as R Inner join (select CID , qtr, apportionedRX, sum(apportionedRX) as AppRx from RXApportioned group by CID, qtr) as A on R.cid=A.cid and R.qtr=A.qtr order by cust, qtr ; quit; 171 1 (252 3 erf( 1 332 1 1 erF(number) 221 1 *252 3 erfc( 1 332 1 1 erFC(number) 222 1 252 3 eurocurr( 1 332 1 1 euroCurr( amount , fromCode , toCode ) /* Codes: AustrianSchilling=ATS BelgianFranc=BEF BritishPoundSterling=GBP CzechKoruna=CZK DanishKrone=DKK DeutscheMark=DEM DutchGuilder=NLG Euro=EUR FinnishMarkka=FIM FrenchFranc=FRF GreekDrachma=GRD HungarianForint=HUF IrishPound=IEP ItalianLira=ITL LuxembourgFranc=LUF NorwegianKrone=NOK PolishZloty=PLZ PortugueseEscudo=PTE RomanianLeu=ROL RussianRuble=RUR SlovenianTolar=SIT SpanishPeseta=ESP SwedishKrona=SEK SwissFranc=CHF TurkishLira=TRL YugoslavianDinar=YUD */ 47 1 (252 3 exp( 1 332 1 1 exp(number) 223 1 4252 3 fact( 1 332 1 1 fact(numberOfElements) 224 1 U252 3 find( 1 332 1 142 /*FIND FINDC FINDW Count CountW CountC (These might eb better than Verify , index , indexc and indexw) The find Function returns the character position of a specific substring of characters within a character string. The FINDC function returns the character position of the first encountered character from a group of individual characters The FindW Funcion returns the character position of a word in a string, The FIND group of functions and the INDEX group of functions both search for substrings of characters in a character string. However, the INDEX functions do not have the modifiers nor the startpos arguments. The FINDC function searches for individual characters in a character string, whereas the FIND function searches for substrings of characters in a character string. The FINDC function and the INDEXC function both search for individual characters in a character string. However, the INDEXC function does not have the modifier nor the startpos arguments. The FINDC function searches for individual characters in a character string, whereas the VERIFY function searches for the first character that is unique to an expression. The VERIFY function does not have the modifier nor the startpos arguments. Count Counts the number of times that a specified substring appears within a character string. CountW Counts the number of words in a character string. CountC Counts the number of characters in a string that appear or do not appear in a list of characters. */ data _null_; /*Find FIND function searches for substrings of characters in a character string*/ WhereIsShe=find('She sells seashells? Yes, she does.','she '); put WhereIsShe; variable1='She sells seashells? Yes, she does.'; variable2='she '; variable3='i'; WhereIsShe_i=find(variable1,variable2,variable3); put WhereIsShe_i; expression1='She sells seashells? '||'Yes, she does.'; expression2=kscan('he or she',3)||' '; expression3=trim('t '); WhereIsShe_t=find(expression1,expression2,expression3); put WhereIsShe_t; xyz='She sells seashells? Yes, she does.'; startposvar=22; WhereIsShe_22=find(xyz,'she',startposvar); /*FindW Returns the character position of a word in a string, or returns the number of the word in a string. */ WhereIsShe_W1=findw('She sells sea shells? Yes, she does.','she'); put WhereIsShe_W1=; /*Only the second occurrence is found by FINDW because the search begins in position 25. The chars argument specifies a space as the delimiter. */ result = findw('At least 2.5 meters of rain falls in a rain forest.', 'rain', ' ', 25); put result=; /*FindC Searches a string for any character in a list of characters. */ /*count*/ xyz='This is a thistle? Yes, this is a thistle.'; HowManyThis=count(xyz,'this'); put HowManyhis; xyz='This is a thistle? Yes, this is a thistle.'; HowManyIs=count(xyz,'is'); put HowManyIs; HowManyhis_i=count('This is a thistle? Yes, this is a thistle.' ,'this','i'); put HowManyhis_i; variable1='This is a thistle? Yes, this is a thistle.'; variable2='is '; variable3='i'; HowManyIs_i=count(variable1,variable2,variable3); put HowManyIs_i; expression1='This is a thistle? '||'Yes, this is a thistle.'; expression2=kscan('This is',2)||' '; expression3=compress('i '||' t'); howmanyis_it=count(expression1,expression2,expression3); put howmanyis_it; put WhereIsShe_22; xyz='She sells seashells? Yes, she does.'; startposexp=1-23; whereisShe_ineg22=find(xyz,'She','i',startposexp); put whereisShe_ineg22; Run; /*CountW*/ /*The following example shows how to use the COUNTW function with the M and P modifiers. */ options ls=64 pageno=1 nodate; data test; length default blanks mp 8; input string $char60.; default = CountW(string); blanks = CountW(string, ' '); mp = CountW(string, 'mp'); datalines; The quick brown fox jumps over the lazy dog. Leading blanks 2+2=4 /unix/path/names/use/slashes \Windows\Path\Names\Use\Backslashes ; run; proc print noobs data=test; run; /*CountC*/ /*The following example uses the COUNTC function with and without modifiers to count the number of characters in a string. */ data test; string = 'Baboons Eat Bananas '; a = countc(string, 'a'); b = countc(string,'b'); b_i = countc(string,'b','i'); abc_i = countc(string,'abc','i'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, (and include blanks). */ abc_iv = countc(string,'abc','iv'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, and trim trailing blanks. */ abc_ivt = countc(string,'abc','ivt'); run; options pageno=1 ls=80 nodate; proc print data=test noobs; run; 55 1 V252 3 findc( 1 332 1 142 /*FIND FINDC FINDW Count CountW CountC (These might eb better than Verify , index , indexc and indexw) The find Function returns the character position of a specific substring of characters within a character string. The FINDC function returns the character position of the first encountered character from a group of individual characters The FindW Funcion returns the character position of a word in a string, The FIND group of functions and the INDEX group of functions both search for substrings of characters in a character string. However, the INDEX functions do not have the modifiers nor the startpos arguments. The FINDC function searches for individual characters in a character string, whereas the FIND function searches for substrings of characters in a character string. The FINDC function and the INDEXC function both search for individual characters in a character string. However, the INDEXC function does not have the modifier nor the startpos arguments. The FINDC function searches for individual characters in a character string, whereas the VERIFY function searches for the first character that is unique to an expression. The VERIFY function does not have the modifier nor the startpos arguments. Count Counts the number of times that a specified substring appears within a character string. CountW Counts the number of words in a character string. CountC Counts the number of characters in a string that appear or do not appear in a list of characters. */ data _null_; /*Find FIND function searches for substrings of characters in a character string*/ WhereIsShe=find('She sells seashells? Yes, she does.','she '); put WhereIsShe; variable1='She sells seashells? Yes, she does.'; variable2='she '; variable3='i'; WhereIsShe_i=find(variable1,variable2,variable3); put WhereIsShe_i; expression1='She sells seashells? '||'Yes, she does.'; expression2=kscan('he or she',3)||' '; expression3=trim('t '); WhereIsShe_t=find(expression1,expression2,expression3); put WhereIsShe_t; xyz='She sells seashells? Yes, she does.'; startposvar=22; WhereIsShe_22=find(xyz,'she',startposvar); /*FindW Returns the character position of a word in a string, or returns the number of the word in a string. */ WhereIsShe_W1=findw('She sells sea shells? Yes, she does.','she'); put WhereIsShe_W1=; /*Only the second occurrence is found by FINDW because the search begins in position 25. The chars argument specifies a space as the delimiter. */ result = findw('At least 2.5 meters of rain falls in a rain forest.', 'rain', ' ', 25); put result=; /*FindC Searches a string for any character in a list of characters. */ /*count*/ xyz='This is a thistle? Yes, this is a thistle.'; HowManyThis=count(xyz,'this'); put HowManyhis; xyz='This is a thistle? Yes, this is a thistle.'; HowManyIs=count(xyz,'is'); put HowManyIs; HowManyhis_i=count('This is a thistle? Yes, this is a thistle.' ,'this','i'); put HowManyhis_i; variable1='This is a thistle? Yes, this is a thistle.'; variable2='is '; variable3='i'; HowManyIs_i=count(variable1,variable2,variable3); put HowManyIs_i; expression1='This is a thistle? '||'Yes, this is a thistle.'; expression2=kscan('This is',2)||' '; expression3=compress('i '||' t'); howmanyis_it=count(expression1,expression2,expression3); put howmanyis_it; put WhereIsShe_22; xyz='She sells seashells? Yes, she does.'; startposexp=1-23; whereisShe_ineg22=find(xyz,'She','i',startposexp); put whereisShe_ineg22; Run; /*CountW*/ /*The following example shows how to use the COUNTW function with the M and P modifiers. */ options ls=64 pageno=1 nodate; data test; length default blanks mp 8; input string $char60.; default = CountW(string); blanks = CountW(string, ' '); mp = CountW(string, 'mp'); datalines; The quick brown fox jumps over the lazy dog. Leading blanks 2+2=4 /unix/path/names/use/slashes \Windows\Path\Names\Use\Backslashes ; run; proc print noobs data=test; run; /*CountC*/ /*The following example uses the COUNTC function with and without modifiers to count the number of characters in a string. */ data test; string = 'Baboons Eat Bananas '; a = countc(string, 'a'); b = countc(string,'b'); b_i = countc(string,'b','i'); abc_i = countc(string,'abc','i'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, (and include blanks). */ abc_iv = countc(string,'abc','iv'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, and trim trailing blanks. */ abc_ivt = countc(string,'abc','ivt'); run; options pageno=1 ls=80 nodate; proc print data=test noobs; run; 64 1 œ252 3 findn( 1 332 1 34 /*FIND FINDC FINDW The find Function returns the character position of a specific substring of characters within a character string. The FINDC function returns the character position of the first encountered character from a group of individual characters The FindW Funcion returns the character position of a word in a string, The FIND group of functions and the INDEX group of functions both search for substrings of characters in a character string. However, the INDEX functions do not have the modifiers nor the startpos arguments. */ /*Missing*/ data _null_; NumAndMissing =.; CharAndMissing =""; CharAndOneBlank=" "; NumAndValued =4; CharAndValued ="SAS Stat"; NumAndMissingYN =missing(NumAndMissing ); put NumAndMissing= NumAndMissingYN=; CharAndMissingYN =missing(CharAndMissing ); put CharAndMissing= CharAndMissingYN=; CharAndOneBlankYN =missing(CharAndOneBlank ); put CharAndOneBlank= CharAndOneBlankYN=; NumAndValuedYN =missing(NumAndValued ); put NumAndValued= NumAndValuedYN=; CharAndValuedYN =missing(CharAndValued); put CharAndValued= CharAndValuedYN=; ; run; 292 1 W252 3 findw( 1 332 1 142 /*FIND FINDC FINDW Count CountW CountC (These might eb better than Verify , index , indexc and indexw) The find Function returns the character position of a specific substring of characters within a character string. The FINDC function returns the character position of the first encountered character from a group of individual characters The FindW Funcion returns the character position of a word in a string, The FIND group of functions and the INDEX group of functions both search for substrings of characters in a character string. However, the INDEX functions do not have the modifiers nor the startpos arguments. The FINDC function searches for individual characters in a character string, whereas the FIND function searches for substrings of characters in a character string. The FINDC function and the INDEXC function both search for individual characters in a character string. However, the INDEXC function does not have the modifier nor the startpos arguments. The FINDC function searches for individual characters in a character string, whereas the VERIFY function searches for the first character that is unique to an expression. The VERIFY function does not have the modifier nor the startpos arguments. Count Counts the number of times that a specified substring appears within a character string. CountW Counts the number of words in a character string. CountC Counts the number of characters in a string that appear or do not appear in a list of characters. */ data _null_; /*Find FIND function searches for substrings of characters in a character string*/ WhereIsShe=find('She sells seashells? Yes, she does.','she '); put WhereIsShe; variable1='She sells seashells? Yes, she does.'; variable2='she '; variable3='i'; WhereIsShe_i=find(variable1,variable2,variable3); put WhereIsShe_i; expression1='She sells seashells? '||'Yes, she does.'; expression2=kscan('he or she',3)||' '; expression3=trim('t '); WhereIsShe_t=find(expression1,expression2,expression3); put WhereIsShe_t; xyz='She sells seashells? Yes, she does.'; startposvar=22; WhereIsShe_22=find(xyz,'she',startposvar); /*FindW Returns the character position of a word in a string, or returns the number of the word in a string. */ WhereIsShe_W1=findw('She sells sea shells? Yes, she does.','she'); put WhereIsShe_W1=; /*Only the second occurrence is found by FINDW because the search begins in position 25. The chars argument specifies a space as the delimiter. */ result = findw('At least 2.5 meters of rain falls in a rain forest.', 'rain', ' ', 25); put result=; /*FindC Searches a string for any character in a list of characters. */ /*count*/ xyz='This is a thistle? Yes, this is a thistle.'; HowManyThis=count(xyz,'this'); put HowManyhis; xyz='This is a thistle? Yes, this is a thistle.'; HowManyIs=count(xyz,'is'); put HowManyIs; HowManyhis_i=count('This is a thistle? Yes, this is a thistle.' ,'this','i'); put HowManyhis_i; variable1='This is a thistle? Yes, this is a thistle.'; variable2='is '; variable3='i'; HowManyIs_i=count(variable1,variable2,variable3); put HowManyIs_i; expression1='This is a thistle? '||'Yes, this is a thistle.'; expression2=kscan('This is',2)||' '; expression3=compress('i '||' t'); howmanyis_it=count(expression1,expression2,expression3); put howmanyis_it; put WhereIsShe_22; xyz='She sells seashells? Yes, she does.'; startposexp=1-23; whereisShe_ineg22=find(xyz,'She','i',startposexp); put whereisShe_ineg22; Run; /*CountW*/ /*The following example shows how to use the COUNTW function with the M and P modifiers. */ options ls=64 pageno=1 nodate; data test; length default blanks mp 8; input string $char60.; default = CountW(string); blanks = CountW(string, ' '); mp = CountW(string, 'mp'); datalines; The quick brown fox jumps over the lazy dog. Leading blanks 2+2=4 /unix/path/names/use/slashes \Windows\Path\Names\Use\Backslashes ; run; proc print noobs data=test; run; /*CountC*/ /*The following example uses the COUNTC function with and without modifiers to count the number of characters in a string. */ data test; string = 'Baboons Eat Bananas '; a = countc(string, 'a'); b = countc(string,'b'); b_i = countc(string,'b','i'); abc_i = countc(string,'abc','i'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, (and include blanks). */ abc_iv = countc(string,'abc','iv'); /* Scan string for characters that are not "a", "b", */ /* and "c", ignore case, and trim trailing blanks. */ abc_ivt = countc(string,'abc','ivt'); run; options pageno=1 ls=80 nodate; proc print data=test noobs; run; 311 1 ‚252 3 finv( 1 332 1 1 fInv( numericProbability , numeratorDegreesOfFreedom , denominatorDegreesOfFreedom , nonCentrality ) 261 1 7252 3 fipname( 1 332 1 1 fipName(fipsStateCode) 297 1 9252 3 fipnamel( 1 332 1 1 fipNameL(fipsStateCode) 298 1 9252 3 fipstate( 1 332 1 1 fipState(fipsStateCode) 299 1 "252 3 floor( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 317 1 .252 3 floorz( 1 332 1 1 floorZ(number) 318 1 252 3 fnonct( 1 332 1 1 fNonct( numericVariable , numeratorDegreesOfFreedom , denominatorDegreesOfFreedom , probability ) 225 1 *252 3 fuzz( 1 332 1 1 fuzz(number) 319 1 D252 3 gaminv( 1 332 1 1 gamInv( numericProbability , shape ) 262 1 ,252 3 gamma( 1 332 1 1 gamma(number) 226 1 D252 3 geomean( 1 332 1 1 geoMean( number1< , number2<...>> ) 167 1 F252 3 geomeanz( 1 332 1 1 geoMeanZ( number1< , number2<...>> ) 168 1 D252 3 harmean( 1 332 1 1 harMean( number1< , number2<...>> ) 169 1 F252 3 harmeanz( 1 332 1 1 harMeanZ( number1< , number2<...>> ) 170 1 i252 3 Hash_3Way_merge 1 332 1 58 /**Hashing - merege 3 files without sorting************************/ /*Judy Loren NESUG 2008 Programming beyond the basics*/ /*How Do I love Hash Tables? Let Me Count The Ways page 3*/ Proc SQL;/*BaseTable- we want to merge data to this*/ create table BaseTable as select name, sex from sashelp.class order by ranuni(5); proc SQL;/*Merge this to base table-not all obs will have a match"*/ create table LookupAge as select name , age from sashelp.class having ranuni(3) Le .7 order by sex; run; Proc SQL; create table summarized as select sex, avg(height) as AvgHeight from sashelp.class group by sex; run; data Hash3WayMerge; /*we are merging on different levels of grouping*/ /*put all variables on the PDV*/ If 0 then set work.LookupAge; if 0 then set Summarized; /*create and load hash table for LookupAge*/ declare hash ages(dataset: "LookupAge", hashexp: 4);/*2^4 cells - playing around*/ ages.definekey("name"); /*we will "merge" on name*/ ages.definedata("age"); /*define the data in the Hash table & PDV*/ ages.DefineDone(); /*create and load hash table for average height by sex*/ declare hash AvgHgt (dataset: "summarized", hashexp:1);/*- playing around*/ AvgHgt.definekey("Sex"); /*we will "merge" on sex*/ AvgHgt.definedata("AvgHeight"); /*define the data in the Hash table & PDV*/ AvgHgt.DefineDone(); do until (EOF); /*read baseline inside a loop*/ /*initialize vars brought in- The PDV is NOT cleared*/ avgHeight=.; age=.; Set BaseTable end=EOF; rc=ages.find(); if RC NE 0 then put "Could not find an age in the hash table"; rc=AvgHgt.find(); if RC NE 0 then put "Could not find avg height in the hash table"; output; end; stop; /*this will only make one pass through the data step*/ run; proc print data=Hash3WayMerge; run; 364 1 ¢252 3 Hashing_LeftJoinLookup 1 332 1 43 /*Using hashing to create an output like a left join*/ /*Courtesy of Paul Dorfmann*/ /*http://www2.sas.com/proceedings/sugi31/241-31.pdf*/ /*http://www.nesug.org/Proceedings/nesug05/cc/ccx3.pdf*/ data Small(keep=name age obsno)/*Boss says get info on these people*/ Large(drop=age obsNo); set sashelp.class; obsNo=_n_; if mod(_n_,3)=0 then output small; if _n_ LE 8 or _n_ GT 14 then output Large; run; proc print data=small;run; proc print data=large;run; Data LeftJoin;/*PUT LARGE FILE IN HASH OBJECT*/ if 0 then set large; /**/ /*load the small file into the hash object 2^4 buckets*/ if _n_=1 then do; /*load the hash table once*/ declare hash HO_Large(dataset:"work.large" ,hashexp: 4 ); rc= HO_Large.defineKey( "name" ); rc= HO_Large.defineData("name","Sex", "Height", "Weight"); rc= HO_Large.defineDone(); end; do until (eof); set Small end=eof; rc=HO_Large.find(); if RC=0 then MatchFlag="Match "; Else MatchFlag="No Match"; output; end; stop; /*We only need one pass through the data step*/ run; proc print data=leftJoin; run; 392 1 ø252 3 HashingInnerJoinLookup 1 332 1 38 /**Hashing as an inner join**/ /*Courtesy of Paul Dorfmann*/ /*http://www2.sas.com/proceedings/sugi31/241-31.pdf*/ /*http://www.nesug.org/Proceedings/nesug05/cc/ccx3.pdf*/ data Small(keep=name age obsno) Large(drop=age obsNo); set sashelp.class; obsNo=_n_; if mod(_n_,3)=0 then output small; if _n_ LE 8 or _n_ GT 14 then output Large; run; proc print data=small;run; proc print data=large;run; /*Using hashing to create an output like an inner join*/ Data InnerJoin; if 0 then set Small; /**/ /*load the small file into the hash object 2^4 buckets*/ if _n_=1 then do; /*load the hash table once*/ declare hash HO_Small(dataset:"work.small" ,hashexp: 4 ); rc= HO_Small.defineKey( "name" ); rc= HO_Small.defineData("name","age", "ObsNo"); rc= HO_Small.defineDone(); end; do until (eof); set large end=eof; rc=HO_Small.find(); if (rc=0) then output; end; run; proc print data=innerJoin; run; 387 1 /252 3 HashLookup 1 332 1 61 /************************************************************************** Section:HASHING http://www2.sas.com/proceedings/sugi30/236-30.pdf http://analytics.ncsu.edu/sesug/2006/SC19_06.PDF http://www.nesug.info/Proceedings/nesug06/dm/da07.pdf http://www.basug.org/downloads/2007q2/Guidelines.ppt#258,2,Join Techniques http://www.sas.com/offices/NA/canada/newsletter/insights/sep05/SAS9_Features_Function.pdf http://www.nesug.info/Proceedings/nesug05/cc/ccx3.pdf ***************************************************************************/ data GetInfo; infile datalines; input @1 name $char8. @10 Runner $char1.; datalines; Alfred Y RUSS N Janet N Ed Y Chris Y Elmo Y Jeffrey N Mary Y Wally N ; run; proc print data=sashelp.class; run; data DataLookedUp; if _n_=0 then set GetINfo; array Cbig(1) $ sex; array Nbig(3) age height weight; if _n_=1 then do; declare hash MyHashTable(dataset: "work.GetInfo", hashexp:4); rc=MyHashTable.DefineKey("name"); if rc NE 0 then put "problem with keys"; else put "keys OK"; rc=MyHashTable.DefineData("name","Runner"); if rc NE 0 then put "problem with data"; else put "data OK"; rc=MyHashTable.definedone(); end; set sashelp.class; rc=MyHashTable.find(); *if (rc=0) then output; If rc NE 0 then do; do i=1 to dim(Cbig); Cbig(i)=""; end; do i=1 to dim(Nbig); Nbig(i)=.; end; end; run; proc print data=DataLookedUp; run; 365 1 Ú 252 3 hbound( 1 332 1 93 /*array Lbound Hbound Dim _temporary_*/ /* this example is weak on multi-dimensional arrays - DIM always returns a total count of the number of elements in an array dimension. HBOUND returns the literal value of the upper bound of an array dimension. The LBOUND function returns the lower bound of a one-dimensional array or the lower bound of a specified dimension of a multidimensional array. temporaty arrays are faster than "regular" arrays*/ data ClassCount; retain age1-age20 /*temp arrays are automatically retianed*/; set sashelp.class end=EOF; array BigAgCt(0:25) _temporary_; array SmlAgCt(20) age1-age20; /*Initialize*/ if _n_=1 then Do; Do S=Lbound(SmlAgCt) to Hbound(SmlAgCt); SmlAgCt(S)=0; put "initializing" S=; end; Do B=Lbound(BigAgCt) to Hbound(BigAgCt); BigAgCt(B)=0; End; End; /*Count students in ages*/ SmlAgCt(age)=SmlAgCt(age)+1 ; put "Loading " age= SmlAgCt(age)= ; /* Count students in ages*/ BigAgCt(age)=BigAgCt(age)+1 ; if EOF=1 then do loopS= Lbound(SmlAgCt) to Hbound(SmlAgCt) ; put "Printing values from the small array: " LoopS= "and the value is " SmlAgCt(LoopS); end; do loopB= Lbound(BigAgCt) to Hbound(BigAgCt) ; put "Printing values from the UntRetained array: " LoopB= "and the value is " BigAgCt(LoopB); end; run; /*Dim*/ /*In this example, DIM returns a value of 5. Therefore, SAS repeats the statements in the DO loop five times. */ data _null_; array big{5} weight sex height state city; do i=1 to dim(big); Put "the value is" Bif(i); end; run; /*Examples of arrays*/ data text; /*Character arrays*/ array names{*} $ n1-n10; array capitals{*} $ c1-c10; input names{*}; do i=1 to 10; capitals{i}=upcase(names{i}); end; datalines; smithers michaels gonzalez hurth frank bleigh rounder joseph peters sam ; /*To create a temporary array, use the _TEMPORARY_ argument. The following example creates a temporary array named TEST: */ options nodate pageno=1 linesize=80 pagesize=60; data score2(drop=i); /*array test{3} t1-t3 (90 80 70);*/ /*Perm array and assign initial values*/ array test{3} _temporary_ (90 80 70); /*Temp array and assign initial values*/ array score{3} s1-s3; input id score{*}; do i=1 to 3; if score{i}>=test{i} then do; NewScore=score{i}; output; end; end; datalines; 1234 99 60 82 5678 80 85 75 ; proc print noobs data=score2; title 'Data Set SCORE2'; run; 2 1 O252 3 hms( 1 332 1 1 hms( numericHour , numericMinute , numericSecond ) 121 1 7252 3 hour( 1 332 1 1 hour(sasDateTime|sasTime) 122 1 252 3 ifc( 1 332 1 1 ifC( logicalExpression , valueReturnedWhenTrue, valueReturnedWhenFalse< , valueReturnedWhenMissing> ) 65 1 252 3 ifn( 1 332 1 1 ifN( logicalExpression , valueReturnedWhenTrue, valueReturnedWhenFalse< , valueReturnedWhenMissing> ) 66 1  252 3 index( 1 332 1 91 /* Might be better to use one of the find functions (find findc findw) find functions seem to be more powerful The INDEX function searches source, from left to right, for the first occurrence OF THE STRING specified in excerpt, and returns the position in source of the string's first character. If the string is not found in source, INDEX returns a value of 0. If there are multiple occurrences of the string, INDEX returns only the position of the first occurrence. The INDEXC function searches source, from left to right, for the first occurrence of ANY character present in the excerpts and returns the position in source of that character. If none of the characters in excerpt-1 through excerpt-n in source are found, INDEXC returns a value of 0. The INDEXW function searches for sTRINGS THAT ARE WORDS, whereas the INDEX function searches for patterns as separate words or as parts of other words. INDEXC searches for any characters that are present in the excerpts. */ data _null_; a='ABC.DEF (X=Y)'; b='X=Y'; x_Index=index(a,b); put "x_Index=index(a,b);"; put a= b= x_index=; put ; a='ABC.DEP (X2=Y1)'; x_Indexc1=indexc(a,'0123',';()=.'); put "x_Indexc1=indexc(a,'0123',';()=.');"; put a= x_Indexc1; put ; b='have a good day'; x_Indexc2=indexc(b,'pleasant','very'); put "x_Indexc2=indexc(b,'pleasant','very');"; put b= x_Indexc2=; put; s='asdf adog dog'; p='dog '; x_IndexW1=indexw(s,p); put "x_IndexW1=indexw(s,p);"; put s= a= x_IndexW1=; put ; s='abcdef x=y'; p='def'; x_IndexW2=indexw(s,p); put "x_IndexW2=indexw(s,p);"; put s= p= x_IndexW2=; put ; x="abc,def@ xyz"; abc_IndexW3=indexw(x, " abc ", "@"); put /* "bc_IndexW3=indexw(x, " abc ", "@%%);*/; put X= abc_IndexW3=; put ; x="abc,def@ xyz"; CommaIndexW=indexw(x, ",", "@"); put 'CommaIndexW=indexw(x, ",", "@");'; put X= CommaIndexW=; put ; x="abc,def% xyz"; DefIndexW=indexw(x, "def", "%"); put 'DefIndexW=indexw(x, "def", "%");'; put x= DefIndexW=; put ; x="abc,def@ xyz"; AtIndexW=indexw(x, "@", "@"); put 'AtIndexW=indexw(x, "@", "@");'; put x= AtIndexW=; put ; x="abc,def@ xyz"; xyzIndexW=indexw(x, " xyz", "@"); put 'xyzIndexW=indexw(x, " xyz", "@");'; put X= xyzIndexW=; put ""; CIndexWTrim=indexw(trimn(' '), ' '); put "CIndexWTrim=indexw(trimn(' '), ' ');"; put CIndexWTrim=; put ; gIndexW=indexw(' x y ', trimn(' ')); put "gIndexW=indexw(' x y ', trimn(' '));"; put gIndexW=; put; run; 67 1  252 3 indexc( 1 332 1 91 /* Might be better to use one of the find functions (find findc findw) find functions seem to be more powerful The INDEX function searches source, from left to right, for the first occurrence OF THE STRING specified in excerpt, and returns the position in source of the string's first character. If the string is not found in source, INDEX returns a value of 0. If there are multiple occurrences of the string, INDEX returns only the position of the first occurrence. The INDEXC function searches source, from left to right, for the first occurrence of ANY character present in the excerpts and returns the position in source of that character. If none of the characters in excerpt-1 through excerpt-n in source are found, INDEXC returns a value of 0. The INDEXW function searches for sTRINGS THAT ARE WORDS, whereas the INDEX function searches for patterns as separate words or as parts of other words. INDEXC searches for any characters that are present in the excerpts. */ data _null_; a='ABC.DEF (X=Y)'; b='X=Y'; x_Index=index(a,b); put "x_Index=index(a,b);"; put a= b= x_index=; put ; a='ABC.DEP (X2=Y1)'; x_Indexc1=indexc(a,'0123',';()=.'); put "x_Indexc1=indexc(a,'0123',';()=.');"; put a= x_Indexc1; put ; b='have a good day'; x_Indexc2=indexc(b,'pleasant','very'); put "x_Indexc2=indexc(b,'pleasant','very');"; put b= x_Indexc2=; put; s='asdf adog dog'; p='dog '; x_IndexW1=indexw(s,p); put "x_IndexW1=indexw(s,p);"; put s= a= x_IndexW1=; put ; s='abcdef x=y'; p='def'; x_IndexW2=indexw(s,p); put "x_IndexW2=indexw(s,p);"; put s= p= x_IndexW2=; put ; x="abc,def@ xyz"; abc_IndexW3=indexw(x, " abc ", "@"); put /* "bc_IndexW3=indexw(x, " abc ", "@%%);*/; put X= abc_IndexW3=; put ; x="abc,def@ xyz"; CommaIndexW=indexw(x, ",", "@"); put 'CommaIndexW=indexw(x, ",", "@");'; put X= CommaIndexW=; put ; x="abc,def% xyz"; DefIndexW=indexw(x, "def", "%"); put 'DefIndexW=indexw(x, "def", "%");'; put x= DefIndexW=; put ; x="abc,def@ xyz"; AtIndexW=indexw(x, "@", "@"); put 'AtIndexW=indexw(x, "@", "@");'; put x= AtIndexW=; put ; x="abc,def@ xyz"; xyzIndexW=indexw(x, " xyz", "@"); put 'xyzIndexW=indexw(x, " xyz", "@");'; put X= xyzIndexW=; put ""; CIndexWTrim=indexw(trimn(' '), ' '); put "CIndexWTrim=indexw(trimn(' '), ' ');"; put CIndexWTrim=; put ; gIndexW=indexw(' x y ', trimn(' ')); put "gIndexW=indexw(' x y ', trimn(' '));"; put gIndexW=; put; run; 68 1  252 3 indexw( 1 332 1 91 /* Might be better to use one of the find functions (find findc findw) find functions seem to be more powerful The INDEX function searches source, from left to right, for the first occurrence OF THE STRING specified in excerpt, and returns the position in source of the string's first character. If the string is not found in source, INDEX returns a value of 0. If there are multiple occurrences of the string, INDEX returns only the position of the first occurrence. The INDEXC function searches source, from left to right, for the first occurrence of ANY character present in the excerpts and returns the position in source of that character. If none of the characters in excerpt-1 through excerpt-n in source are found, INDEXC returns a value of 0. The INDEXW function searches for sTRINGS THAT ARE WORDS, whereas the INDEX function searches for patterns as separate words or as parts of other words. INDEXC searches for any characters that are present in the excerpts. */ data _null_; a='ABC.DEF (X=Y)'; b='X=Y'; x_Index=index(a,b); put "x_Index=index(a,b);"; put a= b= x_index=; put ; a='ABC.DEP (X2=Y1)'; x_Indexc1=indexc(a,'0123',';()=.'); put "x_Indexc1=indexc(a,'0123',';()=.');"; put a= x_Indexc1; put ; b='have a good day'; x_Indexc2=indexc(b,'pleasant','very'); put "x_Indexc2=indexc(b,'pleasant','very');"; put b= x_Indexc2=; put; s='asdf adog dog'; p='dog '; x_IndexW1=indexw(s,p); put "x_IndexW1=indexw(s,p);"; put s= a= x_IndexW1=; put ; s='abcdef x=y'; p='def'; x_IndexW2=indexw(s,p); put "x_IndexW2=indexw(s,p);"; put s= p= x_IndexW2=; put ; x="abc,def@ xyz"; abc_IndexW3=indexw(x, " abc ", "@"); put /* "bc_IndexW3=indexw(x, " abc ", "@%%);*/; put X= abc_IndexW3=; put ; x="abc,def@ xyz"; CommaIndexW=indexw(x, ",", "@"); put 'CommaIndexW=indexw(x, ",", "@");'; put X= CommaIndexW=; put ; x="abc,def% xyz"; DefIndexW=indexw(x, "def", "%"); put 'DefIndexW=indexw(x, "def", "%");'; put x= DefIndexW=; put ; x="abc,def@ xyz"; AtIndexW=indexw(x, "@", "@"); put 'AtIndexW=indexw(x, "@", "@");'; put x= AtIndexW=; put ; x="abc,def@ xyz"; xyzIndexW=indexw(x, " xyz", "@"); put 'xyzIndexW=indexw(x, " xyz", "@");'; put X= xyzIndexW=; put ""; CIndexWTrim=indexw(trimn(' '), ' '); put "CIndexWTrim=indexw(trimn(' '), ' ');"; put CIndexWTrim=; put ; gIndexW=indexw(' x y ', trimn(' ')); put "gIndexW=indexw(' x y ', trimn(' '));"; put gIndexW=; put; run; 69 1 •252 3 inputc( 1 332 1 143 /*INPUTC INPUTN Putc PutN Enables you to specify a character informat at run time. INPUTC(source, informat<,w>) source specifies a character constant, variable, or expression to which you want to apply the informat. informat is a character constant, variable, or expression that contains the character informat you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the informat. Interaction: If you specify a width here, it overrides any width specification in the informat. Using the INPUT function is faster because you specify the informat at compile time.*/ proc format; value typefmt 1='$groupx' 2='$groupy' 3='$groupz'; invalue $groupx 'positive'='agree' 'negative'='disagree' 'neutral'='notsure'; invalue $groupy 'positive'='accept' 'negative'='reject' 'neutral'='possible'; invalue $groupz 'positive'='pass' 'negative'='fail' 'neutral'='retest'; run; /*one file has several different types of tests*/ data TestValues; input MedTest response $; respinformat = put(MedTest, typefmt.); word = inputc(response, respinformat); datalines; 1 positive 1 negative 1 neutral 2 positive 2 negative 2 neutral 3 positive 3 negative 3 neutral ; run; proc print data=TestValues; run; /*INPUTN Function INPUTN(source, informat<,w<,d>>) Enables you to specify a numeric informat at run time. INPUTN(source, informat<,w<,d>>) source specifies a character constant, variable, or expression to which you want to apply the informat. informat is a character constant, variable or expression that contains the numeric informat you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the informat. Interaction: If you specify a width here, it overrides any width specification in the informat. d is a numeric constant, variable, or expression that specifies the number of decimal places to use. Interaction: If you specify a number here, it overrides any decimal-place specification in the informat. */ proc format; value readdate 1='date7.' 2='mmddyy8.'; run; options yearcutoff=1920; data fixdates (drop=start dateinformat); length jobdesc $12; input source id lname $ jobdesc $ start $; dateinformat=put(source, readdate.); newdate = inputn(start, dateinformat); datalines; 1 1604 Ziminski writer 09aug90 1 2010 Clavell editor 26jan95 2 1833 Rivera writer 10/25/92 2 2222 Barnes proofreader 3/26/98 ; proc print data=fixdates; run; /* PUTC Function PUTC(source, format.<,w>) Enables you to specify a character format at run time. source specifies a character constant, variable, or expression to which you want to apply the format. format. is a character constant, variable, or expression with a value that is the character format you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the format. Interaction: If you specify a width here, it overrides any width specification in the format. */ proc format; value typefmt 1='$groupx' 2='$groupy' 3='$groupz'; value $groupx 'positive'='agree' 'negative'='disagree' 'neutral'='notsure '; value $groupy 'positive'='accept' 'negative'='reject' 'neutral'='possible'; value $groupz 'positive'='pass ' 'negative'='fail' 'neutral'='retest'; run; data answers; length word $ 8; input type response $; respfmt = put(type, typefmt.); word = putc(response, respfmt); datalines; 1 positive 1 negative 1 neutral 2 positive 2 negative 2 neutral 3 positive 3 negative 3 neutral ; proc print data=answers; run; /* PUTN Function PUTN(source, format.<,w<,d>>) Enables you to specify a numeric format at run time. source specifies a numeric constant, variable, or expression to which you want to apply the format. format. is a character constant, variable, or expression with a value that is the numeric format you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the format. Interaction: If you specify a width here, it overrides any width specification in the format. d is a numeric constant, variable, or expression that specifies the number of decimal places to use. Interaction: If you specify a number here, it overrides any decimal-place specification in the format. */ proc format; value writfmt 1='date9.' 2='mmddyy10.'; run; data dates; input number key; datefmt=put(key,writfmt.); date=putn(number,datefmt); datalines; 15756 1 14552 2 ; proc print data=dates;run; 210 1 •252 3 inputn( 1 332 1 143 /*INPUTC INPUTN Putc PutN Enables you to specify a character informat at run time. INPUTC(source, informat<,w>) source specifies a character constant, variable, or expression to which you want to apply the informat. informat is a character constant, variable, or expression that contains the character informat you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the informat. Interaction: If you specify a width here, it overrides any width specification in the informat. Using the INPUT function is faster because you specify the informat at compile time.*/ proc format; value typefmt 1='$groupx' 2='$groupy' 3='$groupz'; invalue $groupx 'positive'='agree' 'negative'='disagree' 'neutral'='notsure'; invalue $groupy 'positive'='accept' 'negative'='reject' 'neutral'='possible'; invalue $groupz 'positive'='pass' 'negative'='fail' 'neutral'='retest'; run; /*one file has several different types of tests*/ data TestValues; input MedTest response $; respinformat = put(MedTest, typefmt.); word = inputc(response, respinformat); datalines; 1 positive 1 negative 1 neutral 2 positive 2 negative 2 neutral 3 positive 3 negative 3 neutral ; run; proc print data=TestValues; run; /*INPUTN Function INPUTN(source, informat<,w<,d>>) Enables you to specify a numeric informat at run time. INPUTN(source, informat<,w<,d>>) source specifies a character constant, variable, or expression to which you want to apply the informat. informat is a character constant, variable or expression that contains the numeric informat you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the informat. Interaction: If you specify a width here, it overrides any width specification in the informat. d is a numeric constant, variable, or expression that specifies the number of decimal places to use. Interaction: If you specify a number here, it overrides any decimal-place specification in the informat. */ proc format; value readdate 1='date7.' 2='mmddyy8.'; run; options yearcutoff=1920; data fixdates (drop=start dateinformat); length jobdesc $12; input source id lname $ jobdesc $ start $; dateinformat=put(source, readdate.); newdate = inputn(start, dateinformat); datalines; 1 1604 Ziminski writer 09aug90 1 2010 Clavell editor 26jan95 2 1833 Rivera writer 10/25/92 2 2222 Barnes proofreader 3/26/98 ; proc print data=fixdates; run; /* PUTC Function PUTC(source, format.<,w>) Enables you to specify a character format at run time. source specifies a character constant, variable, or expression to which you want to apply the format. format. is a character constant, variable, or expression with a value that is the character format you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the format. Interaction: If you specify a width here, it overrides any width specification in the format. */ proc format; value typefmt 1='$groupx' 2='$groupy' 3='$groupz'; value $groupx 'positive'='agree' 'negative'='disagree' 'neutral'='notsure '; value $groupy 'positive'='accept' 'negative'='reject' 'neutral'='possible'; value $groupz 'positive'='pass ' 'negative'='fail' 'neutral'='retest'; run; data answers; length word $ 8; input type response $; respfmt = put(type, typefmt.); word = putc(response, respfmt); datalines; 1 positive 1 negative 1 neutral 2 positive 2 negative 2 neutral 3 positive 3 negative 3 neutral ; proc print data=answers; run; /* PUTN Function PUTN(source, format.<,w<,d>>) Enables you to specify a numeric format at run time. source specifies a numeric constant, variable, or expression to which you want to apply the format. format. is a character constant, variable, or expression with a value that is the numeric format you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the format. Interaction: If you specify a width here, it overrides any width specification in the format. d is a numeric constant, variable, or expression that specifies the number of decimal places to use. Interaction: If you specify a number here, it overrides any decimal-place specification in the format. */ proc format; value writfmt 1='date9.' 2='mmddyy10.'; run; data dates; input number key; datefmt=put(key,writfmt.); date=putn(number,datefmt); datalines; 15756 1 14552 2 ; proc print data=dates;run; 266 1 252 3 int( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 320 1 '252 3 intck( 1 332 1 123 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ /* Pretty dates all in a row Dianne Rhodes For my reports, which I usually run on Monday, I want to find last Friday’s date. The Week interval starts with Sunday, so Friday is week.6. ReportDate= intnx(‘week.6’, today(),0) The Start Date of the period will be the Saturday of the week before StartDate = intnx(‘week.7’, ReportDate, 0) http://www2.sas.com/proceedings/sugi30/055-30.pdf*/ /* INTNX('interval', start,from , increment, <,alignment>) INTCK('interval',from_date, to_date)*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ This_Day_Time=DateTime(); /*Reads system clock*/ A_date_part=DatePart(This_Day_Time); A_time_part=TimePart(This_Day_Time); ThisTime=time(); put TodayDate= TodayToday= ; put This_Day_Time= A_date_part= A_time_part=; put ThisTime= ; break=repeat("*",40); put / break /; put"The DAY function produces an integer from 1 to 31 that represents the day of the month."; Bday='05may97'd; DOM_BDay=day(Bday); TodayDate=today(); DOM_TodayDate=day(TodayDate); put Bday= DOM_BDay= TodayDate= DOM_TodayDate= ; break=repeat("*",40); put / break; thisInstant=DateTime(); DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put DayFromDateTime= ThisInstant=; TimeFromDateTime=TimePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put TimeFromDateTime= ThisInstant=; break=repeat("*",15)||" MDY "||repeat("*",15); put / break /; put"The MDY function converts MONTH, DAY, and YEAR values to a SAS date value." ; put "For example, MDY(01,21,2010) returns the SAS date value for 21Jan2010 "; month=01; day=21; year=2010; DateFromNum=MDY(month,day,year); Put DateFromNum= DateFromNum= yymmdd10.; *MDY When month, day, and year are char; Cmonth="01"; Cday ="05"; Cyear ="2010"; DateFromChar=MDY(input(Cmonth,2.),input(Cday,2.),input(Cyear,4.)); Put DateFromChar= DateFromChar= yymmdd10.; break=repeat("*",15)||" INTCK "||repeat("*",15); put / break /; /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; break=repeat("*",15)||" INTNX "||repeat("*",15); put / break /; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; string="Aligning a date to prev or following Friday"; DASH = REPEAT("-",length(string) - 1); PUT /DASH/ STRING / DASH; *Align to friday of previous week; TheDate=today(); PrevFriday= intnx('week.6', today(),0); put TheDate= EURDFWKX21. PrevFriday= EURDFWKX21.; *what if the date IS a friday and we want to align to that date; AFriday=20692; put /"What if the date IS already a friday?"; AlignedFriday= intnx('week.6', AFriday,0); put AFriday= EURDFWKX21. AlignedFriday= EURDFWKX21.; *align to next friday; TheDate=today(); NextFriday= intnx('week.6', today(),+1); put /TheDate= EURDFWKX21. NextFriday= EURDFWKX21.; run; 123 1 '252 3 intnx( 1 332 1 123 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ /* Pretty dates all in a row Dianne Rhodes For my reports, which I usually run on Monday, I want to find last Friday’s date. The Week interval starts with Sunday, so Friday is week.6. ReportDate= intnx(‘week.6’, today(),0) The Start Date of the period will be the Saturday of the week before StartDate = intnx(‘week.7’, ReportDate, 0) http://www2.sas.com/proceedings/sugi30/055-30.pdf*/ /* INTNX('interval', start,from , increment, <,alignment>) INTCK('interval',from_date, to_date)*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ This_Day_Time=DateTime(); /*Reads system clock*/ A_date_part=DatePart(This_Day_Time); A_time_part=TimePart(This_Day_Time); ThisTime=time(); put TodayDate= TodayToday= ; put This_Day_Time= A_date_part= A_time_part=; put ThisTime= ; break=repeat("*",40); put / break /; put"The DAY function produces an integer from 1 to 31 that represents the day of the month."; Bday='05may97'd; DOM_BDay=day(Bday); TodayDate=today(); DOM_TodayDate=day(TodayDate); put Bday= DOM_BDay= TodayDate= DOM_TodayDate= ; break=repeat("*",40); put / break; thisInstant=DateTime(); DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put DayFromDateTime= ThisInstant=; TimeFromDateTime=TimePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put TimeFromDateTime= ThisInstant=; break=repeat("*",15)||" MDY "||repeat("*",15); put / break /; put"The MDY function converts MONTH, DAY, and YEAR values to a SAS date value." ; put "For example, MDY(01,21,2010) returns the SAS date value for 21Jan2010 "; month=01; day=21; year=2010; DateFromNum=MDY(month,day,year); Put DateFromNum= DateFromNum= yymmdd10.; *MDY When month, day, and year are char; Cmonth="01"; Cday ="05"; Cyear ="2010"; DateFromChar=MDY(input(Cmonth,2.),input(Cday,2.),input(Cyear,4.)); Put DateFromChar= DateFromChar= yymmdd10.; break=repeat("*",15)||" INTCK "||repeat("*",15); put / break /; /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; break=repeat("*",15)||" INTNX "||repeat("*",15); put / break /; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; string="Aligning a date to prev or following Friday"; DASH = REPEAT("-",length(string) - 1); PUT /DASH/ STRING / DASH; *Align to friday of previous week; TheDate=today(); PrevFriday= intnx('week.6', today(),0); put TheDate= EURDFWKX21. PrevFriday= EURDFWKX21.; *what if the date IS a friday and we want to align to that date; AFriday=20692; put /"What if the date IS already a friday?"; AlignedFriday= intnx('week.6', AFriday,0); put AFriday= EURDFWKX21. AlignedFriday= EURDFWKX21.; *align to next friday; TheDate=today(); NextFriday= intnx('week.6', today(),+1); put /TheDate= EURDFWKX21. NextFriday= EURDFWKX21.; run; 124 1 *252 3 intz( 1 332 1 1 intZ(number) 321 1 `252 3 IORC_Lookup 1 332 1 44 /************************************************************************** Section: IORC LOOKUP http://www.lexjansen.com/pharmasug/2003/tutorials/tu054.pdf http://www.nesug.info/Proceedings/nesug04/pm/pm18.pdf ; http://www.valsug.org/Meetings/20030311/lookuptechniques.ppt http://sausag.sasusers.net/presentations/0511GettingValueFromIndexing.ppt http://www.units.muohio.edu/doc/sassystem/sugi25/23/Dataware/p92.pdf http://www2.sas.com/proceedings/sugi25/25/po/25p234.pdf ***************************************************************************/ data GetInfo; infile datalines; input @1 name $char8.; datalines; Alfred RUSS Janet CHRIS Elmo Jeffrey Ed Mary Wally ; run; data BigFile(index=(name /unique)); set sashelp.class; ; run; data DataLookedUp; set GetINfo; Array BigChar(1) $ Sex; Array BigNum(3) age height weight; set BigFile key=name /unique; if _IORC_ NE 0 then do; _error_=0; _iorc_=0; do I=1 to dim(BigChar); BigChar(i)=""; end; do J=1 to dim(BigNum); BigNum(j)="."; end; end; run; 366 1 1252 3 juldate( 1 332 1 1 julDate(sasDate) 125 1 3252 3 juldate7( 1 332 1 1 julDate7(sasDate) 126 1 p252 3 kcompare( 1 332 1 1 kCompare( stringToSearch ,< startPosition ,< bytesToCompare ,>> stringToFind ) 143 1 N252 3 kcompress( 1 332 1 1 kCompress( string< , charactersToRremove> ) 144 1 .252 3 kcount( 1 332 1 1 kCount(string) 145 1 ?252 3 kindex( 1 332 1 1 kIndex( string , searchString ) 147 1 [252 3 kindexc( 1 332 1 1 kIndexC( string , characterList1< , characterList2<...>> ) 148 1 3252 3 kleft( 1 332 1 1 kleft( kLeft(string) 149 1 0252 3 klength( 1 332 1 1 kLength(string) 150 1 2252 3 klowcase( 1 332 1 1 kLowCase(string) 151 1 2252 3 kreverse( 1 332 1 1 kReverse(string) 152 1 .252 3 kright( 1 332 1 1 kRight(string) 153 1 J252 3 kscan( 1 332 1 1 kScan( string , wordNumber< , delimiters> ) 154 1 N252 3 kstrcat( 1 332 1 1 kStrCat( string1 , string2< , string3<...>> ) 155 1 Z252 3 ksubstr( 1 332 1 1 kSubstr( string , characterPosition< , characterLength> ) 156 1 R252 3 ksubstrb( 1 332 1 1 kSubstrB( string , bytePosition< , byteLength> ) 157 1 [252 3 ktranslate( 1 332 1 1 kTranslate( string , to1 , from1< , to2 , from2<...>> ) 158 1 ,252 3 ktrim( 1 332 1 1 kTrim(string) 159 1 H252 3 ktruncate( 1 332 1 1 kTruncate( string , number , length ) 160 1 0252 3 kupcase( 1 332 1 1 kUpCase(string) 161 1 ¿252 3 kupdate( 1 332 1 1 kUpdate( string , characterPosition , characterLength<, charactersToReplace> )|kUpdate( string , characterPosition <, characterLength> , charactersToReplace ) 162 1 ®252 3 kupdateb( 1 332 1 1 kUpdateB( string , bytePosition , byteLength<, charactersToReplace> )|kUpdate( string , bytePosition <, byteLength> , charactersToReplace )) 163 1 F252 3 kurtosis( 1 332 1 1 kurtosis( number1< , number2<...>> ) 172 1 O252 3 kverify( 1 332 1 1 kVerify( string , excerpt1< , excerpt2<...>> ) 164 1 I252 3 largest( 1 332 1 1 largest( k , number1< , number2<...>> ) 173 1 Û 252 3 lbound( 1 332 1 93 /*array Lbound Hbound Dim _temporary_*/ /* this example is weak on multi-dimensional arrays - DIM always returns a total count of the number of elements in an array dimension. HBOUND returns the literal value of the upper bound of an array dimension. The LBOUND function returns the lower bound of a one-dimensional array or the lower bound of a specified dimension of a multidimensional array. temporaty arrays are faster than "regular" arrays*/ data ClassCount; retain age1-age20 /*temp arrays are automatically retianed*/; set sashelp.class end=EOF; array BigAgCt(0:25) _temporary_; array SmlAgCt(20) age1-age20; /*Initialize*/ if _n_=1 then Do; Do S=Lbound(SmlAgCt) to Hbound(SmlAgCt); SmlAgCt(S)=0; put "initializing" S=; end; Do B=Lbound(BigAgCt) to Hbound(BigAgCt); BigAgCt(B)=0; End; End; /*Count students in ages*/ SmlAgCt(age)=SmlAgCt(age)+1 ; put "Loading " age= SmlAgCt(age)= ; /* Count students in ages*/ BigAgCt(age)=BigAgCt(age)+1 ; if EOF=1 then do loopS= Lbound(SmlAgCt) to Hbound(SmlAgCt) ; put "Printing values from the small array: " LoopS= "and the value is " SmlAgCt(LoopS); end; do loopB= Lbound(BigAgCt) to Hbound(BigAgCt) ; put "Printing values from the UntRetained array: " LoopB= "and the value is " BigAgCt(LoopB); end; run; /*Dim*/ /*In this example, DIM returns a value of 5. Therefore, SAS repeats the statements in the DO loop five times. */ data _null_; array big{5} weight sex height state city; do i=1 to dim(big); Put "the value is" Bif(i); end; run; /*Examples of arrays*/ data text; /*Character arrays*/ array names{*} $ n1-n10; array capitals{*} $ c1-c10; input names{*}; do i=1 to 10; capitals{i}=upcase(names{i}); end; datalines; smithers michaels gonzalez hurth frank bleigh rounder joseph peters sam ; /*To create a temporary array, use the _TEMPORARY_ argument. The following example creates a temporary array named TEST: */ options nodate pageno=1 linesize=80 pagesize=60; data score2(drop=i); /*array test{3} t1-t3 (90 80 70);*/ /*Perm array and assign initial values*/ array test{3} _temporary_ (90 80 70); /*Temp array and assign initial values*/ array score{3} s1-s3; input id score{*}; do i=1 to 3; if score{i}>=test{i} then do; NewScore=score{i}; output; end; end; datalines; 1234 99 60 82 5678 80 85 75 ; proc print noobs data=score2; title 'Data Set SCORE2'; run; 23 1 Š252 3 lcase( 1 332 1 7 /*UpCase( LCase( */ data _null_; x="this IS 1 instance"; Y=upcase(X); z=LCase(X); put x= y= z=; run; 277 1 Ñ252 3 left( 1 332 1 10 left(string) Left-aligns a character string. data _null_; X="now is the "; Y=" Time for all good men "; Z1=x||Y; Z2=x||Left(Y); put X= Y= Z1=; put X= Y= Z2=; run; 70 1 š252 3 length( 1 332 1 10 length(string) Returns the length of a non-blank character string, excluding trailing blanks, and returns 1 for a blank character string. data _null_; /* 12345678901234567890123456789012345678901234567890*/ target=" Now is the time for all good men "; HowLong=length(target); put "note how the put statement left aligns "; put howlong= target=; run; 71 1 /252 3 lengthc( 1 332 1 1 lengthC(string) 72 1 /252 3 lengthm( 1 332 1 1 lengthM(string) 73 1 /252 3 lengthn( 1 332 1 1 lengthN(string) 74 1 6252 3 lgamma( 1 332 1 1 lGamma(positiveNumber) 229 1 0252 3 log( 1 332 1 1 log(positiveNumber) 230 1 4252 3 log10( 1 332 1 1 log10(positiveNumber) 231 1 2252 3 log2( 1 332 1 1 log2(positiveNumber) 232 1 9252 3 logbeta( 1 332 1 1 logBeta( shape , shape ) 233 1 A252 3 logcdf( 1 332 1 1 logCdf( 'Bernoulli|beta|binomial|Cauchy|chiSquare|exponential|F|gamma|geometric|hyperGeometric|LaPlace|logistic|logNormal|negBinomial|normal|Gauss|normalMix|Pareto|Poissont|uniform|Wald|iGauss|Weibull' , quantile< , shapeLocationOrScaleParameter1< , shapeLocationOrScaleParameter2<...>>> ) 242 1 A252 3 logpdf( 1 332 1 1 logPdf( 'Bernoulli|beta|binomial|Cauchy|chiSquare|exponential|F|gamma|geometric|hyperGeometric|LaPlace|logistic|logNormal|negBinomial|normal|Gauss|normalMix|Pareto|Poissont|uniform|Wald|iGauss|Weibull' , quantile< , shapeLocationOrScaleParameter1< , shapeLocationOrScaleParameter2<...>>> ) 243 1 A252 3 logsdf( 1 332 1 1 logSdf( 'Bernoulli|beta|binomial|Cauchy|chiSquare|exponential|F|gamma|geometric|hyperGeometric|LaPlace|logistic|logNormal|negBinomial|normal|Gauss|normalMix|Pareto|Poissont|uniform|Wald|iGauss|Weibull' , quantile< , shapeLocationOrScaleParameter1< , shapeLocationOrScaleParameter2<...>>> ) 244 1 /252 3 lowcase( 1 332 1 1 lowCase(string) 75 1 <252 3 mad( 1 332 1 1 mad( number1< , number2<...>> ) 174 1 }252 3 MavenMergeWIndex 1 332 1 93 /**************************************************************** Section: 0- Create data sets *****************************************************************/ Options nocenter; Proc SQL; create table WantInfo ( SID Char(4) , Sex Char(1) ); insert into WantInfo values("0001","F") values("3999","F") values("2222","M") values("3134","F") /*values("6090","M")*/ values("7777","M"); proc print data=Wantinfo; title "Wantinfo"; run; Proc SQL; Create table SWantInfo as select * from WantINfo Order by SID; proc print data=swantinfo; title "swantinfo"; run; proc SQL; Create table BigLookIn (SID char(4) , ARM Char(1) ); insert into BigLookIn values("8811","A") values("9033","B") values("9099","A") values("2999","B") values("3453","A") values("3999","B") values("4444","A") values("4766","A") values("5020","B") values("0001","A") values("0099","B") values("1005","B") values("1087","B") values("2111","A") values("5111","A") values("6090","A") values("6888","B") values("7666","A") values("7777","B") values("8188","A"); /*Proc Print data=BigLookIn;*/ /*run;*/ Create table SBigLookIn as select * from BigLookIn order by SID; Create table SDupIn (SID char(4) , test Char(1) ); insert into SDupIn values("0001","N") /*match*/ values("2222","A") /*match*/ values("2222","N") /*match*/ values("2222","A") /*match*/ values("2999","N") values("3453","A") values("3453","N") values("3999","A"); /*match*/ quit; proc print data=SBigLookIn; title "SBigLookIn"; run; /**************************************************************** Section:__ Example 2 Maven merge WITH index on big file *****************************************************************/ Proc SQL; /*Create an index to help the data engine where clause optimizer*/ Create index SID on BigLookIn(SID); quit; options msglevel=i; data Example2;/*Use where and index to only read, from large, the obs in small*/ merge SWantInfo (in=s) BigLookIn (where=(SID in(&WhereCL))); by SID; if s; run; options nocenter; Proc Print data=ExaMPLE2; run; 368 1 ï 252 3 MavenMergeWOINdex 1 332 1 103 /**************************************************************** Section: 0- Create data sets *****************************************************************/ Options nocenter; Proc SQL; create table WantInfo ( SID Char(4) , Sex Char(1) ); insert into WantInfo values("0001","F") values("3999","F") values("2222","M") values("3134","F") /*values("6090","M")*/ values("7777","M"); proc print data=Wantinfo; title "Wantinfo"; run; Proc SQL; Create table SWantInfo as select * from WantINfo Order by SID; proc print data=swantinfo; title "swantinfo"; run; proc SQL; Create table BigLookIn (SID char(4) , ARM Char(1) ); insert into BigLookIn values("8811","A") values("9033","B") values("9099","A") values("2999","B") values("3453","A") values("3999","B") values("4444","A") values("4766","A") values("5020","B") values("0001","A") values("0099","B") values("1005","B") values("1087","B") values("2111","A") values("5111","A") values("6090","A") values("6888","B") values("7666","A") values("7777","B") values("8188","A"); /*Proc Print data=BigLookIn;*/ /*run;*/ Create table SBigLookIn as select * from BigLookIn order by SID; Create table SDupIn (SID char(4) , test Char(1) ); insert into SDupIn values("0001","N") /*match*/ values("2222","A") /*match*/ values("2222","N") /*match*/ values("2222","A") /*match*/ values("2999","N") values("3453","A") values("3453","N") values("3999","A"); /*match*/ quit; proc print data=SBigLookIn; title "SBigLookIn"; run; /**************************************************************** Section:__ Example 1 Maven merge w/o index *****************************************************************/ OPTIONS NOCENTER msglevel=i; proc sql noprint; /*the distinct de-dupes the where clause- duplicates not required for the where*/ select distinct(quote(SID)) into :WhereCL separated by ', ' from SWantInfo ; quit; %put &WhereCl; Proc SQL; /*Create an index to help the data engine where clause optimizer*/ Drop index SID on BigLookIn; quit; options msglevel=i mprint symbolgen mlogic; data Example1; /*no index created yet, so top to bottom processing of large, with where filtering in data engine*/ /*Use where and index to only read, from large, the obs in small*/ merge SWantInfo (in=s) /* SBigLookIn (where=(SID in(&WhereCl)));*/ SBigLookIn ; by SID; if s; run; Proc Print data=EXAMPLE1; run; 296 1 252 3 max( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 227 1 %252 3 mdy( 1 332 1 123 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ /* Pretty dates all in a row Dianne Rhodes For my reports, which I usually run on Monday, I want to find last Friday’s date. The Week interval starts with Sunday, so Friday is week.6. ReportDate= intnx(‘week.6’, today(),0) The Start Date of the period will be the Saturday of the week before StartDate = intnx(‘week.7’, ReportDate, 0) http://www2.sas.com/proceedings/sugi30/055-30.pdf*/ /* INTNX('interval', start,from , increment, <,alignment>) INTCK('interval',from_date, to_date)*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ This_Day_Time=DateTime(); /*Reads system clock*/ A_date_part=DatePart(This_Day_Time); A_time_part=TimePart(This_Day_Time); ThisTime=time(); put TodayDate= TodayToday= ; put This_Day_Time= A_date_part= A_time_part=; put ThisTime= ; break=repeat("*",40); put / break /; put"The DAY function produces an integer from 1 to 31 that represents the day of the month."; Bday='05may97'd; DOM_BDay=day(Bday); TodayDate=today(); DOM_TodayDate=day(TodayDate); put Bday= DOM_BDay= TodayDate= DOM_TodayDate= ; break=repeat("*",40); put / break; thisInstant=DateTime(); DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put DayFromDateTime= ThisInstant=; TimeFromDateTime=TimePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put TimeFromDateTime= ThisInstant=; break=repeat("*",15)||" MDY "||repeat("*",15); put / break /; put"The MDY function converts MONTH, DAY, and YEAR values to a SAS date value." ; put "For example, MDY(01,21,2010) returns the SAS date value for 21Jan2010 "; month=01; day=21; year=2010; DateFromNum=MDY(month,day,year); Put DateFromNum= DateFromNum= yymmdd10.; *MDY When month, day, and year are char; Cmonth="01"; Cday ="05"; Cyear ="2010"; DateFromChar=MDY(input(Cmonth,2.),input(Cday,2.),input(Cyear,4.)); Put DateFromChar= DateFromChar= yymmdd10.; break=repeat("*",15)||" INTCK "||repeat("*",15); put / break /; /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; break=repeat("*",15)||" INTNX "||repeat("*",15); put / break /; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; string="Aligning a date to prev or following Friday"; DASH = REPEAT("-",length(string) - 1); PUT /DASH/ STRING / DASH; *Align to friday of previous week; TheDate=today(); PrevFriday= intnx('week.6', today(),0); put TheDate= EURDFWKX21. PrevFriday= EURDFWKX21.; *what if the date IS a friday and we want to align to that date; AFriday=20692; put /"What if the date IS already a friday?"; AlignedFriday= intnx('week.6', AFriday,0); put AFriday= EURDFWKX21. AlignedFriday= EURDFWKX21.; *align to next friday; TheDate=today(); NextFriday= intnx('week.6', today(),+1); put /TheDate= EURDFWKX21. NextFriday= EURDFWKX21.; run; 127 1 !252 3 mean( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 176 1 #252 3 median( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 177 1 252 3 min( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 213 1 ;252 3 minute( 1 332 1 1 minute(sasDateTime|sasTime) 128 1 c252 3 missing( 1 332 1 20 /*Missing*/ data _null_; NumAndMissing =.; CharAndMissing =""; CharAndOneBlank=" "; NumAndValued =4; CharAndValued ="SAS Stat"; NumAndMissingYN =missing(NumAndMissing ); put NumAndMissing= NumAndMissingYN=; CharAndMissingYN =missing(CharAndMissing ); put CharAndMissing= CharAndMissingYN=; CharAndOneBlankYN =missing(CharAndOneBlank ); put CharAndOneBlank= CharAndOneBlankYN=; NumAndValuedYN =missing(NumAndValued ); put NumAndValued= NumAndValuedYN=; CharAndValuedYN =missing(CharAndValued); put CharAndValued= CharAndValuedYN=; ; run; 179 1 ;252 3 mod( 1 332 1 1 mod( numerator , denominator ) 234 1 d252 3 modulec( 1 332 1 1 moduleC( moduleName< , argument1< , argument2<...> ) 194 1 f252 3 moduleic( 1 332 1 1 moduleIC( moduleName< , argument1< , argument2<...> ) 195 1 f252 3 modulein( 1 332 1 1 moduleIN( moduleName< , argument1< , argument2<...> ) 196 1 d252 3 modulen( 1 332 1 1 moduleN( moduleName< , argument1< , argument2<...> ) 197 1 -252 3 month( 1 332 1 1 month(sasDate) 129 1 252 3 n( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 180 1 >252 3 nldate( 1 332 1 1 nlDate( sasDate , descriptor ) 130 1 B252 3 nldatm( 1 332 1 1 nlDatM( sasDateTime , descriptor ) 131 1 1252 3 nliteral( 1 332 1 1 nLiteral(string) 77 1 Y252 3 nltime( 1 332 1 1 nlTime(sasDateTime|sasTime , descriptor , startPosition ) 132 1 "252 3 nmiss( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 181 1 D252 3 normal( 1 332 1 41 /* it seems that the rand fucntion does it all NORMAL Function variate that is generated from a normal distribution with mean 0 and variance 1. x=RANNOR(seed) RANBIN Function Returns a random variate from a binomial distribution. RANCAU Function Returns a random variate from a Cauchy distribution. RANPOI(seed,m) x=RanPoi(seed,m) m is a numeric constant, variable, or expression that specifies the mean RANEXP Function Returns a random variate from an exponential distribution. RAND (dist, parm-1,...,parm-k) Generates random numbers from a distribution that you specify. Distribution Argument Bernoulli BERNOULLI Beta BETA Binomial BINOMIAL Cauchy CAUCHY Chi-Square CHISQUARE Erlang ERLANG Exponential EXPONENTIAL F F Gamma GAMMA Geometric GEOMETRIC Rannor( Lognormal LOGNORMAL Negative binomial NEGBINOMIAL Normal NORMAL|GAUSSIAN Poisson POISSON T T Tabled TABLE Triangular TRIANGLE Uniform UNIFORM Weibull WEIBULL RANUNI Function returns a number the uniform distribution on the interval (0,1) x=RANUNI(seed) ; If you want to change the seed value during execution, you must use the CALL RANUNI routine instead of the RANUNI function. UNIFORM See RanUNI */ 278 1 ş252 3 notalnum( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 78 1 ş252 3 notalpha( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 79 1 ş252 3 notcntrl( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 80 1 ş252 3 notdigit( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 81 1 ş252 3 notfirst( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 82 1 ş252 3 notgraph( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 83 1 ş252 3 notlower( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 84 1 ı252 3 notname( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 85 1 ş252 3 notprint( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 86 1 ş252 3 notpunct( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 87 1 ş252 3 notspace( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 88 1 ş252 3 notupper( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 89 1 ş252 3 notxdigit( 1 332 1 130 /*anyAlpha( string <, start >) Searches a character string for an alphabetic character, and returns the first position at which the character is found. AnyDigit Searches a character string for a digit, and returns the first position at which the digit is found. AnyName Searches a character string for a character that is valid in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. AnyPunct Searches a character string for a punctuation character, and returns the first position at which that character is found. AnySpace Searches a character string for: a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. AnyUpper Searches a character string for an uppercase letter, and returns the first position at which the letter is found. AnyLower Searches a character string for a lowercase letter, and returns the first position at which the letter is found. INDEX Searches a character expression for a string of characters, and returns the position of the string's first character for the first occurrence of the string. INDEXC Searches a character expression for any of the specified characters, and returns the position of that character. INDEXW Searches a character expression for a string that is specified as a word, and returns the position of the first character in the word. NOTALNUM Searches a character string for a non-alphanumeric character, and returns the first position at which the character is found. NOTALPHA Searches a character string for a nonalphabetic character, and returns the first position at which the character is found. NOTCNTRL Searches a character string for a character that is not a control character, and returns the first position at which that character is found. NOTDIGIT Searches a character string for any character that is not a digit, and returns the first position at which that character is found. NOTFIRST Searches a character string for an invalid first character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTGRAPH Searches a character string for a non-graphical character, and returns the first position at which that character is found. NOTLOWER Searches a character string for a character that is not a lowercase letter, and returns the first position at which that character is found. NOTNAME Searches a character string for an invalid character in a SAS variable name under VALIDVARNAME=V7, and returns the first position at which that character is found. NOTPRINT Searches a character string for a nonprintable character, and returns the first position at which that character is found. NOTPUNCT Searches a character string for a character that is not a punctuation character, and returns the first position at which that character is found. NOTSPACE Searches a character string for a character that is not a white-space character (blank, horizontal and vertical tab, carriage return, line feed, and form feed), and returns the first position at which that character is found. NOTUPPER Searches a character string for a character that is not an uppercase letter, and returns the first position at which that character is found. NOTXDIGIT Searches a character string for a character that is not a hexadecimal character, and returns the first position at which that character is found. */ data _null_; target="123!c5 D9_;91234567890"; AnyAlpha1=AnyAlpha(target); AnyAlpha2=AnyAlpha(target,5); AnyAlpha3=AnyAlpha(target,-1); AnyDigit1=AnyDigit(target); AnyDigit2=AnyDigit(target,5); AnyDigit3=AnyDigit(target,-1); ANYPUNCT1=AnyPunct(target); ANYPUNCT2=AnyPunct(target,13); ANYUPPER1=AnyUpper(target); ANYUPPER2=AnyUpper(target,13); AnyLower1=AnyLower(target); AnyLower2=AnyLower(target,13); NOTALNUM1=NOTALNUM(target); NOTALNUM2=NOTALNUM(target); NOTALPHA1 =NOTALPHA(target); NOTALPHA2 =NOTALPHA(target,8); NOTCNTRL1 =NOTCNTRL(target); NOTCNTRL2 =NOTCNTRL(target,8); NOTDIGIT1 =NOTDIGIT(target); NOTDIGIT2 =NOTDIGIT(target,8); NOTFIRST1 =NOTFIRST(target); NOTFIRST2 =NOTFIRST(target,8); NOTGRAPH1 =NOTGRAPH(target); NOTGRAPH2 =NOTGRAPH(target,8); NOTLOWER1 =NOTLOWER(target); NOTLOWER2 =NOTLOWER(target,8); NOTNAME1 =NOTNAME(target); NOTNAME2 =NOTNAME(target,8); NOTPRINT1 =NOTPRINT(target); NOTPRINT2 =NOTPRINT(target,8); NOTPUNCT1 =NOTPUNCT(target); NOTPUNCT2 =NOTPUNCT(target,8); NOTSPACE1 =NOTSPACE(target); NOTSPACE2 =NOTSPACE(target,8); NOTUPPER1 =NOTUPPER(target); NOTUPPER2 =NOTUPPER(target,8); /* NOTXDIGIT Function*/ put target= AnyAlpha1= AnyAlpha2= AnyAlpha3=; put target= AnyDigit1= AnyDigit2= AnyDigit3=; put target= ANYPUNCT1= ANYPUNCT2= ; put target= ANYUpper1= ANYUpper2= ; put target= ANYLower1= ANYLower2= ; put target= NOTALNUM1= NOTALNUM2= ; put target= NOTALPHA1= NOTALPHA2= ; put target= NOTCNTRL1= NOTCNTRL2= ; put target= NOTDIGIT1= NOTDIGIT2= ; put target= NOTFIRST1= NOTFIRST2= ; put target= NOTGRAPH1= NOTGRAPH2= ; put target= NOTLOWER1= NOTLOWER2= ; put target= NOTNAME1= NOTNAME2= ; put target= NOTPRINT1= NOTPRINT2= ; put target= NOTPUNCT1= NOTPUNCT2= ; put target= NOTSPACE1= NOTSPACE2= ; put target= NOTUPPER1= NOTUPPER2= ; run; 9 1 =252 3 NumFormatLookup 1 332 1 44 data small; infile datalines; input pat_id; datalines; 23116 12554 ; run; data large; infile datalines; input pat_id state $ zip $; datalines; 12554 PA 19003 11121 NJ 08554 44444 MD 21332 23116 MA 62231 99332 PA 19104 33333 DE 21443 ; run; data New_Fmt(keep= fmtname start label type hlo); retain FMTNAME "N_Fltr" TYPE "n" LABEL "YES "; set small (rename=(pat_id=start )) end=last; output; if last=1 then do; Hlo="O"; label="Other" ; start= .; output; end; run; proc format cntlin= New_Fmt; run; /*See the format internal file proc format cntlout= look; run; proc print data=look; title "note that the data is now in ascending order"; run; */ DATA IN_SML_TOO; SET large; IF PUT(PAT_ID, N_Fltr.)="YES"; RUN; proc print data=IN_Sml_too; run; 367 1 £252 3 nvalid( 1 332 1 24 /*NVALID Function Checks the validity of a character string for use as a SAS variable name. */ options validvarname=v7 ls=64; data string; input string $char40.; v7=nvalid(string,'v7'); any=nvalid(string,'any'); nliteral=nvalid(string,'nliteral'); default=nvalid(string); datalines; Tooooooooooooooooooooooooooo Long OK Very_Long_But_Still_OK_for_V7 1st_char_is_a_digit Embedded blank !@#$%^&* "Very Loooong N-Literal with """N 'No closing quotation mark ; proc print noobs; title1 'NLITERAL and Validvarname Arguments Determine'; title2 'Invalid (0) and Valid (1) SAS Variable Names'; run; 91 1 V252 3 ordinal( 1 332 1 1 ordinal( count , number1, number2< , number3<...>> ) 182 1 N252 3 pctl( 1 332 1 1 pctl( percentage , number1< , number2<...>> ) 183 1 ;252 3 pdf( 1 332 1 1 pdf( 'Bernoulli|beta|binomial|Cauchy|chiSquare|exponential|F|gamma|geometric|hyperGeometric|LaPlace|logistic|logNormal|negBinomial|normal|Gauss|normalMix|Pareto|Poissont|uniform|Wald|iGauss|Weibull' , quantile< , shapeLocationOrScaleParameter1< , shapeLocationOrScaleParameter2<...>>> ) 245 1 7252 3 perm( 1 332 1 1 perm( universe , sample ) 236 1 H252 3 poisson( 1 332 1 1 poisson( mean , integerRandomVariable ) 246 1 S252 3 probbeta( 1 332 1 1 probBeta( numericRandomVariable , shape , shape ) 247 1 s252 3 probbnml( 1 332 1 1 probBnml( probabilityOfSuccess , independentBernoulliTrials , numberOfSuccesses ) 248 1 h252 3 probbnrm( 1 332 1 1 probBnrm( numericVariable , numericVariable , correlationCoefficient ) 249 1 d252 3 probchi( 1 332 1 1 probChi( numericRandomVariable , degreesOfFreedom , nonCentrality ) 250 1 w252 3 probf( 1 332 1 1 probF( numericRandomVariable , numeratorDegreesOfFreedom , denominatorDegreesOfFreedom ) 251 1 I252 3 probgam( 1 332 1 1 probGam( numericRandomVariable , shape ) 252 1 {252 3 probhypr( 1 332 1 1 probHypr( population , itemsInCategory , sampleSize , integerRandomVariable , oddsRatio ) 253 1 :252 3 probit( 1 332 1 1 probiT(numericProbability) 263 1 «252 3 probmc( 1 332 1 1 probMC( 'Dunnett1|Dunnett2|maxMod|range|Williams'< , quantile>< , leftProbability> , degreesOfFreedom , numberOfTreatments< , parameters> ) 254 1 i252 3 probnegb( 1 332 1 1 probNegB( probabilityOfSuccess , numberOfSuccesses , numberOfFailures ) 255 1 A252 3 probnorm( 1 332 1 1 probNorm(numericRandomVariable) 256 1 `252 3 probt( 1 332 1 1 probT( numericRandomVariable , degreesOfFreedom , nonCentrality ) 257 1 ­252 3 proc append 1 332 1 30 /**APPEND******************************/ /**************************************/ data Males females(drop=age); set sashelp.class; if sex="M" then output males; else output Females; run; proc sql; drop table combo;quit; PROC APPEND BASE= Combo /*sas creates base if it does not exist*/ DATA= females /*put smaller data set here*/ /*FORCE*/ /*use if data sets have different variables or attributes*/ ; quit; PROC APPEND /*Intentional failure - uncomment FORCE*/ BASE= Combo /*sas creates base if it does not exist*/ DATA= males /*put smaller data set here*/ /*FORCE*/ /*use if data sets have different variables or attributes will NOT add "bad" vars but will allow append to happen for good vars*/ ; quit; /*FORCE forces the APPEND statement to concatenate only the "matching variables" in data sets when the DATA= data set contains variables that either (1) are not in the BASE= data set, (2) do not have the same type as the variables in the BASE= data set or (3) are longer than the variables in the BASE= data set. non-matching variables can be dropped*/ /********************************/ 391 1 ,252 3 proc catalog 1 332 1 6 /**Proc Catalog******************************/ /********************************************/ /*Has many uses - suggest a reading of the manual*/ /*Here we simpley delete all files from a library (here we kill work)*/ proc catalog Cat=work._all_ Kill; quit; 393 1 °252 3 proc chart 1 332 1 30 /** Proc Chart - suggest reading on Proc GChart *******/ /* Proc chart is powerful but is for old style printers *******/ /*GCHART has better graphics - check out the manual on GCHART*/ PROC CHART data=; BLOCK variable(s) ; BY variable-1 <... variable-n> ; HBAR variable(s) ; PIE variable(s) ; STAR variable(s) ; VBAR variable(s) ; run; proc chart data=sashelp.class; /*SAS makes "nice" greoups of ages unless you Code some options*/ /*Options are powerful but interact in complex ways*/ hbar age /group=sex /*discrete- Shows average age. Using discrete is suggested here */; hbar age /Subgroup=sex discrete; Pie age /discrete; Pie sex; Vbar age /Subgroup=sex discrete; Vbar age /Subgroup=sex levels =10; /*create 10 age groups*/ Vbar age /Subgroup=sex Midpoints= 11 15;/*Two groups with midpoints at 11 and 15*/ run; /*options DISCRETE FREQ= MISSING SUMVAR= TYPE= */ /*Specify groupings: G100 GROUP= LEVELS= MIDPOINTS= SUBGROUP= */ /*Compute statistics: CFREQ CPERCENT FREQ MEAN PERCENT SUM */ /*Control output format */ /* ASCENDING AXIS= DESCENDING GSPACE= NOHEADER NOSPACE NOSTATS NOSYMBOL NOZEROS*/ /* REF= SPACE= SYMBOL= WIDTH= */ 394 1 ?252 3 proc contents 1 332 1 8 /************** Proc Contents************/ /*****************************************/ PROC CONTENTS directory /*Print a list of the SAS files in the SAS data library*/ DATA=sashelp.shoes /*Specify the input data set - also used with output data set*/ /*Print a list of the variables by their logical position in the data set */ position /*adds a second printout in the order in which the vars appear in the data set*/ out=ContentsAsDataSet ; /*Specify the output data set */ run; 395 1 252 3 proc copy 1 332 1 6 libname bogus "D:\Documents and Settings\rlavery\My Documents"; PROC COPY IN=work OUT=bogus /*source and destination libraries*/ INDEX=YES; /*Copy index as well as data*/ select class:; /*files to be copied*/ run; 396 1 µ 252 3 proc datasets 1 332 1 113 /***************** Proc Datasets ***************************/ /* The DATASETS procedure is a utility procedure that manages your SAS files */ /*copy, rename , repair. append, delete, list, list & modify attributes SAS files*/ /*manipulate passwords on SAS files */ /*create and manage audit files for SAS data sets */ /*create and delete integrity constraints on SAS data sets. */ /*Delete all files starting with the same prefix - files created by a macro start with _M_ */ proc sql Noprint; select memname into :MacroTables separated by ' ' from dictionary.tables where libname="WORK" and substr(memname,1,3) = "_M_" ; quit; Proc datasets lib=work; delete &MacroTables; quit; /*Change lots of characteristics without reading the data*/ data class; set sashelp.class; run; PROC DATASETS lib=work; /*Can do lots of thngs*/ modify class (label="labels are good for documentation" sortedby=name); index create name; index create NameAge=(name age); label name ="Name of student"; format age 5.2; quit; proc contents data=class;run; proc print data=class; run; PROC DATASETS LIBRARY= work /*Specify the procedure input library*/ DETAILS /*Put info in the log about: number of observations, variables, indexes, and data set labels */; /*DELETE WORK.CLASS*/ /*Delete dataset*/ QUIT; /*http://sastricks.wikidot.com/base:procdataset*/ /*Delete all labels in th.pnsmutaa*/ proc datasets library = th nolist; modify pnsmutaa; attrib _all_ label=''; quit; /*Rename th.bstpns_org to th.bstpns_org1*/ proc datasets library = th nolist; change stpns_org = bstpns_org1; quit; /*Delete all in a library*/ proc datasets library = work kill nolist; quit; /*Delete one specific dataset from a library*/ proc datasets library = work nolist; delete tst1; quit; /*Copy all in library th to work*/ proc datasets nolist; copy out=work in=th; quit; /*Copy th.rappformat to work.rappformat*/ proc datasets nolist; copy out=work in = th; select rappformat; quit; /***************************************************************** Section __:http://www.stats.uwa.edu.au/Internal/sas_training ******************************************************************/ /* 4. proc datasets version of above - list all datasets in the specified library */ proc datasets library=work; quit; run; /* 5. describe a single dataset */ proc datasets library=work; contents data=en1; quit; run; /* 11. move just one dataset from stud07 to work */ proc datasets; copy move in=stud07 out=work; select en3; quit; run; /* 13. change the name of a dataset */ proc datasets library=work; change en2=en4; quit; run; /* 14. append datasets - note this is quicker than using a set command, as only the appended dataset is read in */ proc datasets library=work; append out=en4 data=en1; quit; run; /* 15. rename a variable */ proc datasets library=work NOlist; modify en1; rename student=personid course = course_cd; run; quit; 397 1 J252 3 proc export 1 332 1 21 /****************** Proc EXPORT **********/ /*reads data from a SAS data set and writes it to an external data source*/ /*Creates Access , Excel , Lotus ,& blank, comma, or tab delimited files */ PROC EXPORT DATA=SAS-data-set <(SAS-data-set-options)> OUTFILE="filename" | OUTTABLE="tablename" ; libname bogus "D:\Documents and Settings\rlavery\My Documents"; PROC EXPORT DATA= sashelp.class(where=(SEX="M")) DBMS=EXCEL OUTFILE= "D:\Documents and Settings\rlavery\My Documents\Example.xls" /*path to, and name of, workbook*/ REPLACE; /*replace the workbook if it exists*/ sheet=Males; /*Sheet is on it's own line - make a sheet*/ RUN; PROC EXPORT DATA= sashelp.class(where=(SEX="F")) DBMS=EXCEL OUTFILE= "D:\Documents and Settings\rlavery\My Documents\Example.xls" /*path to, and name of, workbook*/ REPLACE; /*replace the workbook if it exists*/ sheet=Females;/*Sheet is on it's own line - make a sheet*/ RUN; 398 1 œ252 3 proc format 1 332 1 226 /******** Proc FORMAT **************/ /* Suggested Reading Creating formats with a program http://www.nesug.org/proceedings/nesug03/at/at006.pdf My Friend the SAS® Format Andrew Kaep SUGI30 paper 253 http://www2.sas.com/proceedings/sugi30/253-30.pdf MULTILABEL - A useful addition to the FORMAT procedure Venky Chakravarthy http://www.lexjansen.com/pharmasug/2004/technicaltechniques/tt22.pdf Multiple Facts about Multilabel Formats Gwen D. Babcock NESUG 2008 http://www.nesug.org/proceedings/nesug08/cc/cc14.pdf Proc Format Advanced Techniques: Multi-label and Nested Formats Tatiana Nevmyrych & Jennifer Clark http://www.ppdi.com/resource_library/whitepapers/tnevmyrych_jclark_pharmasug_2007.pdf */ proc format;/*examples of creating formats - no use shown for these*/ value $skilltest 'a'-<'e' ,'A'-<'E' ='Test A' /*character format*/ 'e'-<'m' ,'E'-<'M' ='Test B' 'm'-'z~' ,'M'-'Z~' ='Test C'; value levels (fuzz=.2) 1='A' /*num format*/ 2='B' 3='C'; run; proc format; /*These formats will be used below*/ value $ gender "M"="Male" "F"="Female"; value AgeGrp 0 -< 14 = "younger" 14- high = "older"; run; proc print data=sashelp.class; format age AgeGrp. Sex $gender.; /*associate formats with the vars ONLY during this proc*/ run; data new; set sashelp.class; newage=put(age,agegrp.); newsex=put(sex,$gender.); format age agegrp.; /*associate the format PERMANENTLY with the variable*/ run; proc print data=new; title "formats had been permanently associated in data step above"; title2 " so we see formatted values w/o a format statement"; run;/*note: no formats specified in this print*/ **using data steps to create a format that can be used to filter data; /* http://www.nesug.org/Proceedings/nesug03/at/at006.pdf */ /*This can be done easier, but the example runs*/ data NeedInfoOn; /*Inagine we have a small list of customers*/ set sashelp.class(keep=name); if mod(_n_,4)=0; run; data Imagine2BeVeryBig;/*we have a big file, with all their info*/ set sashelp.class; run; data cntlin(keep= FmtName start label type HLo); set NeedInfoOn(rename=(name=start)) end=eof; retain fmtname "GetCust" type "C" label "Y" ; output; IF eof=1 then do; Number=.; start=""; HLo="O"; label="N"; output; end; ; run; proc format cntlin=cntlin; run; data desiredCustomers; set Imagine2BeVeryBig; Number=_n_; if put(name,$GetCust.)="Y"; run; options nocenter; proc print data=desiredCustomers; run; *multiformats only work with means, summary and tabulate; **DANGER - THIS IS TRICKEY**; proc format ; value $GAndT (multilabel) "F"="Females" "M"="Males" "F","M"="Total"; run; proc format cntlout=FmtVarNames; select GAndT; run; proc print data=FmtVarNames; run; proc means data=sashelp.class nway missing; class sex /mlf; class age; format sex $GAndT.; run; proc tabulate data=sashelp.class missing; class sex /mlf; class age; table Sex,age; format sex $GAndT.; run; /***************************************************************** Section __: Picture formats ******************************************************************/ libname proclib 'SAS-library-1 '; libname library 'SAS-library-2'; options nodate pageno=1 linesize=80 pagesize=40; proc format library=library; picture uscurrency low-high='000,000' (mult=1.61 prefix='$'); run; proc print data=proclib.staff noobs label; label salary='Salary in U.S. Dollars'; format salary uscurrency.; title 'PROCLIB.STAFF with a Format for the Variable Salary'; run; /***************************************************************** Section __: Printing the Description of Informats and Formats ******************************************************************/ libname library 'SAS-library'; options nodate pageno=1 linesize=80 pagesize=60; proc format library=library fmtlib; select @evaluation nozeros; title 'FMTLIB Output for the NOZEROS. Format and the'; title2 'Evaluation. Informat'; run; /***************************************************************** Section __: INFormat ******************************************************************/ INVALUE <$>name <(informat-option(s))> ; /*INVALUE Statement Creates an informat for reading and converting raw data values. UPCASE converts all raw data values to uppercase before they are compared to the possible ranges. you use UPCASE, then make sure the values or ranges you specify are in uppercase. */ /* Required Arguments name Options DEFAULT=length FUZZ= fuzz-factor MAX=length MIN=length NOTSORTED JUST left-justifies all input strings before they are compared to the ranges. UPCASE converts all raw data values to uppercase before they are compared to the possible ranges. If you use UPCASE, then make sure the values or ranges you specify are in uppercase. The informat converts the raw data to the values of informatted-value on the right side of the equal sign. informatted-value is the value you want the raw data in value-or-range to become. Use one of the following forms for informatted-value: 'character-string' is a character string up to 32,767 characters long. Typically, character-string becomes the value of a character variable when you use the informat to convert raw data. Use character-string for informatted-value only when you are creating a character informat. If you omit the single or double quotation marks around character-string, then the INVALUE statement assumes that the quotation marks are there. number is a number that becomes the informatted value. Typically, number becomes the value of a numeric variable when you use the informat to convert raw data. Use number for informatted-value when you are creating a numeric informat. The maximum for number depends on the host operating environment. _ERROR_ treats data values in the designated range as invalid data. SAS assigns a missing value to the variable, prints the data line in the SAS log, and issues a warning message. _SAME_ prevents the informat from converting the raw data as any other value. For example, the following GROUP. informat converts values 01 through 20 and assigns the numbers 1 through 20 as the result. All other values are assigned a missing value. invalue group 01-20= _same_ other= .; Consider the following examples: The $GENDER. character informat converts the raw data values F and M to character values '1' and '2': invalue $gender 'F'='1' 'M'='2'; The dollar sign prefix indicates that the informat converts character data. When you are creating numeric informats, you can specify character strings or numbers for value-or-range. For example, the TRIAL. informat converts any character string that sorts between A and M to the number 1 and any character string that sorts between N and Z to the number 2. The informat treats the unquoted range 1-3000 as a numeric range, which includes all numeric values between 1 and 3000: invalue trial 'A'-'M'=1 'F'-'Z'=2 1-3000=3; The CHECK. informat uses _ERROR_ and _SAME_ to convert values of 1 through 4 and 99. All other values are invalid: invalue check 1-4=_same_ 99=. other=_error_; If you use a numeric informat to convert character strings that do not correspond to any values or ranges, then you receive an error message. ***************** Proc format; invalue Gndr 'M'=1 'F'=2; Data new(keep=name sex sexno); set sashelp.class; SexNo=input(sex,Gndr.); run; Proc contents data=new; run; */ 399 1 k252 3 proc freq 1 332 1 50 /**** Proc Freq ******************/ /****** Formats are powerful additions to several SAS procs ******************/ /*sparse option http://www.nesug.org/proceedings/nesug02/cc/cc003.pdf*/ proc format; /*These formats will be used below*/ value $ gender "M"="Male" "F"="Female"; value AgeGrp 0 -< 14 = "younger" 14- high = "older"; run; data class; set sashelp.class; if mod(_n_,10)=0 then sex=""; run; proc freq data=class /*noprint*/; tables age*sex ; run; proc freq data=class /*noprint*/; tables age*sex /missing; run; proc freq data=class /*noprint*/; tables age*sex /list missing; run; ************************************; proc freq data=class /*noprint*/; tables age*sex / norow nocol nopct /*use to make the table fit "smaller"*/ out=MyFreqs1 /*data set with output*/ all /*prints LOTS of statistics*/; tables age*sex*height / list /*do not format as x-tab*/ OUT=MyFreqs2 /*data set with output*/ /*sparse*/ /*Make all combinaitons of values show in list type ouptut*/; FORMAT age ageGrp. /*formats the frequencies in margins of crosstabulation tables*/; *WEIGHT variable ; /*increases/decreases importnace of observatIOns*/; Run; /*Syntax for requesting tables can be nested and elegant*/ /* Examples of nesing table requests shown below */ /*tables age*(sex height); tables age*sex age*height; */ /*tables (age sex)*(height weight); tables age*height sex*height age*weight sex*weight; */ /*tables (age sex height)*weight; tables age*weight sex*weight height*weight; */ /*tables name - - age; tables name sex age; */ /*tables (name - - age)*height; tables Age*height sex*height age*height; */ 400 1 @252 3 proc import 1 332 1 23 /******************* Proc Import *************************************************/ /* NO WORKING EXAMPLE PROVIDED - it would require a fle on your machine */ /*IMPORT reads external data source and makes a SAS data set. */ /*data sources can be Access, Excel, Lotus, & a blank, comma, and tab delilmited.*/ PROC IMPORT OUT= WORK.NeededFile /*use proc export abbrev to create an excel file for practice*/ DATAFILE= "C:\Transfer\NeededFile.xls" DBMS=EXCEL REPLACE; /*you can import other kinds of tables as well*/ RANGE="range-name or absolute-range"; /*identifying the rectangular set of cells to import*/ SHEET=spreadsheet-name; /*identifies a particular spreadsheet to be read*/ GETNAMES=YES; /*generate SAS variable names from the column names in the input file's first row of data.*/ DATAROW=n; /*starts reading data from row number n */ GUESSINGROWS=1( to 3276); /*reads this number of rows before guessing if col type= N or C*/ MIXED=YES | NO;/*if YES, converts numeric data into character data values for a column that contains mixed data types*/ USEDATE=YES | NO; /*If YES, then DATE. format is used for date/time columns in the data source table while importing data from Excel workbook. If NO, then DATETIME. format is used for date/time*/ SCANTIME=YES; /*scans all row values for a DATETIME data type field and automatically determines the TIME data type if only time values (no date or datetime values) exist in the column.*/ RUN; 26 1 ğ 252 3 proc means 1 332 1 81 /********* PROC MEANS *********/ /*** Means is the same as Proc Summary : Also see summary for mre cool stuff****/ /*for production reports (and transposing) investigate:*/ /*class options:EXCLUSIVE & PRELOADFMT */ /*Summary options: CLASSDATA=, COMPLETETYPES, EXCLUSIVE, PRINTALLTYPES*/ /*** Example 1 of proc means ***/ /*what you print is not what goes in the output file*/ Proc means data=sashelp.class n mean P25 P50 P75 missing MaxDec=4 /*noprint*/; class sex; /*using clas or By - class does not require a sorted data set*/ output out=SexMean n(age height)=nage nheight min(age weight)=MinAge MinWeight sum(height)=sumHeight; types () sex; /*Types allows you to specify what you want - more powerful than NWAY */ /*Check out both the types and ways statements*/ /*Also read about exclusive, completetews and pre-loading a format or control file*/ run; proc print data=SexMean; run; /*Example 2 from SAS help - shows the use of a classdata and Exclusive options */ /*classdata and exclusive are very good for production reports */ /* when you want a value to be in the report even if it is not in the data */ /* and ONLY want to process the levels of class varaibels that interest management*/ data cake; input LastName $ 1-12 Age 13-14 PresentScore 16-17 TasteScore 19-20 Flavor $ 23-32 Layers 34 ; datalines; Orlando 27 93 80 Vanilla 1 Ramey 32 84 72 Rum 2 Goldston 46 68 75 Vanilla 1 Roe 38 79 73 Vanilla 2 Larsen 23 77 84 Chocolate . Davis 51 86 91 Spice 3 Strickland 19 82 79 Chocolate 1 Nguyen 57 77 84 Vanilla . Hildenbrand 33 81 83 Chocolate 1 Byron 62 72 87 Vanilla 2 Sanders 26 56 79 Chocolate 1 Jaeger 43 66 74 1 Davis 28 69 75 Chocolate 2 Conrad 69 85 94 Vanilla 1 Walters 55 67 72 Chocolate 2 Rossburger 28 78 81 Spice 2 Matthew 42 81 92 Chocolate 2 Becker 36 62 83 Spice 2 Anderson 27 87 85 Chocolate 1 Merritt 62 73 84 Chocolate 1 ; options nodate pageno=1 linesize=80 pagesize=60; data caketype; /*a driver file - management wants to see informtion on these levels*/ input Flavor $ 1-10 Layers 12; datalines; Vanilla 1 Vanilla 2 Vanilla 3 Chocolate 1 Chocolate 2 Chocolate 3 ; proc means data=cake range median min max fw=7 maxdec=0 classdata=caketype /*show all levels that are in the driver file*/ exclusive /*only show what is in the driver file*/ printalltypes; output out=CakeOut; var TasteScore; class flavor layers; title 'Taste Score For Number of Layers and Cake Flavor'; run; proc print data=CakeOut; title "Note that we have freq=0 (effect of the printalltypes"; title2 "Note that we have no spice cakes (Effect of the exclusive)"; run; 369 1 š252 3 proc options 1 332 1 3 /******** Proc Options **********************/ /* writes system options/settings to the log */ proc options ;run; 371 1 +252 3 proc plot 1 332 1 20 /*********** PROC PLOT *******/ /*Proc plot is powereful but is for impact printers*/ /* for nicer looking output, see proc Gplot */ PROC PLOT DATA=sashelp.class ; PLOT Height*age=sex /*make the plotting symbol= the value of sex for that obs*/ / box Href=12 /*put a reference line on the chart*/ Vref=60 /*put a reference line on the chart*/ Haxis=0 to 20 by 2 /*control the horizontal axis*/; run; options nodate pageno=1 linesize=120 pagesize=60; proc plot data=sashelp.class vpercent=50 hpercent=50; title "Cool! Multiple plots per page"; plot Weight*age=Sex; plot Height*age='H'; plot Height*Weight=sex age*Weight='A' / overlay box; /*plotting multiple vars per plot is good for "pred & actual" plots in stat*/ run; 372 1 ˆ252 3 proc print 1 332 1 34 /****************** PROC PRINT ***********/ /* has lots of useful options */ proc format; value $LongGn "M"="Males" "F"="Females"; run; data class; set sashelp.class; spacer="*"; Gndr_of_Student=sex; label spacer="Spacer_variable"; run; proc sort data=class out=SortdClass; by sex descending name; /*sort for by processing below*/ run; PROC PRINT DATA=SortdClass NOOBS /*suppresses the obs column*/ DOUBLE /*double space the output*/ UNIFORM /*keep same page layout if output goes to multiple pages*/ label /*use labels for column headers*/ split="_" /*Split var names and lables on this character*/ Width=Min; BY Sex ; PAGEBY Sex; /*new page when By variable cahnges*/ SUMBY Sex; /*If BY var. changes, any BY var. to left, print sum var(s)in SUM statement*/ ID name ; /*print instead of the number at beginning of row*/ SUM age weight ; /*identifies the numeric variables to total in the report.*/ VAR _numeric_ spacer _character_ ; /*variabels to be printed and their order*/ format sex $LongGn.; ; run; 373 1 Z252 3 proc printto 1 332 1 53 /*********** PROC PRINTTO ********************************************/ /**PRINTTO defines destinations for Proc output and for the SAS log */ /* If you RSUBMIT, there is a little extra complexity */ /***** Example 1: Local submit and local log***************/ PROC PRINTTO LOG='C:\temp\example.log' /*identifies the location and routes the SAS log to this alternate location*/ PRINT='C:\temp\example.lst' /*identifies the location and routes the procedure output to this alternate location*/ NEW /*specifies that the current log or procedure output writes over the previous contents of the file*/; run; proc print data=sashelp.class; run; Proc Printto; /*Clear the routing - log and list go to "regualr" windows*/ run; /***** Example 2: remote submit and local log ***************/ /* if Printto is NOT inside the RSUBMIT, log/list are stored locally**/ PROC PRINTTO LOG='C:\temp\example.log' /*identifies the location and routes the SAS log to this alternate location*/ PRINT='C:\temp\example.lst' /*identifies the location and routes the procedure output to this alternate location*/ NEW /*specifies that the current log or procedure output writes over the previous contents of the file*/; run; rsubmit; proc print data=sashelp.class; run; endrsubmit; Proc Printto; /*Clear the routing - log and list go to "regualr" windows*/ run; /***** Example 3: remote submit and Remote log***************/ /* If PRINTTO is inside the rsubmit, log/list are stored remotely*/ rsubmit; PROC PRINTTO LOG='/sasuser/rlavery/example.log' /*identifies the location and routes the SAS log to this alternate location*/ PRINT='/sasuser/rlavery/example.lst' /*identifies the location and routes the procedure output to this alternate location*/ NEW /*specifies that the current log or procedure output writes over the previous contents of the file*/; run; proc print data=sashelp.class; run; Proc Printto; /*Clear the routing - log and list go to "regualr" windows*/ run; endrsubmit; 374 1 Å252 3 proc rank 1 332 1 145 /************proc rank******/ /*RANK computes ranks for one or more numeric variables and sends ranks to a new data set PROC RANK by itself produces no printed output. PROC RANK DATA= OUT= names the output data set.If SAS-data-set does not exist, PROC RANK creates it. DESCENDING reverses the direction of the ranks FRACTION computes fractional ranks by dividing each rank by the number of observations having nonmissing values of the ranking variable. GROUPS=number-of-groups assigns group values ranging from 0 to number-of-groups minus 1. NORMAL=BLOM | TUKEY | VW computes normal scores from the ranks. NPLUS1 computes fractional ranks by dividing each rank by the denominator n+1 PERCENT divides each rank by the number of observations that have nonmissing values of the variable and multiplies the result by 100 to get a percentage TIES=HIGH | LOW | MEAN | DENSE specifies how to compute normal scores or ranks for tied data values. HIGH assigns the largest of the corresponding ranks (or largest of the normal scores when NORMAL= is specified). LOW assigns the smallest of the corresponding ranks (or smallest of the normal scores when NORMAL= is specified). MEAN assigns the mean of the corresponding rank (or mean of the normal scores when NORMAL= is specified). DENSE computes scores and ranks by treating tied values as a single-order statistic. ; BY variable-1 <... variable-n> ; VAR data-set-variables(s); RANKS new-variables(s); The output data set contains all the variables from the input data set plus the variables named in the RANKS statement. If you omit the RANKS statement, the rank values replace the original variable values in the output data set. Missing Values Missing values are not ranked and are left missing when ranks or rank scores replace the original values in the output data set. */ /*pretty basic rank but there are options*/ PROC RANK data=sashelp.class OUT=RankedClass Ties=mean /*you have options here: specify condense, low, avg or high*/ ; Var age height weight; ranks RankAge RankHeight weight/*can overwrite old variable*/; run; proc print data=rankedClass; run; /***Ranks inside Groupings *******/ proc sort data=sashelp.class out = GndrAgeClass; by sex Age; run; proc Rank data= GndrAgeClass out =RankedGndrAgeClass groups=3; by Sex; var Age; ranks AgeGrpByGndr; run; Proc print data= RankedGndrAgeClass; run; /*Example" ties low and descending are logically related*/ options nodate pageno=1 linesize=80 pagesize=60; data elect; input Candidate $ 1-11 District 13 Vote 15-18 Years 20; datalines; Cardella 1 1689 8 Latham 1 1005 2 Smith 1 1406 0 Walker 1 846 0 Hinkley 2 912 0 Kreitemeyer 2 1198 0 Lundell 2 2447 6 Thrash 2 912 2 ; proc rank data=elect out=results ties=low descending; by district; var vote years; ranks VoteRank YearsRank; run; proc print data=results n; by district; title 'Results of City Council Election'; run; /*example partition observations into groups on the basis of values of two input variables groups observations separately within BY groups replace the original variable values with the group values. Cool Logic from PROC Rank The group values pair up swimmers with similar times to work on each stroke. For example, Andrea and Ellen work together on the backstroke because they have the fastest times in the female class. The groups of male swimmers are unbalanced because there are seven male swimmers; for each stroke, one group has three swimmers. */ options nodate pageno=1 linesize=80 pagesize=60; data swim; input Name $ 1-7 Gender $ 9 Back 11-14 Free 16-19; datalines; Andrea F 28.6 30.3 Carole F 32.9 24.0 Clayton M 27.0 21.9 Curtis M 29.0 22.6 Doug M 27.3 22.4 Ellen F 27.8 27.0 Jan F 31.3 31.2 Jimmy M 26.3 22.5 Karin F 34.6 26.2 Mick M 29.0 25.4 Richard M 29.7 30.2 Sam M 27.2 24.1 Susan F 35.1 36.1 ; proc sort data=swim out=pairs; by gender; run; proc rank data=pairs out=rankpair groups=3; by gender; var back free; run; proc print data=rankpair n; by gender; title 'Pairings of Swimmers for Backstroke and Freestyle'; run; 375 1 Î[252 3 proc report 1 332 1 729 /***************************************************************** Section __Proc Report: ******************************************************************/ /*This is so powerful that it is hard to describe how options interact*/ /*Basics are simple, but management usually wants fancy*/ /*Overviews*/ /*http://www2.sas.com/proceedings/sugi29/122-29.pdf RayP and DanB*/ /*http://www2.sas.com/proceedings/sugi28/071-28.pdf Lauren*/ /*http://www2.sas.com/proceedings/sugi31/142-31.pdf Louise*/ /*http://www2.sas.com/proceedings/sugi31/060-31.pdf Temp Var Molter*/ /*http://www.lexjansen.com/pharmasug/2007/ad/ad16.pdf report Null David, Lanie, Akari*/ /*http://www2.sas.com/proceedings/forum2008/170-2008.pdf compare and contrast keith*/ /*Art Carpenter wrote the best book and wrote great stuff on compute blocks*/ /*http://www.lexjansen.com/pharmasug/2005/handsonworkshops/hw07.pdf basics Art*/ /*http://www2.sas.com/proceedings/forum2008/188-2008.pdf Comput Block Practicum Art*/ /*http://www2.sas.com/proceedings/forum2008/188-2008.pdf Comput Blocks 2 Art*/ /*http://www2.sas.com/proceedings/forum2007/242-2007.pdf Advanced Compute Block Art*/ /*http://www2.sas.com/proceedings/forum2007/025-2007.pdf Naming Issues Art*/ /*http://www.lexjansen.com/pharmasug/2004/CodersCorner/CC07.pdf Compute Blocks Sharon*/ /*Ray and Daphnie - wrote the classic papers*/ /*http://nesug.info/Proceedings/nesug99/bt/bt138.PDF Still Not Using*/ /*http://www.lexjansen.com/pharmasug/2004/handsonworkshops/hw01.pdf Still Not Using*/ /*http://www2.sas.com/proceedings/sugi30/244-30.pdf Is it Pretty*/ /*http://www.lexjansen.com/pharmasug/2006/sasinstitute/sa04.pdf Doing It In Stye;*/ /*http://www.nesug.org/proceedings/nesug99/cc/cc060.PDF Missing Obs Column*/ /*Useful*/ /*http://www2.sas.com/proceedings/sugi29/242-29.pdf Getting up to speed Kimberly*/ /*http://nesug.info/Proceedings/nesug99/cc/cc117.PDF CHRIS ID option*/ /*http://www2.sas.com/proceedings/sugi30/259-30.pdf Gentle Intro Ben*/ /*http://www2.sas.com/proceedings/forum2008/079-2008.pdf Step-by-step David*/ /*http://www2.sas.com/proceedings/sugi27/p059-27.pdf Quick MeiMei, Sandra, Maria*/ /*http://www2.sas.com/proceedings/sugi30/036-30.pdf Statistical Nestor*/ /*http://www2.sas.com/proceedings/forum2008/173-2008.pdf complex Cynthia */ /*http://www.lexjansen.com/pharmasug/2002/proceed/TechTech/tt20.pdf Footnotes Angleina*/ /*http://www2.sas.com/proceedings/sugi24/Coders/p079-24.pdf*/ /*http://www2.sas.com/proceedings/forum2007/056-2007.pdf*/ /*http://www2.sas.com/proceedings/sugi22/HANDSON/PAPER149.PDF*/ /*http://analytics.ncsu.edu/sesug/1999/031.pdf Text flow donals and John*/ /*http://analytics.ncsu.edu/sesug/2007/CC15.pdf ExcelXP Elayne*/ /*http://www.lexjansen.com/pharmasug/2002/proceed/Coders/cc08.pdf Whole page Richard */ /*http://www2.sas.com/proceedings/sugi31/129-31.pdf style thaer*/ /*http://www2.sas.com/proceedings/forum2008/224-2008.pdf Color Style Wendy*/ /*http://analytics.ncsu.edu/sesug/2007/CC13.pdf EMAIL Theresa*/ ods listing; ODS html close; /*Example 1 - basic stuff and the internal file*/ title1 "Look at the variable name_sex when sex is defined as order"; title2 "There are some tricks to this - This is not Exactly the internal file"; title3 "Order supresses repeating of values in the internal file and report"; title4 "Missing Repeating values are added 'back in' as thius file is created "; proc report data=sashelp.class nowd panels=2 /*Specify the number of panels on each page of the report*/ PS=30 ls=120 /*Specify the number of columns/lines in a page*/ split="*" /*Specify the split character*/ MISSING /*Consider missing values as valid values for group, order, or across variables*/ SPACING=2 /*number of blank characters between columns*/ out=InternalFile /*Holds internal file created by Proc Report*/ ; column sex name NameSex age height; /*the Define statement Supports preloadfmt and Exclusive for production reporting*/ define sex / /*order*/ Width=7 "Gender*of*Students"; define name / Width=7 "Student*Name"; define NameSex / computed Width=20 "Student*Name" FLOW; define age / Sum Width=20 "Age" spacing=3; define Height / mean Width=20 "Heught" spacing=3; compute NameSex / character length=30; If _break_ = "_RBREAK_" then namesex="Age is Sum & Height is avg."; Else namesex=trim(name)||" is a "||Sex||" On our records"; endcomp; rbreak after /summarize DOL; run; proc print data=InternalFile; title1 "Look at the variable name_sex when sex is defined as order"; title2 "There are some tricks to this - This is not Exactly the internal file"; title3 "Order supresses repeating of values in the internal file and report"; title4 "Missing Repeating values are added 'back in' as thius file is created "; run; title ""; /*Example 2 - across variables*/ proc report data=sashelp.class nowd split="*" /*Specify the split character*/ MISSING /*Consider missing values as valid values for group, order, or across variables*/ SPACING=2 /*number of blank characters between columns*/ out=InternalFile /*Holds internal file created by Proc Report*/ ; column sex age,(n=count height); define sex /group width=4; define age / across "-Count and Mean Height by Sex * Ages of Students-"; define count / "Count*of*Students" center; define height / mean "Mean*Height" center; run; *example 3 From Art Carpenter***/ * Creating a new NUMERIC column with a compute block; title1 'Using The COMPUTE Block'; title2 'Adding a Computed Column'; proc report data=sashelp.class split='*' NOWD; column name sex NmSex(' Weight *--' weight wtkg); define name / order width=18 'Last Name*--'; define sex / display width=6 'Gender*--'; define NmSex / computed 'Just A Character*Concatination*--'; define weight / display format=6. 'Pounds*--'; define wtkg / computed format=9.2 'Kilograms*--'; compute NMSEX /character length=20; NMSEX = strip(name)||"_"||Sex; endcomp; compute wtkg; wtkg = weight / 2.2; endcomp; run; title ""; * example 4 - panels ; data classlong; set sashelp.Class sashelp.Class sashelp.Class sashelp.Class sashelp.Class sashelp.Class; spacer="*"; run; ods listing; proc report data=ClassLong panels=3 nowd PSPACE=3; column name sex age spacer; define name / width=10 spacing=1; define sex / width=4 spacing=1; define age / width =4 spacing=1; define spacer / width =1 spacing=3 ""; run; * example 5 luo proc report option background color\; ods html file='C:\temp1\report1.html'; title1 "report2"; proc report data=sashelp.class split='*' NOWD style(column)={background=red}; column name sex NmSex(' Weight *--' weight wtkg) ; define name / order width=18 'Last Name*--' style(header)={background=yellow}; define sex / display width=6 'Gender*--'; define NmSex / computed 'Just A Character*Concatination*--'; define weight / display format=6. 'Pounds*--'; define wtkg / computed format=9.2 'Kilograms*--'; compute NMSEX /character length=20; NMSEX = strip(name)||"_"||Sex; endcomp; compute wtkg; wtkg = weight / 2.2; endcomp; run; ods html close; data classlong; set sashelp.Class sashelp.Class sashelp.Class sashelp.Class sashelp.Class sashelp.Class; spacer="*"; run; ods html file="C:\temp1\report2.html" ; title1 "Report1"; proc report data=ClassLong panels=3 nowd style(column)={background=_undef_}; column name sex age spacer; define name / width=10 spacing=1 style(column)={background=red}; define sex / width=4 spacing=1 ; define age / width =4 spacing=1; define spacer / width =1 spacing=3 ""; run; ods html close; /***************************************************************** Section __: Creating statistics ******************************************************************/ options ls=120 nocenter; proc format;/*examples of creating formats - no use shown for these*/ value $Gndr M ='-Male-' /*character format*/ F ='-Female-'; run; ods listing; Proc report data=SASHelp.class nowd split="*" Spacing=4; columns age sex,(N=count height); define age /group width=10; define sex /across "-count and mean height by age & sex -" format=$Gndr.; define count / "Count*of*Students" center; define height / mean "Mean*Height" center; run; proc report data=sashelp.class nowd split="*" /*Specify the split character*/ MISSING /*Consider missing values as valid values for group, order, or across variables*/ SPACING=2 /*number of blank characters between columns*/ out=InternalFile /*Holds internal file created by Proc Report*/ ; column sex age,(n=count height); define sex /group width=4; define age / across "-Count and Mean Height by Sex * Ages of Students-"; define count / "Count*of*Students" center; define height / mean "Mean*Height" center; run; /**********************/ data grocery; input Sector $ Manager $ Department $ Sales @@; datalines; se 1 np1 50 se 1 p1 100 se 1 np2 120 se 1 p2 80 se 2 np1 40 se 2 p1 300 se 2 np2 220 se 2 p2 70 nw 3 np1 60 nw 3 p1 600 nw 3 np2 420 nw 3 p2 30 nw 4 np1 45 nw 4 p1 250 nw 4 np2 230 nw 4 p2 73 nw 9 np1 45 nw 9 p1 205 nw 9 np2 420 nw 9 p2 76 sw 5 np1 53 sw 5 p1 130 sw 5 np2 120 sw 5 p2 50 sw 6 np1 40 sw 6 p1 350 sw 6 np2 225 sw 6 p2 80 ne 7 np1 90 ne 7 p1 190 ne 7 np2 420 ne 7 p2 86 ne 8 np1 200 ne 8 p1 300 ne 8 np2 420 ne 8 p2 125 ne 7 np1 90 ne 7 p1 190 ne 7 np2 420 ne 7 p2 86 ne 8 np1 200 ne 8 p1 300 ne 8 np2 420 ne 8 p2 125 ; run; /*libname proclib 'SAS-library';*/ options nodate pageno=1 linesize=80 pagesize=60 /* fmtsearch=(proclib)*/; proc format /*library=proclib*/; value $sctrfmt 'se' = 'Southeast' 'ne' = 'Northeast' 'nw' = 'Northwest' 'sw' = 'Southwest'; value $mgrfmt '1' = 'Smith' '2' = 'Jones' '3' = 'Reveiz' '4' = 'Brown' '5' = 'Taylor' '6' = 'Adams' '7' = 'Alomar' '8' = 'Andrews' '9' = 'Pelfrey'; value $deptfmt 'np1' = 'Paper' 'np2' = 'Canned' 'p1' = 'Meat/Dairy' 'p2' = 'Produce'; run; proc report data=grocery nowd headline headskip /* ls=130 ps=18;*/ ls=68 ps=18; column sector manager (n=count Sum Min Max Range Mean Std),sales; define manager / group format=$mgrfmt. id; define count / ":-( # of sales :-(" format=5.0; define sector / group format=$sctrfmt.; define sales / format=dollar11.2 ; title 'Sales Statistics for All Sectors'; run; /**********************************************************************/ options nodate pageno=1 linesize=64 pagesize=30 fmtsearch=(proclib); proc report data=grocery nowd headline headskip; title 'Sales for Individual Stores'; column sector manager department sales Profit; define sector / group noprint; define manager / group noprint; define profit / computed format=dollar11.2; define sales / analysis sum format=dollar11.2; define department / group format=$deptfmt.; compute profit; if department='np1' or department='np2' then profit=0.4*sales.sum; else profit=0.25*sales.sum; endcomp; compute before _page_ / left; line sector $sctrfmt. ' Sector'; line 'Store managed by ' manager $mgrfmt.; line ' '; line ' '; line ' '; endcomp; break after manager / ol summarize page; compute after manager; length text $ 35; if sales.sum lt 500 then text='Sales are below the target region.'; else if sales.sum ge 500 and sales.sum lt 1000 then text='Sales are in the target region.'; else if sales.sum ge 1000 then text='Sales exceeded goal!'; line ' '; line text $35.; endcomp; run; /********************************************************************************** * Program name : the proc report seminar - Art Carpenter's book * Project : * Written by : rl * Date of creation : * Description : * Macros called : * Input file : * Output file : * Revision History : * Date Author Description of the change * **********************************************************************************/ Footnote "Prog Name: %sysget(SAS_EXECFILENAME) **By: &SYSUSERID ** Run on: %sysfunc(datetime(),datetime16.)"; options nocenter ps=20; ods listing; ods html close; /***************************************************************** Section _A_: Create data ******************************************************************/ data A01_House1; infile datalines Missover firstobs=2; Input @1 Type $char5. @6 Zone $Char6. @14 price @21 Bath; datalines; 123456789012345678901234567890 Split 3 179950 3 Condo 1 214900 3 Split 1 100000 4 Split 1 82900 3 Condo 2 189900 4 Row 2 184000 3 ; run; /***************************************************************** Section _B_: Sample Report 1 detail level report with report break ******************************************************************/ Proc report data= a01_house1 nowd headline out=B01_out1; title "Section B Sample Report 1 -- detail level report with report break"; column zone type price bath; define zone / order width=5; define type / order ; define price/ display ; define bath / sum width=5; /*compute before ;*/ /* Zone="All";*/ /* Type="All";*/ /*EndComp;*/ Rbreak before /summarize dul; run; proc print data = B01_out1; run; /***************************************************************** Section _C_: Sample Report 2 Detail Level Report with a: break after variable RBREAK after and a compute ******************************************************************/ Proc report data= A01_house1 NOWD headline out=C01_out2; title "Sample report 2 Section C Report with a: break after variable RBREAK after and a compute"; where zone GE ' 2' ; column zone type price bath; define zone/order width=5; define type / order; define price/ sum ; define bath / mean width=5; Break after zone /summarize ol skip suppress; Rbreak after /summarize dol; compute after ; price.sum = .; Zone="ALL"; endcomp; run; /***************************************************************** Section _D_: Sample Report 3 Summary Level Report with Rbreak ******************************************************************/ Proc report data= A01_house1 nowd headline out=D01_Out3; title "Sample report 3 Section D Summary Level Report with Rbreak"; column zone price bath; define zone / Group width=5; /*define type / Group;*/ define price/ sum ; define bath /mean width=5; rbreak before /summarize ul; compute before ; Zone = 'ALL' ; endcomp; where zone LE ' 2'; run; **; Proc report data= A01_house1 nowd headline out=D01_Out3; title "Sample report 3 Section D Summary Level Report with Rbreak"; column zone type price bath; define zone / Group width=5; define type / Group; define price/ sum ; define bath /mean width=5; rbreak before /summarize ul; compute before ; Zone = 'ALL' ; endcomp; where zone LE ' 2'; run; **; Proc report data= A01_house1 nowd headline out=D01_Out3; title "Sample report 3 Section D Summary Level Report with Rbreak"; column zone type price bath; define zone / Group width=5; define type / order; define price/ sum ; define bath /mean width=5; rbreak before /summarize ul; compute before ; Zone = 'ALL' ; endcomp; where zone LE ' 2'; run; **; Proc report data= A01_house1 nowd headline out=D01_Out3; title "Sample report 3 Section D Summary Level Report with Rbreak"; column zone type price bath; define zone / order width=5; define type / group; define price/ sum ; define bath /mean width=5; rbreak before /summarize ul; compute before ; Zone = 'ALL' ; endcomp; where zone LE ' 2'; run; **; Proc report data= A01_house1 nowd headline out=D01_Out3; title "Sample report 3 Section D Summary Level Report with Rbreak"; column zone type price bath; define type / group; define zone / order width=5; define price/ sum ; define bath /mean width=5; rbreak before /summarize ul; compute before ; Zone = 'ALL' ; endcomp; where zone LE ' 2'; run; /***************************************************************** Section _E_: Sample Report 4a When do different types of computes happen ******************************************************************/ data E01_few; infile datalines missover FIRSTOBS=3; input @1 Sty $char5. /*Style Of House*/ @11 Regn $char1. /*region of the city*/ ; datalines; 12345678901234567890 Sty regn Condo 1 Condo 2 Row 2 Split 1 Split 1 Split 3 ; RUN; proc report data=E01_Few out=E01_out4a nowd spacing=2; title "Section _E_: Sample Report 4a When do different types of computes happen"; column sty regn detl rept grup n; define sty / order; define regn / order; define detl / computed; /*use how this is valued to determine the order of statement execution*/ define rept / computed; define grup / computed; compute before; endcomp; compute detl; detl=333; endcomp; compute rept; rept=10; endcomp; compute after sty; endcomp; compute after regn; rept=3; grup=4; endcomp; compute after; grup=3/21; rept=rept*2.2; endcomp; run; options ps=30 ls=120 nocenter;; proc print data=E01_out4a; run; /***************************************************************** Section _F_: Sample Report 4b IF STATEMENTS IN COMPUTE BLOCKS ******************************************************************/ proc report data=E01_Few out=F01_out4b nowd spacing=2; title "Section _F_: Sample Report 4b IF STATEMENTS IN COMPUTE BLOCKS"; column sty regn detl rept grup n; define sty / order; define regn / order; define detl / computed; /*use how this is valued to determine the order of statement execution*/ define rept / computed; define grup / computed; compute before; endcomp; compute detl; if sty="" and _Break_= "_RBREAK_" then detl=111; else if sty="" then detl=222; else if regn=. then detl=777; else detl=333; endcomp; compute rept; rept=10; endcomp; compute after sty; endcomp; compute after regn; rept=3; grup=4; endcomp; compute after; grup=3/21; rept=rept*2.2; endcomp; run; proc print data=F01_out4b; run; /***************************************************************** Section _G_: sample report 5 percentages and temp variables ******************************************************************/ Proc Report data=A01_House1 out=G01_out5b NOWD; column zone TYPE price PTot PZne; where zone LE ' 2'; define zone / order width=15; define TYPE / DISPLAY width=8; define price/ sum ; define PTot/computed ; define PZne/computed ; compute PZne; PTot=price.sum /AllPr; PZne=price.sum/ZnTot; endcomp; rbreak before / summarize ul; compute before ; Zone="ALL ZNE"; AllPr=price.sum; PTot=.; endcomp; compute before zone ; ZnTot=price.sum; endcomp; break After Zone / summarize Ol; compute AFTER ZONE ; Zone="ZONE="||zone; *LINE ""; endcomp; rbreak after /summarize dol; compute AFTER ; Zone="CITY SUM"; PZne=.; PTot=price.sum/AllPr; endcomp; run; /***************************************************************** Section _H_: sample report 6 ACROSS Variables ******************************************************************/ proc report data=A01_house1 out=H01_Example6_across nowd split="/"; column type zone price=count price bath; Define type /group width=12; define zone /across '# Prop./in Zone' width=2; define count /n '# Prop/on Mkt.' width=11; define price /analysis mean format=6.1 'Avg./Price' width=10; rbreak after / dol summarize skip; run; /***************************************************************** Section _I_: Example report 7 ******************************************************************/ proc format ; value $ZonUL " 1" = "_1_" " 2" = "_2_" " 3" = "_3_"; run; options ls=150 nocenter; proc report data=A01_House1 NOWD out=I01_Compute_under_an_across split="/" spacing=1 ; column type ('_ZONE IN CITY_' zone),(price=count price bath doll_bath) LAST ; Where zone in(' 1',' 2'); Define type /group width=8; define zone /across width=2 " " format=$ZonUL.; define bath /analysis sum "total/Baths" width=7; define count /n "# Prop/on Mkt." width=7; define doll_bath /computed "$ per/Bath" format=8.1; define price /analysis sum format=8.1 "Total/Price" width=10; define LAST /computed noprint; /*compute LAST; */ /* _c5_=_c3_/_c4_; */ /* _c9_=_c7_/_c8_; */ /*endcomp; */ rbreak after / dol summarize skip; RUN; QUIT; 178 1 Ç252 3 proc sort 1 332 1 27 /************ Proc sort *************************/ /*http://analytics.ncsu.edu/sesug/2006/CC14_06.PDF is a review*/ /**/ PROC SORT data=sashelp.class Ascii /*Use ASCII sorting/collating sequence - defaulot on PC*/ nodupkey /*or NODUPRECS - there is a trick here*/ out=SortedClass Dupout=work.RemovedObs /*send Obs removed by noDup or NoDupkey to this file*/ OVERWRITE /*Delete the input data set before the replacement output data set is populated.*/ Force /* Force redundant sorting When you specify FORCE, PROC SORT sorts and replaces the data set and destroys all user-created indexes for the data set. Indexes that were created or required by integrity constraints are preserved. */ NOEQUALS /*Speed trick -Do not maintain relative order within BY groups default is equals*/ SORTSIZE=Max /*Speed trick -Specify the available memory */ By Descending Height /*Ascending is default but you can sort by Descending var */ Threads /*enables or prevents (NoThreads) the activation of multi-threaded sorting.*/ /*Tagsort - Reduces temporary disk usage but is slow*/ ; run 376 1 B;252 3 proc sql 1 332 1 518 /********************** Proc SQL ****************************/ /*SQL is very powerful - read the SQL manual*****************/ /*buy the ten dollar V6 SQL manual for an quick way to learn*/ /* it is called "Getting started with SQL procedure" and is SAS #55042*/ /* Get papers via http://www.lexjansen.com/Phuse 2008; Read An Animated Guide: Knowing SQL internal processes makes SQL easy http://www2.sas.com/proceedings/sugi30/101-30.pdf or via http://www.lexjansen.com/Phuse 2008 Very good explanation of the where clause and indexing Where clause optimization is CRITICAL to making your query run quickly Power Indexing: A Guide to Using Indexes Effectively in Nashville Releases Diane Olson, http://www2.sas.com/proceedings/sugi25/25/dw/25p124.pdf Using the Magical Keyword "INTO:" in PROC SQL by Thiru Satchi, SUGI 27-paper71 Storing and Using a List of Values in a Macro Variable by Arthur L. Carpenter SUGI30- paper 028 SQL SET OPERATORS: SO HANDY VENN YOU NEED THEM by Howard Schreier, SUGI 31-paper242 Fuzzy Key Linkage: Robust Data Mining Methods for Real Databases by Sigurd Hermansen Existential Moments in Database Programming: SAS® PROC SQL EXISTS and NOT EXISTS Quantifiers, and More Sigurd W. Hermansen and Stanley E. Legum, SAS Global Forum 2008 paper 084 How Do I Look it Up If I Cannot Spell It:An Introduction to SAS® Dictionary Tables Peter Eberhardt & Ilene Brill SUGI 31 paper 259 SQL Step by Step: An advanced tutorial for business users by Lauren and Nelson WHAT WOULD I DO WITHOUT PROC SQL AND THE MACRO LANGUAGE By Jeff Abolafia SUGI31 - paper 30 Using Data Set Options in PROC SQL by Kenneth W. Borowiak SIGI 31 paper 131 */ /*Example 1: Housekeeping - Use SQL to create an index and delete files */ options msglevel=i NOCENTER; data class class2; set sashelp.class; run; Proc SQL; create index age on class(age); /*simple index*/ create index ageSex on class(age,sex); /*compound index*/ drop table work.class2; /*delete a table*/ quit; /*** Example 2: general SQL use***/ Proc SQL _method _tree /*shows optimizer execute plan*/ /*noprint*/ /*suppresses printing*/ number /*adds row number ot output*/ BUFFERSIZE=64M /* 65536=page size of 65536 bytes. 64k= page size of 65536 bytes. */ /*large values can makes SQL more likley to use hash object join*/ feedback /*Expands query in log*/ double /*double spaces output in list*/ inobs=15 /*Number of obs to read -makes for quick runs - useful in QC on large tables */ outobs=10 /*Number of obs to print or send to outfile - useful in QC*/ FLOW=5 /*character columns longer than n are flowed to multiple lines*/ /*- can be very useful*/ ; /*First semicolon is a long way from the Proc SQL*/ /*create table SQLExample as */ /*uncomment if you want to make a table*/ select Name as Subject_Name , * ,COUNT(*) AS SUBJ_PASSING_WHERE_FILTER , avg(Height) as AVERAGE_AGE from sashelp.class where sex="M" Group by height Having substr(name,1,1) NE "P"; quit; **** Example 3 Create a macro variables** ; data bigclass; Set sashelp.class; output; output; run; proc SQL noprint;/*qUERY DOES NOT FAIL, BUT DOES not DISTINCT*/ select distinct age , Sex , Name into :AgeList separated by " " ,:sexlist separated by " " ,:NameList separated by " " from bigclass; quit; %put Agelist &Agelist ; %put Sexlist &Sexlist ; %put namelist &namelist; proc SQL noprint;/*Works OK IN TWO STEPS*/ select distinct age into :DAgeList separated by " " from bigclass; select distinct Sex into :Dsexlist separated by " " from bigclass; quit; %put *******DISTINCTING**************; %put DAgelist &DAgelist ; %put DSexlist &DSexlist ; %put **************************; proc sql; /*this works but takes three passes through the data*/ /*No way to get this on one pass through the data*/ select Distinct name into :DistinctNamelist separated by " " from Bigclass; select Distinct Sex into :DistinctSexlist separated by " " from Bigclass ; select Distinct age into :Distinctagelist separated by " " from Bigclass ; run; %put &DistinctNamelist; %put &DistinctSexlist; %put &DistinctAgelist; **** Example 4 Create a macro variable and use it in a scan loop** ; proc SQL noprint; /*Has an error*/ select distinct name, sex, age into :Namelist /* without "separated", will only store one value. See example 3*/ ,:sexlist /* without "separated", will only store one value. See example 3*/ ,:AgeList separated by " " from SAShelp.class; quit; %put &NameList; %put &SexList; %put &AgeList; proc SQL noprint; select distinct age into :AgeList separated by " " from SAShelp.class; quit; %put &NameList; %put &SexList; %put &AgeList; %macro scanloop; %let counter=1; %do %while(%scan(&AgeList,&counter,%str( )) NE ); %let ThisAge=%scan(&AgeList,&counter,%str( )); %put &ThisAge; proc print data=sashelp.class; where age=&thisage; run; %let counter=%eval(&counter+1); %end; %mend scanloop; %scanloop; **** Example 4 Create a bunch of macro variables and use them in a macro loop** ; PROC SQL ; SELECT DISTINCT name , sex INTO :name1-:name99, :Gndr1-:Gndr99 /*Lazy - just make bigger than you need*/ FROM sashelp.class;quit; %put _user_ ; %put &SqlObs; %macro WhatIS; Options nosymbolgen nomlogic; %do i=1 %to &SqlObs; %put On loop number &i we see:; %put Name&i is &&Name&i and Gender &i is &&Gndr&i; %put; %end; %Mend WhatIs; %WhatIs; /*SQL makes six automatic macro vars(SQLOBS, SQLRC, SQLOOPS, SQLEXITCODE, SQLXRC,& SQLXMSG)*/ /*SQLOBS is # of rows that were processed by an SQL procedure statement. */ /*E.G. the # of rows that were formatted & displayed in output by a SELECT statement*/ /* the number of rows that were deleted by a DELETE statement. */ /* If an SQL view is created, then SQLOBS contains the value 0.*/ %macro showMe; options nomprint nomlogic nosymbolgen; %do I=1 %to &sqlobs; /*,- I use &sqlobs here to control the loop*/ %put In our loop, when i=&i ,we see &&name&i has gender = &&Gndr&i ; %end; %mend showMe; %showme; *******Example 5 Applying Quotes ****************; PROC SQL NOPRINT; SELECT DISTINCT name ,QUOTE(name) ,quote(strip(name)) ," ' " || (name) || " ' " ,age ,age FORMAT Z6.2 INTO :E1 SEPARATED BY " , " ,:E2 SEPARATED BY " , " ,:E3 SEPARATED BY " , " /*Best practice??*/ ,:E4 SEPARATED BY " , " ,:M1 SEPARATED BY " " ,:M2 SEPARATED BY " , " FROM sashelp.class(keep=name age); /*Thanks to Ken Borowiak*/ QUIT; %PUT &E1; %put; %PUT &E2; %put; %PUT &E3 ; /*Best??*/ %put; %PUT &E4 ; %put; %PUT &M1; %put; %PUT &M2; %put; *******Example 6 the CASE statement (SQL's verson of an IF statement) ****************; *Create some datasets with merge problems; data LeftFile(keep= name Sex); set sashelp.class; if mod(_n_,3)=0; run; data RightFile(keep= name height); set sashelp.class; if mod(_n_,4)=0; run; options nocenter; proc sql; select left(coalesce(l.name, r.name)) as CoalescedName ,sex ,height , case /*Could be replaced with a coalesce but this shows use of 'IS NOT NULL' */ when sex IS NOT NULL then sex else "?" end as CaseSex ,case /*Could be replaced with a coalesce but this shows use of 'IS NULL' */ when height IS NULL then . else height end as CaseHeight ,case when substr(coalesce(l.name, r.name),1,1)="J" then "This is one of our many J people" When substr(coalesce(l.name, r.name),1,1)="B" then "This name starts with a B " else "Who cares about this name " end as comment from (select * from LeftFile) as L full join (select * from RightFile) as R on l.name=r.name; quit; ****Example 7********************************************; Proc sql; create table SevenRows (Seven_a char(5) ,Seven_B num); proc SQL; insert into SevenRows values("Bob", 1) values("Sue", 2) values("Lee", 3) values("Sam", 4) values("Chi", 5) values("Ed ", 6) values("AJ ", 7) ; run; proc print data=SevenRows;run; Proc sql; create table FiveRows (Five_A char(3) ,Five_B num); insert into FiveRows Set Five_a="Bob",Five_B=11 Set Five_a="Sue",Five_B=12 Set Five_a="Lee",Five_B=13 Set Five_a="Sam",Five_B=14 Set Five_a="Chi",Five_B=15 ; quit; proc print data=FiveRows;run; ****Example 8 Some Joins ********************************************; data Left_File (keep=name sex ObsNo) Right_file(keep=name age ObsNo) ; set sashelp.class; ObsNo=_n_; if mod(_n_,3)=0 then output Left_File; if mod(_n_,4) in (0,1) then output Right_File; run; options nocenter; proc sql; title "Comma form of inner join - using Where syntax"; title2 "Most of the time we would use a coalesce on common varaibles"; select L.*, "*" as separator, R.* from Left_file as L , Right_file as R where L.name=R.name ; options nocenter; proc sql; title "Inner join form of inner join - using "on" syntax"; title2 "Most of the time we would use a coalesce on common variables"; title3 "SQL Joins are different from Data step joins"; title4 "The differences show up in many-to many merges"; select L.*, "*" as separator, R.* from Left_file as L Inner join Right_file as R on L.name=R.name ; options nocenter; proc sql; title "Left join"; title2 "Most of the time we would use a coalesce on variables in both data sets"; title3 "SQL Joins are different from Data step joins"; title4 "The differences show up in many-to many merges"; select L.*, "*" as separator, R.* from Left_file as L Left join Right_file as R on L.name=R.name ; options nocenter; proc sql; title "Right join"; title2 "Most of the time we would use a coalesce"; title3 "SQL Joins are different from Data step joins"; title4 "The differences show up in many-tomany merges"; select L.*, "*" as separator, R.* from Left_file as L Right join Right_file as R on L.name=R.name ; options nocenter; proc sql; title "Full join"; title2 "Most of the time we would use a coalesce"; title3 "SQL Joins are different from Data step joins"; title4 "The differences show up in many-to many merges"; select L.*, "*" as separator, R.* from Left_file as L Full join Right_file as R on L.name=R.name ; options nocenter; proc sql; title "Natural join"; title2 "Most of the time we would use a coalesce"; title3 "SQL Joins are different from Data step joins"; title4 "The differences show up in many-tomany merges"; select L.*, "*" as separator, R.* from Left_file as L Natural join Right_file as R /* on L.name=R.name */ ; *** Example 9 REFLEXIVE JOIN *********; *data Quality is important - in a real project check/CLEAN the mapping files *; data HospChain; infile datalines truncover firstobs=2; input @1 OrgID $char5. @10 ParID $char5. @20 Rx; /*Chn stands for Hospital Chain*/ datalines ; 1234567890123456789012345 /*Naming logic and QC Logic*/ Chn01 Chn01 100 /*Chn Stands for chain*/ Chn02 Chn02 200 Chn03 Chn03 000 Chn04 Chn04 99 /*Problem lilnking down -This chain has a hospital but no outpatient sites */ Chn05 Chn05 99 /*Problem lilnking down -This has no hospitals*/ ; run; data Hospitals; infile datalines truncover firstobs=2; input @1 OrgID $char5. @10 ParID $char5. @20 Rx; /*Hsp stands for hospital*/ datalines ; 1234567890123456789012345 /*Naming logic and QC Logic*/ Hsp1A Chn01 0 /*Hsp 1 rolls up to chain 1*/ Hsp2A Chn02 0 Hsp2B Chn02 30 Hsp3A Chn03 10 Hsp3B Chn03 20 Hsp3C Chn03 30 Hsp4E Chn04 99 /*Problem lilnking down - this Hospital has no outpatient sites*/ Hsp6E Chn06 99 /*Problem lilnking up -there is no hospital chain six*/ ; run; data OutpatientSites; infile datalines truncover firstobs=2; input @1 OrgID $char5. @10 ParID $char5. @20 Rx; /*OpS stands for Outpatient Sites*/ datalines ; 1234567890123456789012345 /*Naming logic and QC Logic*/ OpS1A Hsp1A 0 /*OpS 1 rolls up to Hsp 1 to chain 1 */ OpS1B Hsp1A 10 OpS1C Hsp1B 99 /*Deliberate Error - there is no HSP1B to roll up into*/ OpS2A Hsp2A 0 OpS2B Hsp2A 10 OpS2C Hsp2B 10 OpS3A Hsp3A 0 OpS3B Hsp3A 10 OpS3C Hsp3B 10 OpS3D Hsp3B 10 OpS3E Hsp3E 10 /*Deliberate Error - there is no HSP3E into which we can roll up*/ ; run; /*Assemble all the files into one */ Data AllRx; set HospChain Hospitals OutpatientSites; run; /*Create a mapping file - map any level to the hospital Chain - IN STAGES*/ /*we will use the mapping file to assign rx later */ Proc Sql; Create table OpS2Hosp as select Ops.OrgId as OrgID ,Ops.ParID as HospOrChainId from AllRx as Ops Left Join /**/ AllRx as Hsp on OPS.ParId = Hsp.OrgId ; Proc Sql; Create table OpS2Hosp2Chain as select O2H.OrgID ,O2H.HospOrChainId ,All.ParID as ChainID from OpS2Hosp as O2H /*Outpatient 2 hospital*/ Inner Join AllRx as All on O2H.HospOrChainId = All.OrgId order by OrgID ; /*Now bring in the Rx*/ proc SQL; Create table RxRolledUp as select Rx.* ,Ru.HospOrChainId ,Ru.ChainID from AllRx rx left join OpS2Hosp2Chain as RU on Rx.OrgID= Ru.OrgID order by Ru.ChainID, Ru.HospOrChainId, Rx.OrgID; ; Proc SQl; select "the Rx file has this total for rx" , sum(rx) from allRx union select "the Rolled up file has this total for rx" , sum(rx) from RxRolledUp ; /*Checked by eye as well*/ OPTIONS NOCENTER; proc print data=RxRolledUp; title "Chn04 Chn04 99 /*Problem lilnking down -This chain has a hospital but no outpatient sites */"; title2 "Chn05 Chn05 99 /*Problem lilnking down -This has no hospitals*/"; title4 "Hsp4E Chn04 99 /*Problem lilnking down - this Hospital has no outpatient sites*/"; title5 "Hsp6E Chn06 99 /*Problem lilnking up -there is no hospital chain six*/"; title7 "OpS1C Hsp1B 99 /*Deliberate Error - there is no HSP1B to roll up into*/"; title8 "OpS3E Hsp3E 10 /*Deliberate Error - there is no HSP3E into which we can roll up*/"; title10 "DATA QUALITY IS IMPORTANT - bad mapping files are easy to create and hard to bebug"; VAR ChainID Rx HospOrChainId ParID oRGid; run; ***** Example ??? Unions - Venn joins*****; /* Examples are coming but for now */ *google these strings "Howard Scirier" "so handy Venn " and read his paper */ 378 1 '252 3 proc standard 1 332 1 20 /*************** Proc Standard *********/ /************************************************************/ /*STANDARD standardizes variables to a given mean & std. dev.*/ data class; set sashelp.class; newHeight=height; run; Proc standard data=class out=StdClass mean=0 /*the new variable should have a mean of zero*/ std=3 /*the new variable should have a Std Dev of 3*/ print; Var NewHeight weight; run; proc print data=StdClass; sum NewHeight weight; run; 379 1 t252 3 proc summary 1 332 1 24 /************************* Proc Summary **************************/ /* Sumary is the same as means so also SEE PROC MEANS & Transpose************/ /*for production reports (and transposing) investigate:*/ /*class options:EXCLUSIVE & PRELOADFMT */ /*Summary options: CLASSDATA=, COMPLETETYPES, EXCLUSIVE, PRINTALLTYPES*/ data classic; set sashelp.class; if _n_ in (5,10) then age=.; IF MOD(_N_,5)=0 then weight=.; run; Proc Summary data=classic /*PRELOADFMT*/ missing ; /*make missing values of class variable show in output*/; class sex /order=unformatted descending; class age /order=freq ascending; /*grouping variables*/ output out=SmryExample /*output data set*/ N(age weight)=Nage Nsex /*Count NON-MISSING values of age and weight*/ sum(age height)=SumAge Sum_ht /*Sum age and height*/ Nmiss(Height weight)=MissHt Misswt /*Count missing values of Height and weight*/; types () Sex age Sex*age; /*specify exactly the rows of output you desire*/ run; proc print data=SmryExample; title "Note the order of the variables sex and age"; run; 370 1 à252 3 proc tabulate 1 332 1 166 /*******************Proc Tabulate**********************/ /*This is so powerful that it is hard to describe how options interact*/ /*Basics are simple, but management usually wants fancy*/ /*Classic articles are below*/ /*http://www2.sas.com/proceedings/sugi29/122-29.pdf Ray & DanB Report Vs tabulate*/ /*http://www2.sas.com/proceedings/sugi28/071-28.pdf ODS Lauren Report Vs tabulate*/ /*http://analytics.ncsu.edu/sesug/2001/P-601.pdf Drill Down Lauren*/ /*http://www2.sas.com/proceedings/sugi30/007-30.pdf Ray ODS table of contents*/ /*http://www.nesug.org/Proceedings/nesug06/dm/da05.pdf Wendi */ /*http://www2.sas.com/proceedings/forum2008/264-2008.pdf Wendi*/ /*http://www2.sas.com/proceedings/sugi27/p078-27.pdf Marianne*/ /*http://analytics.ncsu.edu/sesug/2006/SC15_06.PDF Russ*/ /*http://www2.sas.com/proceedings/sugi22/ADVTUTOR/PAPER45.PDF DanB*/ /*http://www2.sas.com/proceedings/sugi30/127-30.pdf Dan B*/ /*http://www2.sas.com/proceedings/forum2007/230-2007.pdf Jonas*/ /*http://www.nesug.org/proceedings/nesug04/pr/pr03.pdf Loise*/ /*http://www2.sas.com/proceedings/sugi30/258-30.pdf Dianne*/ /*http://www2.sas.com/proceedings/forum2008/171-2008.pdf Tom*/ /*http://www2.sas.com/proceedings/sugi22/POSTERS/PAPER223.PDF Pei,Ting Mike*/ /*http://www2.sas.com/proceedings/sugi23/Posters/p190.pdf Lisa*/ /*http://analytics.ncsu.edu/sesug/2000/p-306.pdf Carol & Joy */ /*http://www2.sas.com/proceedings/sugi31/058-31.pdf Zeros Marie & Sharon*/ /*http://www2.sas.com/proceedings/sugi29/085-29.pdf Style RayP & SandyM */ /*http://www2.sas.com/proceedings/sugi23/Posters/p211.pdf Univariate & Tab Barbara */ /*http://www2.sas.com/proceedings/sugi30/179-30.pdf E.G. Susan & Laura*/ /*Example 1: */ options ls=160; proc tabulate data=sashelp.class missing /*Noseps *& format crams more data on a page*/; class sex age; var height; table Sex="Gender of student" all , age="Ages Of Students"*(height*(n*format=6.0 mean*format=6.2 max*format=6.2)) all*(height*(n*format=2.0 mean*format=6.2 max*format=6.2))/*note layout*/ /rts=15 /*space for cols on left*/ box="example 1"; KEYLABEL N = "Count" MEAN ="Mean" max="Maximum" ALL = " Datset Total" ; run; /*Example 2 */ options ls=160; proc tabulate data=sashelp.class missing Noseps format=6.0; class sex age height; table Sex="Gender of student"*age="Ages Of Students" all , height all /rts=15 /*number of print positions available for row titles */ CONDENSE /*Print as many complete logical pages as possible on a single printed page*/ NOCONTINUED /*No continuation message for tables spaning multiple physical pages*/ PRINTMISS /*prints all values of class variable each time headings are printed*/ box="example 2"; run; /*Example 3 */ options ls=160; proc tabulate data=sashelp.class missing Noseps format=6.0; class sex age height; table Sex*age all , height="Counts of students by gender, age and height" all /rts=15 /*space for cols on left*/ INDENT=5 box="example 3"; run; /*Example 4 */ %let GroupBQ1=.25; %let GroupBQ2=.25; %let GroupBN = 50; data QStatExample; Do i=1 to &GroupAN; Q1Answer = (RAND('UNIFORM') LE &GroupAQ1 ); Q2Answer = (RAND('UNIFORM') LE &GroupAQ2 ); group="A"; Subjid = "GrA_"||Left(put(i,3.0)); output; End; Do j=1 to &GroupBN; Q1Answer = (RAND('UNIFORM') LE &GroupBQ1 ); Q2Answer = (RAND('UNIFORM') LE &GroupBQ2 ); group="B"; Subjid = "GrB_"||Left(put(j,3.0)); output; End; run; options ls=110; proc tabulate data=QStatExample missing; class Group Q1Answer Q2Answer; table (Group all) *Q1Answer ,Q2Answer*(n='Number of Subjects' pctn='Percent of Group Total') all*(n='Number of Subjects' pctn='Percent of Group Total'); run; /* Example 5 */ options nodate pageno=1 linesize=80 pagesize=60; data jobclass; input Gender Occupation @@; datalines; 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 3 1 3 1 3 1 3 1 3 1 3 1 3 1 1 1 1 1 1 1 2 1 2 1 2 1 2 1 2 1 2 1 3 1 3 1 4 1 4 1 4 1 4 1 4 1 4 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 3 1 3 1 3 1 3 1 4 1 4 1 4 1 4 1 4 1 1 1 3 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 2 2 2 2 2 3 2 3 2 3 2 4 2 4 2 4 2 4 2 4 2 4 2 1 2 3 2 3 2 3 2 3 2 3 2 4 2 4 2 4 2 4 2 4 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 3 2 4 2 4 2 4 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 2 3 2 3 2 3 2 3 2 4 ; Run; proc format; value gendfmt 1='Female' 2='Male' other='*** Data Entry Error ***'; value occupfmt 1='Technical' 2='Manager/Supervisor' 3='Clerical' 4='Administrative' other='*** Data Entry Error ***'; run; proc tabulate data=jobclass format=8.2; class gender occupation; table (occupation='Job Class' all='All Jobs') *(n='Number of employees'*f=9. pctn='Percent of row total' pctn='Percent of column total' pctn='Percent of total') ,gender='Gender' all='All Employees'/ rts=50; format gender gendfmt. occupation occupfmt.; title 'Gender Distribution'; title2 'within Job Classes'; run; 175 1 252 3 proc transpose 1 332 1 92 /************************* PROC TRANSPOSE ********************************/ /*Example 1: note the odd ordering look for the 11 year olds*/ proc Freq data=sashelp.class; tables sex*age / list out=FromFreq; where not (sex = "F" and Age=11); /*creates a data problem for the complettypes*/ run; proc print data=FromFreq; run; proc transpose /*the transposed variables will be in the order in which transpose sees values*/ /*if first obs does not have all values of varible being transposed output looks odd*/ /*Summary and completetypes makes for nice printout*/ data=FromFreq out=OddTrSumClass Prefix=Age_; Id age; /*helps if the data set is sorted by the ID var*/ var count; by sex; /*must be sorted by sex (and age- if first sex has all ages)*/ proc print data=OddTrSumClass; title "the column order is odd"; title2 "look for Age_11"; run; /*Example 2: note the use of competetyes to order columns in the transpose*/ proc summary data=sashelp.class missing completetypes; /*Adds 0 freq rows to first class - helps in ordering */ class sex age; output out=SumClass1 ; types Sex*age; where not (sex = "F" and Age=11); /*creates a data problem for the complettypes*/ run; proc print data=SumClass; title "Note: 11 year old females have freq of zero"; run; proc transpose /*Here, the transposed variables will be in the order in which transpose sees values*/ /*If first obs does not have all values of varible being transposed output looks odd*/ /*Summary and completetypes then a transpose make for nice printout*/ data=Sumclass out=TrSumClass Prefix=Age_; Id age; /*helps if the data set is sorted by the ID var*/ var _freq_; by sex; /*must be sorted by sex (and age- if first sex has all ages)*/ proc print data=TrSumClass; run; /*Example 3: note the odd ordering look for the 11 year olds*/ proc format; value PreLoad 10='10' 11='11' 12='12' 13='13' 14='14' 15='15' 16='16' 17='17'; ; run; proc summary data=sashelp.class missing completetypes; /*Adds 0 freq rows to first class - helps in ordering */ class sex ; class age /PreLoadFmt; output out=SumClass2 ; types Sex*age; where not (sex = "F" and Age=11); /*creates a data problem for the complettypes*/ format age PreLoad.; run; proc print data=SumClass2; title "Note: 11 year old females have freq of zero"; run; proc transpose /*Here, the transposed variables will be in the order in which transpose sees values*/ /*If first obs does not have all values of varible being transposed output looks odd*/ /*Summary and completetypes then a transpose make for nice printout*/ data=Sumclass2 out=TrSumClass2 Prefix=Age_; Id age; /*helps if the data set is sorted by the ID var*/ var _freq_; by sex; /*must be sorted by sex (and age- if first sex has all ages)*/ proc print data=TrSumClass2; run; 388 1 252 3 proc univariate 1 332 1 22 /********************* PROC UNIVARIATE ***************************/ /* very powerful and complex - suggest a reading of the documentation */ Proc sort data=sashelp.class out=class; by sex; run; Proc Univariate data=class ; by sex; freq age; histogram age height; QQplot height; ID name; var weight age height; run; options nocenter; ods select ExtremeObs MissingValues FREQuencies quantiles ; Proc Univariate data=Students freq; run; ods select all; 389 1 B252 3 propcase( 1 332 1 1 propCase( string< , delimiters> ) 92 1 k252 3 prxchange( 1 332 1 1 prxChange( perlRegularExpression | regularExpressionId , times , source ) 38 1 a252 3 prxmatch( 1 332 1 1 prxMatch( perlRegularExpression | regularExpressionId , source ) 39 1 >252 3 prxparen( 1 332 1 1 prxParen(regularExpressionId) 40 1 @252 3 prxparse( 1 332 1 1 prxParse(perlRegularExpression) 41 1 W252 3 prxposn( 1 332 1 1 prxPosn( regularExpressionId , captureBuffer , source ) 42 1 “252 3 putc( 1 332 1 143 /*INPUTC INPUTN Putc PutN Enables you to specify a character informat at run time. INPUTC(source, informat<,w>) source specifies a character constant, variable, or expression to which you want to apply the informat. informat is a character constant, variable, or expression that contains the character informat you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the informat. Interaction: If you specify a width here, it overrides any width specification in the informat. Using the INPUT function is faster because you specify the informat at compile time.*/ proc format; value typefmt 1='$groupx' 2='$groupy' 3='$groupz'; invalue $groupx 'positive'='agree' 'negative'='disagree' 'neutral'='notsure'; invalue $groupy 'positive'='accept' 'negative'='reject' 'neutral'='possible'; invalue $groupz 'positive'='pass' 'negative'='fail' 'neutral'='retest'; run; /*one file has several different types of tests*/ data TestValues; input MedTest response $; respinformat = put(MedTest, typefmt.); word = inputc(response, respinformat); datalines; 1 positive 1 negative 1 neutral 2 positive 2 negative 2 neutral 3 positive 3 negative 3 neutral ; run; proc print data=TestValues; run; /*INPUTN Function INPUTN(source, informat<,w<,d>>) Enables you to specify a numeric informat at run time. INPUTN(source, informat<,w<,d>>) source specifies a character constant, variable, or expression to which you want to apply the informat. informat is a character constant, variable or expression that contains the numeric informat you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the informat. Interaction: If you specify a width here, it overrides any width specification in the informat. d is a numeric constant, variable, or expression that specifies the number of decimal places to use. Interaction: If you specify a number here, it overrides any decimal-place specification in the informat. */ proc format; value readdate 1='date7.' 2='mmddyy8.'; run; options yearcutoff=1920; data fixdates (drop=start dateinformat); length jobdesc $12; input source id lname $ jobdesc $ start $; dateinformat=put(source, readdate.); newdate = inputn(start, dateinformat); datalines; 1 1604 Ziminski writer 09aug90 1 2010 Clavell editor 26jan95 2 1833 Rivera writer 10/25/92 2 2222 Barnes proofreader 3/26/98 ; proc print data=fixdates; run; /* PUTC Function PUTC(source, format.<,w>) Enables you to specify a character format at run time. source specifies a character constant, variable, or expression to which you want to apply the format. format. is a character constant, variable, or expression with a value that is the character format you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the format. Interaction: If you specify a width here, it overrides any width specification in the format. */ proc format; value typefmt 1='$groupx' 2='$groupy' 3='$groupz'; value $groupx 'positive'='agree' 'negative'='disagree' 'neutral'='notsure '; value $groupy 'positive'='accept' 'negative'='reject' 'neutral'='possible'; value $groupz 'positive'='pass ' 'negative'='fail' 'neutral'='retest'; run; data answers; length word $ 8; input type response $; respfmt = put(type, typefmt.); word = putc(response, respfmt); datalines; 1 positive 1 negative 1 neutral 2 positive 2 negative 2 neutral 3 positive 3 negative 3 neutral ; proc print data=answers; run; /* PUTN Function PUTN(source, format.<,w<,d>>) Enables you to specify a numeric format at run time. source specifies a numeric constant, variable, or expression to which you want to apply the format. format. is a character constant, variable, or expression with a value that is the numeric format you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the format. Interaction: If you specify a width here, it overrides any width specification in the format. d is a numeric constant, variable, or expression that specifies the number of decimal places to use. Interaction: If you specify a number here, it overrides any decimal-place specification in the format. */ proc format; value writfmt 1='date9.' 2='mmddyy10.'; run; data dates; input number key; datefmt=put(key,writfmt.); date=putn(number,datefmt); datalines; 15756 1 14552 2 ; proc print data=dates;run; 267 1 “252 3 putn( 1 332 1 143 /*INPUTC INPUTN Putc PutN Enables you to specify a character informat at run time. INPUTC(source, informat<,w>) source specifies a character constant, variable, or expression to which you want to apply the informat. informat is a character constant, variable, or expression that contains the character informat you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the informat. Interaction: If you specify a width here, it overrides any width specification in the informat. Using the INPUT function is faster because you specify the informat at compile time.*/ proc format; value typefmt 1='$groupx' 2='$groupy' 3='$groupz'; invalue $groupx 'positive'='agree' 'negative'='disagree' 'neutral'='notsure'; invalue $groupy 'positive'='accept' 'negative'='reject' 'neutral'='possible'; invalue $groupz 'positive'='pass' 'negative'='fail' 'neutral'='retest'; run; /*one file has several different types of tests*/ data TestValues; input MedTest response $; respinformat = put(MedTest, typefmt.); word = inputc(response, respinformat); datalines; 1 positive 1 negative 1 neutral 2 positive 2 negative 2 neutral 3 positive 3 negative 3 neutral ; run; proc print data=TestValues; run; /*INPUTN Function INPUTN(source, informat<,w<,d>>) Enables you to specify a numeric informat at run time. INPUTN(source, informat<,w<,d>>) source specifies a character constant, variable, or expression to which you want to apply the informat. informat is a character constant, variable or expression that contains the numeric informat you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the informat. Interaction: If you specify a width here, it overrides any width specification in the informat. d is a numeric constant, variable, or expression that specifies the number of decimal places to use. Interaction: If you specify a number here, it overrides any decimal-place specification in the informat. */ proc format; value readdate 1='date7.' 2='mmddyy8.'; run; options yearcutoff=1920; data fixdates (drop=start dateinformat); length jobdesc $12; input source id lname $ jobdesc $ start $; dateinformat=put(source, readdate.); newdate = inputn(start, dateinformat); datalines; 1 1604 Ziminski writer 09aug90 1 2010 Clavell editor 26jan95 2 1833 Rivera writer 10/25/92 2 2222 Barnes proofreader 3/26/98 ; proc print data=fixdates; run; /* PUTC Function PUTC(source, format.<,w>) Enables you to specify a character format at run time. source specifies a character constant, variable, or expression to which you want to apply the format. format. is a character constant, variable, or expression with a value that is the character format you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the format. Interaction: If you specify a width here, it overrides any width specification in the format. */ proc format; value typefmt 1='$groupx' 2='$groupy' 3='$groupz'; value $groupx 'positive'='agree' 'negative'='disagree' 'neutral'='notsure '; value $groupy 'positive'='accept' 'negative'='reject' 'neutral'='possible'; value $groupz 'positive'='pass ' 'negative'='fail' 'neutral'='retest'; run; data answers; length word $ 8; input type response $; respfmt = put(type, typefmt.); word = putc(response, respfmt); datalines; 1 positive 1 negative 1 neutral 2 positive 2 negative 2 neutral 3 positive 3 negative 3 neutral ; proc print data=answers; run; /* PUTN Function PUTN(source, format.<,w<,d>>) Enables you to specify a numeric format at run time. source specifies a numeric constant, variable, or expression to which you want to apply the format. format. is a character constant, variable, or expression with a value that is the numeric format you want to apply to source. w is a numeric constant, variable, or expression that specifies a width to apply to the format. Interaction: If you specify a width here, it overrides any width specification in the format. d is a numeric constant, variable, or expression that specifies the number of decimal places to use. Interaction: If you specify a number here, it overrides any decimal-place specification in the format. */ proc format; value writfmt 1='date9.' 2='mmddyy10.'; run; data dates; input number key; datefmt=put(key,writfmt.); date=putn(number,datefmt); datalines; 15756 1 14552 2 ; proc print data=dates;run; 268 1 )252 3 qtr( 1 332 1 1 qtr(sasDate) 133 1 H252 3 quantile( 1 332 1 1 quantile( 'Bernoulli|beta|binomial|Cauchy|chiSquare|exponential|F|gamma|geometric|hyperGeometric|LaPlace|logistic|logNormal|negBinomial|normal|Gauss|normalMix|Pareto|Poissont|uniform|Wald|iGauss|Weibull' , probability< , shapeLocationOrScaleParameter1< , shapeLocationOrScaleParameter2<...>>> ) 264 1 +252 3 quote( 1 332 1 1 quote(string) 93 1 V252 3 ranbin( 1 332 1 108 NORMAL Function variate that is generated from a normal distribution with mean 0 and variance 1. x=RANNOR(seed) RANBIN Function Returns a random variate from a binomial distribution. RANCAU Function Returns a random variate from a Cauchy distribution. RANPOI(seed,m) x=RanPoi(seed,m) m is a numeric constant, variable, or expression that specifies the mean RANEXP Function Returns a random variate from an exponential distribution. RAND (dist, parm-1,...,parm-k) Generates random numbers from a distribution that you specify. Distribution Argument Bernoulli x = RAND('BERNOULLI',p) p is a numeric probability of success. Beta BETA x = RAND('BETA',a,b) a is a numeric shape parameter. Range: a > 0 b is a numeric shape parameter. Range: b > 0 Binomial BINOMIAL x = RAND('BINOMIAL',p,n) x is an integer observation from the distribution p is a numeric probability of success. n is an integer parameter that counts the number of independent Bernoulli trials Cauchy CAUCHY x = RAND('CAUCHY') x is an observation from the distribution Chi-Square x = RAND('CHISQUARE',df) x is an observation from the distribution df is a numeric degrees of freedom parameter Erlang x = RAND('ERLANG',a) x is an observation from the distribution a is an integer numeric shape parameter Exponential x = RAND('EXPONENTIAL') x is an observation from the distribution x > 0 F x = RAND('F',ndf, ddf) x is an observation from the distribution ndf is a numeric numerator degrees of freedom parameter. Range: ndf > 0 ddf is a numeric DENOMINATOR degrees of freedom parameter. Range: Ddf > 0 Gamma x = RAND('GAMMA',a) x is an observation from the distribution Range: x > 0 a is a numeric shape parameter. Range: a > 0 Geometric x = RAND('GEOMETRIC',p) x is an integer count that denotes the number of trials that are needed to obtain one success. p is a numeric probability of success. Hypergeometric x = RAND('HYPER',N,R,n) x is an integer observation from the distribution N is an integer population size parameter. Range: N = 1, 2, ... R is an integer number of items in the category of interest. Range: R = 0, 1, ..., N n is an integer sample size parameter.Range: n = 1, 2, ..., N Rannor( Lognormal x = RAND('LOGNORMAL') Negative binomial x = RAND('NEGBINOMIAL',p,k) x is an integer observation from the distribution k is an integer parameter that is the number of successes. However, non-integer k values are allowed as well. Range: k = 1, 2, ... p is a numeric probability of success. Range: 0 < p 1 Normal x = RAND('NORMAL',<,m,s>) x is an observation from the normal distribution with a mean of m and a standard deviation of s m is the mean parameter. Default: 0 s is the standard deviation parameter. Default: 1 Range: s> 0 Poisson x = RAND('POISSON',m) x is an integer observation from the distribution M is a numeric mean parameter. Range: m > 0 T x = RAND('T',df) x is an observation from the distribution df is a numeric degrees of freedom parameter. Range: df > 0 Tabled TABLE x = RAND('TABLE',p1,p2, ...) x is an integer observation p1, p2, ... are numeric probability values. Range: 0 <= p1, p2, ... <= 1 The maximum number of probability parameters depends on your operating environment Triangular x = RAND('TRIANGLE',h) x is an observation from the distribution where 0 h 1. Range: 0 <= x <= 1 Note: The distribution can be easily shifted and scaled. h is the horizontal location of the peak of the triangle. Range: 0 h 1 Uniform x = RAND('UNIFORM') x is an observation from the distribution Range: 0 < x < 1 Weibull x = RAND('WEIBULL',a,b) x is an integer observation from the distribution a is a numeric shape parameter. Range: a > 0 b is a numeric scale parameter. Range: b > 0 RANTRI Function Returns a random variate from a triangular distribution. RANTRI(seed,h) h is a numeric constant, variable, or expression that specifies the mode of the distribution. range: 0 < h < 1 RANUNI Function returns a number the uniform distribution on the interval (0,1) x=RANUNI(seed) ; If you want to change the seed value during execution, you must use the CALL RANUNI routine instead of the RANUNI function. UNIFORM See RanUNI */ 279 1 V252 3 rancau( 1 332 1 108 NORMAL Function variate that is generated from a normal distribution with mean 0 and variance 1. x=RANNOR(seed) RANBIN Function Returns a random variate from a binomial distribution. RANCAU Function Returns a random variate from a Cauchy distribution. RANPOI(seed,m) x=RanPoi(seed,m) m is a numeric constant, variable, or expression that specifies the mean RANEXP Function Returns a random variate from an exponential distribution. RAND (dist, parm-1,...,parm-k) Generates random numbers from a distribution that you specify. Distribution Argument Bernoulli x = RAND('BERNOULLI',p) p is a numeric probability of success. Beta BETA x = RAND('BETA',a,b) a is a numeric shape parameter. Range: a > 0 b is a numeric shape parameter. Range: b > 0 Binomial BINOMIAL x = RAND('BINOMIAL',p,n) x is an integer observation from the distribution p is a numeric probability of success. n is an integer parameter that counts the number of independent Bernoulli trials Cauchy CAUCHY x = RAND('CAUCHY') x is an observation from the distribution Chi-Square x = RAND('CHISQUARE',df) x is an observation from the distribution df is a numeric degrees of freedom parameter Erlang x = RAND('ERLANG',a) x is an observation from the distribution a is an integer numeric shape parameter Exponential x = RAND('EXPONENTIAL') x is an observation from the distribution x > 0 F x = RAND('F',ndf, ddf) x is an observation from the distribution ndf is a numeric numerator degrees of freedom parameter. Range: ndf > 0 ddf is a numeric DENOMINATOR degrees of freedom parameter. Range: Ddf > 0 Gamma x = RAND('GAMMA',a) x is an observation from the distribution Range: x > 0 a is a numeric shape parameter. Range: a > 0 Geometric x = RAND('GEOMETRIC',p) x is an integer count that denotes the number of trials that are needed to obtain one success. p is a numeric probability of success. Hypergeometric x = RAND('HYPER',N,R,n) x is an integer observation from the distribution N is an integer population size parameter. Range: N = 1, 2, ... R is an integer number of items in the category of interest. Range: R = 0, 1, ..., N n is an integer sample size parameter.Range: n = 1, 2, ..., N Rannor( Lognormal x = RAND('LOGNORMAL') Negative binomial x = RAND('NEGBINOMIAL',p,k) x is an integer observation from the distribution k is an integer parameter that is the number of successes. However, non-integer k values are allowed as well. Range: k = 1, 2, ... p is a numeric probability of success. Range: 0 < p 1 Normal x = RAND('NORMAL',<,m,s>) x is an observation from the normal distribution with a mean of m and a standard deviation of s m is the mean parameter. Default: 0 s is the standard deviation parameter. Default: 1 Range: s> 0 Poisson x = RAND('POISSON',m) x is an integer observation from the distribution M is a numeric mean parameter. Range: m > 0 T x = RAND('T',df) x is an observation from the distribution df is a numeric degrees of freedom parameter. Range: df > 0 Tabled TABLE x = RAND('TABLE',p1,p2, ...) x is an integer observation p1, p2, ... are numeric probability values. Range: 0 <= p1, p2, ... <= 1 The maximum number of probability parameters depends on your operating environment Triangular x = RAND('TRIANGLE',h) x is an observation from the distribution where 0 h 1. Range: 0 <= x <= 1 Note: The distribution can be easily shifted and scaled. h is the horizontal location of the peak of the triangle. Range: 0 h 1 Uniform x = RAND('UNIFORM') x is an observation from the distribution Range: 0 < x < 1 Weibull x = RAND('WEIBULL',a,b) x is an integer observation from the distribution a is a numeric shape parameter. Range: a > 0 b is a numeric scale parameter. Range: b > 0 RANTRI Function Returns a random variate from a triangular distribution. RANTRI(seed,h) h is a numeric constant, variable, or expression that specifies the mode of the distribution. range: 0 < h < 1 RANUNI Function returns a number the uniform distribution on the interval (0,1) x=RANUNI(seed) ; If you want to change the seed value during execution, you must use the CALL RANUNI routine instead of the RANUNI function. UNIFORM See RanUNI */ 280 1 T252 3 rand( 1 332 1 108 NORMAL Function variate that is generated from a normal distribution with mean 0 and variance 1. x=RANNOR(seed) RANBIN Function Returns a random variate from a binomial distribution. RANCAU Function Returns a random variate from a Cauchy distribution. RANPOI(seed,m) x=RanPoi(seed,m) m is a numeric constant, variable, or expression that specifies the mean RANEXP Function Returns a random variate from an exponential distribution. RAND (dist, parm-1,...,parm-k) Generates random numbers from a distribution that you specify. Distribution Argument Bernoulli x = RAND('BERNOULLI',p) p is a numeric probability of success. Beta BETA x = RAND('BETA',a,b) a is a numeric shape parameter. Range: a > 0 b is a numeric shape parameter. Range: b > 0 Binomial BINOMIAL x = RAND('BINOMIAL',p,n) x is an integer observation from the distribution p is a numeric probability of success. n is an integer parameter that counts the number of independent Bernoulli trials Cauchy CAUCHY x = RAND('CAUCHY') x is an observation from the distribution Chi-Square x = RAND('CHISQUARE',df) x is an observation from the distribution df is a numeric degrees of freedom parameter Erlang x = RAND('ERLANG',a) x is an observation from the distribution a is an integer numeric shape parameter Exponential x = RAND('EXPONENTIAL') x is an observation from the distribution x > 0 F x = RAND('F',ndf, ddf) x is an observation from the distribution ndf is a numeric numerator degrees of freedom parameter. Range: ndf > 0 ddf is a numeric DENOMINATOR degrees of freedom parameter. Range: Ddf > 0 Gamma x = RAND('GAMMA',a) x is an observation from the distribution Range: x > 0 a is a numeric shape parameter. Range: a > 0 Geometric x = RAND('GEOMETRIC',p) x is an integer count that denotes the number of trials that are needed to obtain one success. p is a numeric probability of success. Hypergeometric x = RAND('HYPER',N,R,n) x is an integer observation from the distribution N is an integer population size parameter. Range: N = 1, 2, ... R is an integer number of items in the category of interest. Range: R = 0, 1, ..., N n is an integer sample size parameter.Range: n = 1, 2, ..., N Rannor( Lognormal x = RAND('LOGNORMAL') Negative binomial x = RAND('NEGBINOMIAL',p,k) x is an integer observation from the distribution k is an integer parameter that is the number of successes. However, non-integer k values are allowed as well. Range: k = 1, 2, ... p is a numeric probability of success. Range: 0 < p 1 Normal x = RAND('NORMAL',<,m,s>) x is an observation from the normal distribution with a mean of m and a standard deviation of s m is the mean parameter. Default: 0 s is the standard deviation parameter. Default: 1 Range: s> 0 Poisson x = RAND('POISSON',m) x is an integer observation from the distribution M is a numeric mean parameter. Range: m > 0 T x = RAND('T',df) x is an observation from the distribution df is a numeric degrees of freedom parameter. Range: df > 0 Tabled TABLE x = RAND('TABLE',p1,p2, ...) x is an integer observation p1, p2, ... are numeric probability values. Range: 0 <= p1, p2, ... <= 1 The maximum number of probability parameters depends on your operating environment Triangular x = RAND('TRIANGLE',h) x is an observation from the distribution where 0 h 1. Range: 0 <= x <= 1 Note: The distribution can be easily shifted and scaled. h is the horizontal location of the peak of the triangle. Range: 0 h 1 Uniform x = RAND('UNIFORM') x is an observation from the distribution Range: 0 < x < 1 Weibull x = RAND('WEIBULL',a,b) x is an integer observation from the distribution a is a numeric shape parameter. Range: a > 0 b is a numeric scale parameter. Range: b > 0 RANTRI Function Returns a random variate from a triangular distribution. RANTRI(seed,h) h is a numeric constant, variable, or expression that specifies the mode of the distribution. range: 0 < h < 1 RANUNI Function returns a number the uniform distribution on the interval (0,1) x=RANUNI(seed) ; If you want to change the seed value during execution, you must use the CALL RANUNI routine instead of the RANUNI function. UNIFORM See RanUNI */ 281 1 V252 3 ranexp( 1 332 1 108 NORMAL Function variate that is generated from a normal distribution with mean 0 and variance 1. x=RANNOR(seed) RANBIN Function Returns a random variate from a binomial distribution. RANCAU Function Returns a random variate from a Cauchy distribution. RANPOI(seed,m) x=RanPoi(seed,m) m is a numeric constant, variable, or expression that specifies the mean RANEXP Function Returns a random variate from an exponential distribution. RAND (dist, parm-1,...,parm-k) Generates random numbers from a distribution that you specify. Distribution Argument Bernoulli x = RAND('BERNOULLI',p) p is a numeric probability of success. Beta BETA x = RAND('BETA',a,b) a is a numeric shape parameter. Range: a > 0 b is a numeric shape parameter. Range: b > 0 Binomial BINOMIAL x = RAND('BINOMIAL',p,n) x is an integer observation from the distribution p is a numeric probability of success. n is an integer parameter that counts the number of independent Bernoulli trials Cauchy CAUCHY x = RAND('CAUCHY') x is an observation from the distribution Chi-Square x = RAND('CHISQUARE',df) x is an observation from the distribution df is a numeric degrees of freedom parameter Erlang x = RAND('ERLANG',a) x is an observation from the distribution a is an integer numeric shape parameter Exponential x = RAND('EXPONENTIAL') x is an observation from the distribution x > 0 F x = RAND('F',ndf, ddf) x is an observation from the distribution ndf is a numeric numerator degrees of freedom parameter. Range: ndf > 0 ddf is a numeric DENOMINATOR degrees of freedom parameter. Range: Ddf > 0 Gamma x = RAND('GAMMA',a) x is an observation from the distribution Range: x > 0 a is a numeric shape parameter. Range: a > 0 Geometric x = RAND('GEOMETRIC',p) x is an integer count that denotes the number of trials that are needed to obtain one success. p is a numeric probability of success. Hypergeometric x = RAND('HYPER',N,R,n) x is an integer observation from the distribution N is an integer population size parameter. Range: N = 1, 2, ... R is an integer number of items in the category of interest. Range: R = 0, 1, ..., N n is an integer sample size parameter.Range: n = 1, 2, ..., N Rannor( Lognormal x = RAND('LOGNORMAL') Negative binomial x = RAND('NEGBINOMIAL',p,k) x is an integer observation from the distribution k is an integer parameter that is the number of successes. However, non-integer k values are allowed as well. Range: k = 1, 2, ... p is a numeric probability of success. Range: 0 < p 1 Normal x = RAND('NORMAL',<,m,s>) x is an observation from the normal distribution with a mean of m and a standard deviation of s m is the mean parameter. Default: 0 s is the standard deviation parameter. Default: 1 Range: s> 0 Poisson x = RAND('POISSON',m) x is an integer observation from the distribution M is a numeric mean parameter. Range: m > 0 T x = RAND('T',df) x is an observation from the distribution df is a numeric degrees of freedom parameter. Range: df > 0 Tabled TABLE x = RAND('TABLE',p1,p2, ...) x is an integer observation p1, p2, ... are numeric probability values. Range: 0 <= p1, p2, ... <= 1 The maximum number of probability parameters depends on your operating environment Triangular x = RAND('TRIANGLE',h) x is an observation from the distribution where 0 h 1. Range: 0 <= x <= 1 Note: The distribution can be easily shifted and scaled. h is the horizontal location of the peak of the triangle. Range: 0 h 1 Uniform x = RAND('UNIFORM') x is an observation from the distribution Range: 0 < x < 1 Weibull x = RAND('WEIBULL',a,b) x is an integer observation from the distribution a is a numeric shape parameter. Range: a > 0 b is a numeric scale parameter. Range: b > 0 RANTRI Function Returns a random variate from a triangular distribution. RANTRI(seed,h) h is a numeric constant, variable, or expression that specifies the mode of the distribution. range: 0 < h < 1 RANUNI Function returns a number the uniform distribution on the interval (0,1) x=RANUNI(seed) ; If you want to change the seed value during execution, you must use the CALL RANUNI routine instead of the RANUNI function. UNIFORM See RanUNI */ 282 1 V252 3 rangam( 1 332 1 108 NORMAL Function variate that is generated from a normal distribution with mean 0 and variance 1. x=RANNOR(seed) RANBIN Function Returns a random variate from a binomial distribution. RANCAU Function Returns a random variate from a Cauchy distribution. RANPOI(seed,m) x=RanPoi(seed,m) m is a numeric constant, variable, or expression that specifies the mean RANEXP Function Returns a random variate from an exponential distribution. RAND (dist, parm-1,...,parm-k) Generates random numbers from a distribution that you specify. Distribution Argument Bernoulli x = RAND('BERNOULLI',p) p is a numeric probability of success. Beta BETA x = RAND('BETA',a,b) a is a numeric shape parameter. Range: a > 0 b is a numeric shape parameter. Range: b > 0 Binomial BINOMIAL x = RAND('BINOMIAL',p,n) x is an integer observation from the distribution p is a numeric probability of success. n is an integer parameter that counts the number of independent Bernoulli trials Cauchy CAUCHY x = RAND('CAUCHY') x is an observation from the distribution Chi-Square x = RAND('CHISQUARE',df) x is an observation from the distribution df is a numeric degrees of freedom parameter Erlang x = RAND('ERLANG',a) x is an observation from the distribution a is an integer numeric shape parameter Exponential x = RAND('EXPONENTIAL') x is an observation from the distribution x > 0 F x = RAND('F',ndf, ddf) x is an observation from the distribution ndf is a numeric numerator degrees of freedom parameter. Range: ndf > 0 ddf is a numeric DENOMINATOR degrees of freedom parameter. Range: Ddf > 0 Gamma x = RAND('GAMMA',a) x is an observation from the distribution Range: x > 0 a is a numeric shape parameter. Range: a > 0 Geometric x = RAND('GEOMETRIC',p) x is an integer count that denotes the number of trials that are needed to obtain one success. p is a numeric probability of success. Hypergeometric x = RAND('HYPER',N,R,n) x is an integer observation from the distribution N is an integer population size parameter. Range: N = 1, 2, ... R is an integer number of items in the category of interest. Range: R = 0, 1, ..., N n is an integer sample size parameter.Range: n = 1, 2, ..., N Rannor( Lognormal x = RAND('LOGNORMAL') Negative binomial x = RAND('NEGBINOMIAL',p,k) x is an integer observation from the distribution k is an integer parameter that is the number of successes. However, non-integer k values are allowed as well. Range: k = 1, 2, ... p is a numeric probability of success. Range: 0 < p 1 Normal x = RAND('NORMAL',<,m,s>) x is an observation from the normal distribution with a mean of m and a standard deviation of s m is the mean parameter. Default: 0 s is the standard deviation parameter. Default: 1 Range: s> 0 Poisson x = RAND('POISSON',m) x is an integer observation from the distribution M is a numeric mean parameter. Range: m > 0 T x = RAND('T',df) x is an observation from the distribution df is a numeric degrees of freedom parameter. Range: df > 0 Tabled TABLE x = RAND('TABLE',p1,p2, ...) x is an integer observation p1, p2, ... are numeric probability values. Range: 0 <= p1, p2, ... <= 1 The maximum number of probability parameters depends on your operating environment Triangular x = RAND('TRIANGLE',h) x is an observation from the distribution where 0 h 1. Range: 0 <= x <= 1 Note: The distribution can be easily shifted and scaled. h is the horizontal location of the peak of the triangle. Range: 0 h 1 Uniform x = RAND('UNIFORM') x is an observation from the distribution Range: 0 < x < 1 Weibull x = RAND('WEIBULL',a,b) x is an integer observation from the distribution a is a numeric shape parameter. Range: a > 0 b is a numeric scale parameter. Range: b > 0 RANTRI Function Returns a random variate from a triangular distribution. RANTRI(seed,h) h is a numeric constant, variable, or expression that specifies the mode of the distribution. range: 0 < h < 1 RANUNI Function returns a number the uniform distribution on the interval (0,1) x=RANUNI(seed) ; If you want to change the seed value during execution, you must use the CALL RANUNI routine instead of the RANUNI function. UNIFORM See RanUNI */ 283 1 "252 3 range( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 184 1 )252 3 rank( 1 332 1 1 rank(string) 94 1 V252 3 rannor( 1 332 1 108 NORMAL Function variate that is generated from a normal distribution with mean 0 and variance 1. x=RANNOR(seed) RANBIN Function Returns a random variate from a binomial distribution. RANCAU Function Returns a random variate from a Cauchy distribution. RANPOI(seed,m) x=RanPoi(seed,m) m is a numeric constant, variable, or expression that specifies the mean RANEXP Function Returns a random variate from an exponential distribution. RAND (dist, parm-1,...,parm-k) Generates random numbers from a distribution that you specify. Distribution Argument Bernoulli x = RAND('BERNOULLI',p) p is a numeric probability of success. Beta BETA x = RAND('BETA',a,b) a is a numeric shape parameter. Range: a > 0 b is a numeric shape parameter. Range: b > 0 Binomial BINOMIAL x = RAND('BINOMIAL',p,n) x is an integer observation from the distribution p is a numeric probability of success. n is an integer parameter that counts the number of independent Bernoulli trials Cauchy CAUCHY x = RAND('CAUCHY') x is an observation from the distribution Chi-Square x = RAND('CHISQUARE',df) x is an observation from the distribution df is a numeric degrees of freedom parameter Erlang x = RAND('ERLANG',a) x is an observation from the distribution a is an integer numeric shape parameter Exponential x = RAND('EXPONENTIAL') x is an observation from the distribution x > 0 F x = RAND('F',ndf, ddf) x is an observation from the distribution ndf is a numeric numerator degrees of freedom parameter. Range: ndf > 0 ddf is a numeric DENOMINATOR degrees of freedom parameter. Range: Ddf > 0 Gamma x = RAND('GAMMA',a) x is an observation from the distribution Range: x > 0 a is a numeric shape parameter. Range: a > 0 Geometric x = RAND('GEOMETRIC',p) x is an integer count that denotes the number of trials that are needed to obtain one success. p is a numeric probability of success. Hypergeometric x = RAND('HYPER',N,R,n) x is an integer observation from the distribution N is an integer population size parameter. Range: N = 1, 2, ... R is an integer number of items in the category of interest. Range: R = 0, 1, ..., N n is an integer sample size parameter.Range: n = 1, 2, ..., N Rannor( Lognormal x = RAND('LOGNORMAL') Negative binomial x = RAND('NEGBINOMIAL',p,k) x is an integer observation from the distribution k is an integer parameter that is the number of successes. However, non-integer k values are allowed as well. Range: k = 1, 2, ... p is a numeric probability of success. Range: 0 < p 1 Normal x = RAND('NORMAL',<,m,s>) x is an observation from the normal distribution with a mean of m and a standard deviation of s m is the mean parameter. Default: 0 s is the standard deviation parameter. Default: 1 Range: s> 0 Poisson x = RAND('POISSON',m) x is an integer observation from the distribution M is a numeric mean parameter. Range: m > 0 T x = RAND('T',df) x is an observation from the distribution df is a numeric degrees of freedom parameter. Range: df > 0 Tabled TABLE x = RAND('TABLE',p1,p2, ...) x is an integer observation p1, p2, ... are numeric probability values. Range: 0 <= p1, p2, ... <= 1 The maximum number of probability parameters depends on your operating environment Triangular x = RAND('TRIANGLE',h) x is an observation from the distribution where 0 h 1. Range: 0 <= x <= 1 Note: The distribution can be easily shifted and scaled. h is the horizontal location of the peak of the triangle. Range: 0 h 1 Uniform x = RAND('UNIFORM') x is an observation from the distribution Range: 0 < x < 1 Weibull x = RAND('WEIBULL',a,b) x is an integer observation from the distribution a is a numeric shape parameter. Range: a > 0 b is a numeric scale parameter. Range: b > 0 RANTRI Function Returns a random variate from a triangular distribution. RANTRI(seed,h) h is a numeric constant, variable, or expression that specifies the mode of the distribution. range: 0 < h < 1 RANUNI Function returns a number the uniform distribution on the interval (0,1) x=RANUNI(seed) ; If you want to change the seed value during execution, you must use the CALL RANUNI routine instead of the RANUNI function. UNIFORM See RanUNI */ 284 1 V252 3 ranpoi( 1 332 1 108 NORMAL Function variate that is generated from a normal distribution with mean 0 and variance 1. x=RANNOR(seed) RANBIN Function Returns a random variate from a binomial distribution. RANCAU Function Returns a random variate from a Cauchy distribution. RANPOI(seed,m) x=RanPoi(seed,m) m is a numeric constant, variable, or expression that specifies the mean RANEXP Function Returns a random variate from an exponential distribution. RAND (dist, parm-1,...,parm-k) Generates random numbers from a distribution that you specify. Distribution Argument Bernoulli x = RAND('BERNOULLI',p) p is a numeric probability of success. Beta BETA x = RAND('BETA',a,b) a is a numeric shape parameter. Range: a > 0 b is a numeric shape parameter. Range: b > 0 Binomial BINOMIAL x = RAND('BINOMIAL',p,n) x is an integer observation from the distribution p is a numeric probability of success. n is an integer parameter that counts the number of independent Bernoulli trials Cauchy CAUCHY x = RAND('CAUCHY') x is an observation from the distribution Chi-Square x = RAND('CHISQUARE',df) x is an observation from the distribution df is a numeric degrees of freedom parameter Erlang x = RAND('ERLANG',a) x is an observation from the distribution a is an integer numeric shape parameter Exponential x = RAND('EXPONENTIAL') x is an observation from the distribution x > 0 F x = RAND('F',ndf, ddf) x is an observation from the distribution ndf is a numeric numerator degrees of freedom parameter. Range: ndf > 0 ddf is a numeric DENOMINATOR degrees of freedom parameter. Range: Ddf > 0 Gamma x = RAND('GAMMA',a) x is an observation from the distribution Range: x > 0 a is a numeric shape parameter. Range: a > 0 Geometric x = RAND('GEOMETRIC',p) x is an integer count that denotes the number of trials that are needed to obtain one success. p is a numeric probability of success. Hypergeometric x = RAND('HYPER',N,R,n) x is an integer observation from the distribution N is an integer population size parameter. Range: N = 1, 2, ... R is an integer number of items in the category of interest. Range: R = 0, 1, ..., N n is an integer sample size parameter.Range: n = 1, 2, ..., N Rannor( Lognormal x = RAND('LOGNORMAL') Negative binomial x = RAND('NEGBINOMIAL',p,k) x is an integer observation from the distribution k is an integer parameter that is the number of successes. However, non-integer k values are allowed as well. Range: k = 1, 2, ... p is a numeric probability of success. Range: 0 < p 1 Normal x = RAND('NORMAL',<,m,s>) x is an observation from the normal distribution with a mean of m and a standard deviation of s m is the mean parameter. Default: 0 s is the standard deviation parameter. Default: 1 Range: s> 0 Poisson x = RAND('POISSON',m) x is an integer observation from the distribution M is a numeric mean parameter. Range: m > 0 T x = RAND('T',df) x is an observation from the distribution df is a numeric degrees of freedom parameter. Range: df > 0 Tabled TABLE x = RAND('TABLE',p1,p2, ...) x is an integer observation p1, p2, ... are numeric probability values. Range: 0 <= p1, p2, ... <= 1 The maximum number of probability parameters depends on your operating environment Triangular x = RAND('TRIANGLE',h) x is an observation from the distribution where 0 h 1. Range: 0 <= x <= 1 Note: The distribution can be easily shifted and scaled. h is the horizontal location of the peak of the triangle. Range: 0 h 1 Uniform x = RAND('UNIFORM') x is an observation from the distribution Range: 0 < x < 1 Weibull x = RAND('WEIBULL',a,b) x is an integer observation from the distribution a is a numeric shape parameter. Range: a > 0 b is a numeric scale parameter. Range: b > 0 RANTRI Function Returns a random variate from a triangular distribution. RANTRI(seed,h) h is a numeric constant, variable, or expression that specifies the mode of the distribution. range: 0 < h < 1 RANUNI Function returns a number the uniform distribution on the interval (0,1) x=RANUNI(seed) ; If you want to change the seed value during execution, you must use the CALL RANUNI routine instead of the RANUNI function. UNIFORM See RanUNI */ 285 1 V252 3 rantbl( 1 332 1 108 NORMAL Function variate that is generated from a normal distribution with mean 0 and variance 1. x=RANNOR(seed) RANBIN Function Returns a random variate from a binomial distribution. RANCAU Function Returns a random variate from a Cauchy distribution. RANPOI(seed,m) x=RanPoi(seed,m) m is a numeric constant, variable, or expression that specifies the mean RANEXP Function Returns a random variate from an exponential distribution. RAND (dist, parm-1,...,parm-k) Generates random numbers from a distribution that you specify. Distribution Argument Bernoulli x = RAND('BERNOULLI',p) p is a numeric probability of success. Beta BETA x = RAND('BETA',a,b) a is a numeric shape parameter. Range: a > 0 b is a numeric shape parameter. Range: b > 0 Binomial BINOMIAL x = RAND('BINOMIAL',p,n) x is an integer observation from the distribution p is a numeric probability of success. n is an integer parameter that counts the number of independent Bernoulli trials Cauchy CAUCHY x = RAND('CAUCHY') x is an observation from the distribution Chi-Square x = RAND('CHISQUARE',df) x is an observation from the distribution df is a numeric degrees of freedom parameter Erlang x = RAND('ERLANG',a) x is an observation from the distribution a is an integer numeric shape parameter Exponential x = RAND('EXPONENTIAL') x is an observation from the distribution x > 0 F x = RAND('F',ndf, ddf) x is an observation from the distribution ndf is a numeric numerator degrees of freedom parameter. Range: ndf > 0 ddf is a numeric DENOMINATOR degrees of freedom parameter. Range: Ddf > 0 Gamma x = RAND('GAMMA',a) x is an observation from the distribution Range: x > 0 a is a numeric shape parameter. Range: a > 0 Geometric x = RAND('GEOMETRIC',p) x is an integer count that denotes the number of trials that are needed to obtain one success. p is a numeric probability of success. Hypergeometric x = RAND('HYPER',N,R,n) x is an integer observation from the distribution N is an integer population size parameter. Range: N = 1, 2, ... R is an integer number of items in the category of interest. Range: R = 0, 1, ..., N n is an integer sample size parameter.Range: n = 1, 2, ..., N Rannor( Lognormal x = RAND('LOGNORMAL') Negative binomial x = RAND('NEGBINOMIAL',p,k) x is an integer observation from the distribution k is an integer parameter that is the number of successes. However, non-integer k values are allowed as well. Range: k = 1, 2, ... p is a numeric probability of success. Range: 0 < p 1 Normal x = RAND('NORMAL',<,m,s>) x is an observation from the normal distribution with a mean of m and a standard deviation of s m is the mean parameter. Default: 0 s is the standard deviation parameter. Default: 1 Range: s> 0 Poisson x = RAND('POISSON',m) x is an integer observation from the distribution M is a numeric mean parameter. Range: m > 0 T x = RAND('T',df) x is an observation from the distribution df is a numeric degrees of freedom parameter. Range: df > 0 Tabled TABLE x = RAND('TABLE',p1,p2, ...) x is an integer observation p1, p2, ... are numeric probability values. Range: 0 <= p1, p2, ... <= 1 The maximum number of probability parameters depends on your operating environment Triangular x = RAND('TRIANGLE',h) x is an observation from the distribution where 0 h 1. Range: 0 <= x <= 1 Note: The distribution can be easily shifted and scaled. h is the horizontal location of the peak of the triangle. Range: 0 h 1 Uniform x = RAND('UNIFORM') x is an observation from the distribution Range: 0 < x < 1 Weibull x = RAND('WEIBULL',a,b) x is an integer observation from the distribution a is a numeric shape parameter. Range: a > 0 b is a numeric scale parameter. Range: b > 0 RANTRI Function Returns a random variate from a triangular distribution. RANTRI(seed,h) h is a numeric constant, variable, or expression that specifies the mode of the distribution. range: 0 < h < 1 RANUNI Function returns a number the uniform distribution on the interval (0,1) x=RANUNI(seed) ; If you want to change the seed value during execution, you must use the CALL RANUNI routine instead of the RANUNI function. UNIFORM See RanUNI */ 286 1 V252 3 rantri( 1 332 1 108 NORMAL Function variate that is generated from a normal distribution with mean 0 and variance 1. x=RANNOR(seed) RANBIN Function Returns a random variate from a binomial distribution. RANCAU Function Returns a random variate from a Cauchy distribution. RANPOI(seed,m) x=RanPoi(seed,m) m is a numeric constant, variable, or expression that specifies the mean RANEXP Function Returns a random variate from an exponential distribution. RAND (dist, parm-1,...,parm-k) Generates random numbers from a distribution that you specify. Distribution Argument Bernoulli x = RAND('BERNOULLI',p) p is a numeric probability of success. Beta BETA x = RAND('BETA',a,b) a is a numeric shape parameter. Range: a > 0 b is a numeric shape parameter. Range: b > 0 Binomial BINOMIAL x = RAND('BINOMIAL',p,n) x is an integer observation from the distribution p is a numeric probability of success. n is an integer parameter that counts the number of independent Bernoulli trials Cauchy CAUCHY x = RAND('CAUCHY') x is an observation from the distribution Chi-Square x = RAND('CHISQUARE',df) x is an observation from the distribution df is a numeric degrees of freedom parameter Erlang x = RAND('ERLANG',a) x is an observation from the distribution a is an integer numeric shape parameter Exponential x = RAND('EXPONENTIAL') x is an observation from the distribution x > 0 F x = RAND('F',ndf, ddf) x is an observation from the distribution ndf is a numeric numerator degrees of freedom parameter. Range: ndf > 0 ddf is a numeric DENOMINATOR degrees of freedom parameter. Range: Ddf > 0 Gamma x = RAND('GAMMA',a) x is an observation from the distribution Range: x > 0 a is a numeric shape parameter. Range: a > 0 Geometric x = RAND('GEOMETRIC',p) x is an integer count that denotes the number of trials that are needed to obtain one success. p is a numeric probability of success. Hypergeometric x = RAND('HYPER',N,R,n) x is an integer observation from the distribution N is an integer population size parameter. Range: N = 1, 2, ... R is an integer number of items in the category of interest. Range: R = 0, 1, ..., N n is an integer sample size parameter.Range: n = 1, 2, ..., N Rannor( Lognormal x = RAND('LOGNORMAL') Negative binomial x = RAND('NEGBINOMIAL',p,k) x is an integer observation from the distribution k is an integer parameter that is the number of successes. However, non-integer k values are allowed as well. Range: k = 1, 2, ... p is a numeric probability of success. Range: 0 < p 1 Normal x = RAND('NORMAL',<,m,s>) x is an observation from the normal distribution with a mean of m and a standard deviation of s m is the mean parameter. Default: 0 s is the standard deviation parameter. Default: 1 Range: s> 0 Poisson x = RAND('POISSON',m) x is an integer observation from the distribution M is a numeric mean parameter. Range: m > 0 T x = RAND('T',df) x is an observation from the distribution df is a numeric degrees of freedom parameter. Range: df > 0 Tabled TABLE x = RAND('TABLE',p1,p2, ...) x is an integer observation p1, p2, ... are numeric probability values. Range: 0 <= p1, p2, ... <= 1 The maximum number of probability parameters depends on your operating environment Triangular x = RAND('TRIANGLE',h) x is an observation from the distribution where 0 h 1. Range: 0 <= x <= 1 Note: The distribution can be easily shifted and scaled. h is the horizontal location of the peak of the triangle. Range: 0 h 1 Uniform x = RAND('UNIFORM') x is an observation from the distribution Range: 0 < x < 1 Weibull x = RAND('WEIBULL',a,b) x is an integer observation from the distribution a is a numeric shape parameter. Range: a > 0 b is a numeric scale parameter. Range: b > 0 RANTRI Function Returns a random variate from a triangular distribution. RANTRI(seed,h) h is a numeric constant, variable, or expression that specifies the mode of the distribution. range: 0 < h < 1 RANUNI Function returns a number the uniform distribution on the interval (0,1) x=RANUNI(seed) ; If you want to change the seed value during execution, you must use the CALL RANUNI routine instead of the RANUNI function. UNIFORM See RanUNI */ 287 1 V252 3 ranuni( 1 332 1 108 NORMAL Function variate that is generated from a normal distribution with mean 0 and variance 1. x=RANNOR(seed) RANBIN Function Returns a random variate from a binomial distribution. RANCAU Function Returns a random variate from a Cauchy distribution. RANPOI(seed,m) x=RanPoi(seed,m) m is a numeric constant, variable, or expression that specifies the mean RANEXP Function Returns a random variate from an exponential distribution. RAND (dist, parm-1,...,parm-k) Generates random numbers from a distribution that you specify. Distribution Argument Bernoulli x = RAND('BERNOULLI',p) p is a numeric probability of success. Beta BETA x = RAND('BETA',a,b) a is a numeric shape parameter. Range: a > 0 b is a numeric shape parameter. Range: b > 0 Binomial BINOMIAL x = RAND('BINOMIAL',p,n) x is an integer observation from the distribution p is a numeric probability of success. n is an integer parameter that counts the number of independent Bernoulli trials Cauchy CAUCHY x = RAND('CAUCHY') x is an observation from the distribution Chi-Square x = RAND('CHISQUARE',df) x is an observation from the distribution df is a numeric degrees of freedom parameter Erlang x = RAND('ERLANG',a) x is an observation from the distribution a is an integer numeric shape parameter Exponential x = RAND('EXPONENTIAL') x is an observation from the distribution x > 0 F x = RAND('F',ndf, ddf) x is an observation from the distribution ndf is a numeric numerator degrees of freedom parameter. Range: ndf > 0 ddf is a numeric DENOMINATOR degrees of freedom parameter. Range: Ddf > 0 Gamma x = RAND('GAMMA',a) x is an observation from the distribution Range: x > 0 a is a numeric shape parameter. Range: a > 0 Geometric x = RAND('GEOMETRIC',p) x is an integer count that denotes the number of trials that are needed to obtain one success. p is a numeric probability of success. Hypergeometric x = RAND('HYPER',N,R,n) x is an integer observation from the distribution N is an integer population size parameter. Range: N = 1, 2, ... R is an integer number of items in the category of interest. Range: R = 0, 1, ..., N n is an integer sample size parameter.Range: n = 1, 2, ..., N Rannor( Lognormal x = RAND('LOGNORMAL') Negative binomial x = RAND('NEGBINOMIAL',p,k) x is an integer observation from the distribution k is an integer parameter that is the number of successes. However, non-integer k values are allowed as well. Range: k = 1, 2, ... p is a numeric probability of success. Range: 0 < p 1 Normal x = RAND('NORMAL',<,m,s>) x is an observation from the normal distribution with a mean of m and a standard deviation of s m is the mean parameter. Default: 0 s is the standard deviation parameter. Default: 1 Range: s> 0 Poisson x = RAND('POISSON',m) x is an integer observation from the distribution M is a numeric mean parameter. Range: m > 0 T x = RAND('T',df) x is an observation from the distribution df is a numeric degrees of freedom parameter. Range: df > 0 Tabled TABLE x = RAND('TABLE',p1,p2, ...) x is an integer observation p1, p2, ... are numeric probability values. Range: 0 <= p1, p2, ... <= 1 The maximum number of probability parameters depends on your operating environment Triangular x = RAND('TRIANGLE',h) x is an observation from the distribution where 0 h 1. Range: 0 <= x <= 1 Note: The distribution can be easily shifted and scaled. h is the horizontal location of the peak of the triangle. Range: 0 h 1 Uniform x = RAND('UNIFORM') x is an observation from the distribution Range: 0 < x < 1 Weibull x = RAND('WEIBULL',a,b) x is an integer observation from the distribution a is a numeric shape parameter. Range: a > 0 b is a numeric scale parameter. Range: b > 0 RANTRI Function Returns a random variate from a triangular distribution. RANTRI(seed,h) h is a numeric constant, variable, or expression that specifies the mode of the distribution. range: 0 < h < 1 RANUNI Function returns a number the uniform distribution on the interval (0,1) x=RANUNI(seed) ; If you want to change the seed value during execution, you must use the CALL RANUNI routine instead of the RANUNI function. UNIFORM See RanUNI */ 288 1 x252 3 repeat( 1 332 1 51 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ ThisInstant=DateTime(); /*Reads system clock*/ put TodayDate= TodayToday= ThisInstant=; break=repeat("*",40); put break; DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; run; 102 1 ı252 3 resolve( 1 332 1 14 /*Call Symput, symget, resolve */ data _null_; length CVarInPDV1 $6; call symput ("DogName","spot"); call Symput ("DogAge",5); put "Before Symget " CVarInPDV1= ; CVarInPDV1=symget("DogName"); put "After Symget " CVarInPDV1= ; NVarInPDV1=symget("DogAge"); put "After Symget " NVarInPDV1= ; /*I do not know anyone who uses resolve*/ /*see The RESOLVE Function - What Is It Good For?*/ /*http://www.nesug.org/proceedings/nesug98/code/p088.pdf*/ run; 201 1 h252 3 reverse( 1 332 1 16 /*Reverse*/ data RevFunctn; infile datalines truncover; input @1 FileName $char20.; reversed=reverse(FileName); if left(upcase(reverse(FileName))) =:"SAS" then put "We found a sas file named: " Filename; datalines; someXLSFile.xls someSASFile.sas someAccessFile.mdb ; run; proc print data=RevFunctn; run; 103 1 ,252 3 right( 1 332 1 1 right(string) 104 1 <252 3 rms( 1 332 1 1 rms( number1< , number2<...>> ) 185 1 "252 3 round( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 322 1 A252 3 rounde( 1 332 1 1 roundE( number< , roundingUnit> ) 323 1 A252 3 roundz( 1 332 1 1 roundZ( number< , roundingUnit> ) 324 1 F252 3 rxmatch( 1 332 1 1 rxMatch(regularExpressionId , string ) 45 1 :252 3 rxparse( 1 332 1 1 rxParse(patternExpression) 46 1 p252 3 scan( 1 332 1 50 scan( string , wordNumber< , delimiters> ) Returns the nth word from a character string. Definition of "Delimiter" and "Word" A delimiter is any of several characters that are used to separate words. You can specify the delimiters in the charlist and modifier arguments. If you specify the Q modifier, then delimiters inside of substrings that are enclosed in quotation marks are ignored. In the SCAN function, "word" refers to a substring that has all of the following characteristics: is bounded on the left by a delimiter or the beginning of the string is bounded on the right by a delimiter or the end of the string contains no delimiters A word can have a length of zero if there are delimiters at the beginning or end of the string, or if the string contains two or more consecutive delimiters. However, the SCAN function ignores words that have a length of zero unless you specify the M modifier. Note: The definition of "word" is the same in both the SCAN and COUNTW functions. Using Default Delimiters in ASCII and EBCDIC Environments If you use the SCAN function with only two arguments, then the default delimiters depend on whether your computer uses ASCII or EBCDIC characters. If your computer uses ASCII characters, then the default delimiters are as follows: blank ! $ % & ( ) * + , - . / ; < ^ In ASCII environments that do not contain the ^ character, the SCAN function uses the ~ character instead. If your computer uses EBCDIC characters, then the default delimiters are as follows: blank ! $ % & ( ) * + , - . / ; < ¬ | ¢ data firstlast; input String $60.; First_Word = scan(string, 1); Last_Word = scan(string, -1); datalines4; Jack and Jill & Bob & Carol & Ted & Alice & Leonardo ! $ % & ( ) * + , - . / ; ;;;; proc print data=firstlast; run; 105 1 J252 3 scanq( 1 332 1 1 scanQ( string , wordNumber< , delimiters> ) 106 1 ;252 3 sdf( 1 332 1 1 sdf( 'Bernoulli|beta|binomial|Cauchy|chiSquare|exponential|F|gamma|geometric|hyperGeometric|LaPlace|logistic|logNormal|negBinomial|normal|Gauss|normalMix|Pareto|Poissont|uniform|Wald|iGauss|Weibull' , quantile< , shapeLocationOrScaleParameter1< , shapeLocationOrScaleParameter2<...>>> ) 258 1 µ252 3 SECBLOCK 1 332 1 3 /***************************************************************** Section __: ******************************************************************/ 390 1 ;252 3 second( 1 332 1 1 second(sasDateTime|sasTime) 134 1 *252 3 sign( 1 332 1 1 sign(number) 237 1 (252 3 sin( 1 332 1 1 sin(number) 313 1 F252 3 skewness( 1 332 1 1 skewness( number1< , number2<...>> ) 186 1 /252 3 sleep( 1 332 1 10 /*Sleep */ data _Null_; SleepTime=5; BeforeSleep=time(); put "Before the " SleepTime "Second sleep the time is: " BeforeSleep= timeAMPM12.; x=sleep(5); AfterSleep=time(); put "After the " SleepTime "Second sleep the time is: " AfterSleep= timeAMPM12.; ; run; 228 1 K252 3 smallest( 1 332 1 1 smallest( k , number1< , number2<...>> ) 187 1 Ğ 252 3 soundex( 1 332 1 106 /*Compged Complev soundex Speedis*/ /*CompGed Returns the generalized edit distance between two strings. */ /*Soundex Encodes a string to facilitate searching. */ /*Speedis Determines the likelihood of two words matching,*/ data test; infile datalines missover; input String1 $char8. +1 String2 $char8. +1 Operation $40.; GED=CompGed(string1, string2); datalines; baboon baboon match baXboon baboon insert baoon baboon delete baXoon baboon replace baboonX baboon append baboo baboon truncate babboon baboon double babon baboon single baobon baboon swap bab oon baboon blank bab,oon baboon punctuation bXaoon baboon insert+delete bXaYoon baboon insert+replace bXoon baboon delete+replace Xbaboon baboon finsert aboon baboon trick question: swap+delete Xaboon baboon freplace axoon baboon fdelete+replace axoo baboon fdelete+replace+truncate axon baboon fdelete+replace+single baby baboon replace+truncate*2 balloon baboon replace+insert ; proc print data=test label; label GED='Generalized Edit Distance'; var String1 String2 GED Operation; run; /*COMPLEV Function Returns the Levenshtein edit distance between two strings. */ options pageno=1 nodate ls=80 ps=60; data test; infile datalines missover; input string1 $char8. string2 $char8. modifiers $char8.; result=CompLev(string1, string2, modifiers); datalines; 1234567812345678 abc abxc ac abc aXc abc aXbZc abc aXYZc abc WaXbYcZ abc XYZ abcdef aBc abc aBc AbC i abc abc abc abc l AxC 'abc'n AxC 'abc'n n ; proc print data=test; run; /*The SOUNDEX function encodes a character string according to an algorithm that was originally developed */ /*by Margaret K. Odell and Robert C. Russel (US Patents 1261167 (1918) and 1435663 (1922)). */ /*The algorithm is described in Knuth, The Art of Computer Programming, Volume 3. (See References.) */ /*Note that the SOUNDEX algorithm is English-biased and is less useful for languages other than English.*/ data _Null_; x=soundex('Paul'); put x; word='amnesty'; x=soundex(word); put x; ; run; /*Speedis Determines the likelihood of two words matching, expressed as the asymmetric spelling distance between the two words.*/ data words; input Operation $ Query $ Keyword $; Distance = spedis(query,keyword); Cost = distance * length(query); datalines; match fuzzy fuzzy singlet fuzy fuzzy doublet fuuzzy fuzzy swap fzuzy fuzzy truncate fuzz fuzzy append fuzzys fuzzy delete fzzy fuzzy insert fluzzy fuzzy replace fizzy fuzzy firstdel uzzy fuzzy firstins pfuzzy fuzzy firstrep wuzzy fuzzy several floozy fuzzy ; proc print data = words; run; 107 1 Ï 252 3 spedis( 1 332 1 106 /*Compged Complev soundex Speedis*/ /*CompGed Returns the generalized edit distance between two strings. */ /*Soundex Encodes a string to facilitate searching. */ /*Speedis Determines the likelihood of two words matching,*/ data test; infile datalines missover; input String1 $char8. +1 String2 $char8. +1 Operation $40.; GED=CompGed(string1, string2); datalines; baboon baboon match baXboon baboon insert baoon baboon delete baXoon baboon replace baboonX baboon append baboo baboon truncate babboon baboon double babon baboon single baobon baboon swap bab oon baboon blank bab,oon baboon punctuation bXaoon baboon insert+delete bXaYoon baboon insert+replace bXoon baboon delete+replace Xbaboon baboon finsert aboon baboon trick question: swap+delete Xaboon baboon freplace axoon baboon fdelete+replace axoo baboon fdelete+replace+truncate axon baboon fdelete+replace+single baby baboon replace+truncate*2 balloon baboon replace+insert ; proc print data=test label; label GED='Generalized Edit Distance'; var String1 String2 GED Operation; run; /*COMPLEV Function Returns the Levenshtein edit distance between two strings. */ options pageno=1 nodate ls=80 ps=60; data test; infile datalines missover; input string1 $char8. string2 $char8. modifiers $char8.; result=CompLev(string1, string2, modifiers); datalines; 1234567812345678 abc abxc ac abc aXc abc aXbZc abc aXYZc abc WaXbYcZ abc XYZ abcdef aBc abc aBc AbC i abc abc abc abc l AxC 'abc'n AxC 'abc'n n ; proc print data=test; run; /*The SOUNDEX function encodes a character string according to an algorithm that was originally developed */ /*by Margaret K. Odell and Robert C. Russel (US Patents 1261167 (1918) and 1435663 (1922)). */ /*The algorithm is described in Knuth, The Art of Computer Programming, Volume 3. (See References.) */ /*Note that the SOUNDEX algorithm is English-biased and is less useful for languages other than English.*/ data _Null_; x=soundex('Paul'); put x; word='amnesty'; x=soundex(word); put x; ; run; /*Speedis Determines the likelihood of two words matching, expressed as the asymmetric spelling distance between the two words.*/ data words; input Operation $ Query $ Keyword $; Distance = spedis(query,keyword); Cost = distance * length(query); datalines; match fuzzy fuzzy singlet fuzy fuzzy doublet fuuzzy fuzzy swap fzuzy fuzzy truncate fuzz fuzzy append fuzzys fuzzy delete fzzy fuzzy insert fluzzy fuzzy replace fizzy fuzzy firstdel uzzy fuzzy firstins pfuzzy fuzzy firstrep wuzzy fuzzy several floozy fuzzy ; proc print data = words; run; 108 1 5252 3 sqrt( 1 332 1 1 sqRt(nonnegativeNumber) 238 1 <252 3 std( 1 332 1 1 std( number1< , number2<...>> ) 188 1 A252 3 stderr( 1 332 1 1 stdErr( number1< , number2<...>> ) 76 1 2252 3 stfips( 1 332 1 1 stFips(postalCode) 300 1 2252 3 stname( 1 332 1 1 stName(postalCode) 301 1 4252 3 stnamel( 1 332 1 1 stNameL(postalCode) 302 1 ]252 3 strip( 1 332 1 18 strip(string) Returns a character string with all leading and trailing blanks removed. data StrippedVars; input string $char8.; original = '*' || string || '*'; stripped = '*' || strip(string) || '*'; datalines; abcd abcd abcd abcdefgh x y z ; proc print data=StrippedVars; run; 109 1 <252 3 stuff 6 255 1 271 1 255 1 251 1 44 265 1 270 1 293 0 F252 3 subpad( 1 332 1 1 subPad( string , position< , length> ) 110 1 Ş252 3 substr( 1 332 1 41 substr( string , position< , length> ) SUBSTR (left of =) Function Replaces character value contents. SUBSTR (right of =) Function Extracts a substring from an argument. Arguments variable specifies a valid SAS variable name. string specifies a character constant, variable, or expression. position specifies a numeric constant, variable, or expression that is the beginning character position. length specifies a numeric constant, variable, or expression that is the length of the substring to extract. Interaction: If length is zero, a negative value, or larger than the length of the expression that remains in string after position, SAS extracts the remainder of the expression. SAS also sets _ERROR_ to 1 and prints a note to the log indicating that the length argument is invalid. Tip: If you omit length, SAS extracts the remainder of the expression. Data _null_; /*Left*/ a='KIDNAP'; substr(a,1,3)='CAT'; put a; b=a; substr(b,4)='TY'; put b; /*Right*/ date='06MAY1998'; month=substr(date,3,3); year=substr(date,6,4); MoAndYr=substr(date,3); put @1 month= @15 year= @30 MoAndYr=; ; run; 111 1 H252 3 substrn( 1 332 1 1 substrN( string , position< , length> ) 112 1 252 3 sum( 1 332 1 59 /*Min Function*/ /* MEAN Function MEDIAN Function CALL SLEEP Routine SLEEP Function CEIL Function FLOOR Function INT Function ROUND Function RANGE Function */ data StatExamples; x=10; y=200; i=123; j=555; z=1; put z= x= i= y= j= ; MAxExample1=Max(x,y,i,j,z); put MAxExample1= ; MAxExample2=Max(.,x,y,i,j,z); put MAxExample2= ; MinExample1=Min(x,y,i,j,z); put MinExample1= ; MinExample2=Min(.,x,y,i,j,z); put MinExample2= ; MeanExample1=Mean(x,y,i,j,z); put MeanExample1= ; MeanExample2=Mean(x,y, . ,i,j,z); put MeanExample2= ; MedianExample1=Median(x,y,i,j,z); put MedianExample1= ; MedianExample2=Median(x,y, . , i,j,z); put MedianExample2= ; NExample=N(x,y,i,.,.,j,z); put "For the function NExample=N(x,y,i,.,.,j,z); " NExample= ; NMissExample=NMiss(x,y,i,.,.,j,z); /*Missing values*/ put "For the function NMissExample=NMiss(x,y,i,.,.,j,z); " NMissExample= ; SumExample=Sum(x,y,i,.,j,z); /*Missing values*/ put SumExample= ; CeilExample =ceil(5.4637); put "CeilExample =ceil(5.4637) " CeilExample= ; FloorExample =Floor(5.4637); put "FloorExample =Floor(5.4637) " FloorExample= ; IntExample =Int(5.4637); put "IntExample =Int(5.4637);" IntExample= ; RoundExample1=Round(5.4637,0.1); put "RoundExample1=Round(5.4637,0.1)" RoundExample1= ; RoundExample2=Round(5.4637,0.01); put "RoundExample2=Round(5.4537,0.01);" RoundExample2= ; RoundExample3=Round(5.4637,0.001); put "RoundExample3=Round(5.4637,0.001);" RoundExample3=; RangeExample1=range(x,y,i,j,z); put "RangeExample1=range(x,y,i,j,z);" RangeExample1=; RangeExample2=range(.,.,x,y,i,j,z); /*Missing values*/ put "RangeExample2=range(.,.,x,y,i,j,z);" RangeExample2=; ; run; 189 1 ?252 3 symexist( 1 332 1 1 symExist('macroVariableName') 202 1 ü252 3 symget( 1 332 1 14 /*Call Symput, symget, resolve */ data _null_; length CVarInPDV1 $6; call symput ("DogName","spot"); call Symput ("DogAge",5); put "Before Symget " CVarInPDV1= ; CVarInPDV1=symget("DogName"); put "After Symget " CVarInPDV1= ; NVarInPDV1=symget("DogAge"); put "After Symget " NVarInPDV1= ; /*I do not know anyone who uses resolve*/ /*see The RESOLVE Function - What Is It Good For?*/ /*http://www.nesug.org/proceedings/nesug98/code/p088.pdf*/ run; 203 1 ?252 3 symglobl( 1 332 1 1 symGlobl('macroVariableName') 204 1 ?252 3 symlocal( 1 332 1 1 symLocal('macroVariableName') 205 1 (252 3 tan( 1 332 1 1 tan(number) 314 1 &252 3 time( 1 332 1 123 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ /* Pretty dates all in a row Dianne Rhodes For my reports, which I usually run on Monday, I want to find last Friday’s date. The Week interval starts with Sunday, so Friday is week.6. ReportDate= intnx(‘week.6’, today(),0) The Start Date of the period will be the Saturday of the week before StartDate = intnx(‘week.7’, ReportDate, 0) http://www2.sas.com/proceedings/sugi30/055-30.pdf*/ /* INTNX('interval', start,from , increment, <,alignment>) INTCK('interval',from_date, to_date)*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ This_Day_Time=DateTime(); /*Reads system clock*/ A_date_part=DatePart(This_Day_Time); A_time_part=TimePart(This_Day_Time); ThisTime=time(); put TodayDate= TodayToday= ; put This_Day_Time= A_date_part= A_time_part=; put ThisTime= ; break=repeat("*",40); put / break /; put"The DAY function produces an integer from 1 to 31 that represents the day of the month."; Bday='05may97'd; DOM_BDay=day(Bday); TodayDate=today(); DOM_TodayDate=day(TodayDate); put Bday= DOM_BDay= TodayDate= DOM_TodayDate= ; break=repeat("*",40); put / break; thisInstant=DateTime(); DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put DayFromDateTime= ThisInstant=; TimeFromDateTime=TimePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put TimeFromDateTime= ThisInstant=; break=repeat("*",15)||" MDY "||repeat("*",15); put / break /; put"The MDY function converts MONTH, DAY, and YEAR values to a SAS date value." ; put "For example, MDY(01,21,2010) returns the SAS date value for 21Jan2010 "; month=01; day=21; year=2010; DateFromNum=MDY(month,day,year); Put DateFromNum= DateFromNum= yymmdd10.; *MDY When month, day, and year are char; Cmonth="01"; Cday ="05"; Cyear ="2010"; DateFromChar=MDY(input(Cmonth,2.),input(Cday,2.),input(Cyear,4.)); Put DateFromChar= DateFromChar= yymmdd10.; break=repeat("*",15)||" INTCK "||repeat("*",15); put / break /; /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; break=repeat("*",15)||" INTNX "||repeat("*",15); put / break /; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; string="Aligning a date to prev or following Friday"; DASH = REPEAT("-",length(string) - 1); PUT /DASH/ STRING / DASH; *Align to friday of previous week; TheDate=today(); PrevFriday= intnx('week.6', today(),0); put TheDate= EURDFWKX21. PrevFriday= EURDFWKX21.; *what if the date IS a friday and we want to align to that date; AFriday=20692; put /"What if the date IS already a friday?"; AlignedFriday= intnx('week.6', AFriday,0); put AFriday= EURDFWKX21. AlignedFriday= EURDFWKX21.; *align to next friday; TheDate=today(); NextFriday= intnx('week.6', today(),+1); put /TheDate= EURDFWKX21. NextFriday= EURDFWKX21.; run; 135 1 *252 3 timepart( 1 332 1 123 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ /* Pretty dates all in a row Dianne Rhodes For my reports, which I usually run on Monday, I want to find last Friday’s date. The Week interval starts with Sunday, so Friday is week.6. ReportDate= intnx(‘week.6’, today(),0) The Start Date of the period will be the Saturday of the week before StartDate = intnx(‘week.7’, ReportDate, 0) http://www2.sas.com/proceedings/sugi30/055-30.pdf*/ /* INTNX('interval', start,from , increment, <,alignment>) INTCK('interval',from_date, to_date)*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ This_Day_Time=DateTime(); /*Reads system clock*/ A_date_part=DatePart(This_Day_Time); A_time_part=TimePart(This_Day_Time); ThisTime=time(); put TodayDate= TodayToday= ; put This_Day_Time= A_date_part= A_time_part=; put ThisTime= ; break=repeat("*",40); put / break /; put"The DAY function produces an integer from 1 to 31 that represents the day of the month."; Bday='05may97'd; DOM_BDay=day(Bday); TodayDate=today(); DOM_TodayDate=day(TodayDate); put Bday= DOM_BDay= TodayDate= DOM_TodayDate= ; break=repeat("*",40); put / break; thisInstant=DateTime(); DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put DayFromDateTime= ThisInstant=; TimeFromDateTime=TimePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put TimeFromDateTime= ThisInstant=; break=repeat("*",15)||" MDY "||repeat("*",15); put / break /; put"The MDY function converts MONTH, DAY, and YEAR values to a SAS date value." ; put "For example, MDY(01,21,2010) returns the SAS date value for 21Jan2010 "; month=01; day=21; year=2010; DateFromNum=MDY(month,day,year); Put DateFromNum= DateFromNum= yymmdd10.; *MDY When month, day, and year are char; Cmonth="01"; Cday ="05"; Cyear ="2010"; DateFromChar=MDY(input(Cmonth,2.),input(Cday,2.),input(Cyear,4.)); Put DateFromChar= DateFromChar= yymmdd10.; break=repeat("*",15)||" INTCK "||repeat("*",15); put / break /; /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; break=repeat("*",15)||" INTNX "||repeat("*",15); put / break /; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; string="Aligning a date to prev or following Friday"; DASH = REPEAT("-",length(string) - 1); PUT /DASH/ STRING / DASH; *Align to friday of previous week; TheDate=today(); PrevFriday= intnx('week.6', today(),0); put TheDate= EURDFWKX21. PrevFriday= EURDFWKX21.; *what if the date IS a friday and we want to align to that date; AFriday=20692; put /"What if the date IS already a friday?"; AlignedFriday= intnx('week.6', AFriday,0); put AFriday= EURDFWKX21. AlignedFriday= EURDFWKX21.; *align to next friday; TheDate=today(); NextFriday= intnx('week.6', today(),+1); put /TheDate= EURDFWKX21. NextFriday= EURDFWKX21.; run; 136 1 [252 3 tinv( 1 332 1 1 tInv( numericProbability , degreesOfFreedom , nonCentrality ) 265 1 Z252 3 tnonct( 1 332 1 1 tNonct( numericVariable , degreesOfFreedom , probability ) 239 1 '252 3 today( 1 332 1 123 /*DATE Function DATEPART Function DATETIME Function DAY Function INTCK Function INTNX Function MDY Function TIME Function TIMEPART Function TODAY Function*/ /* Pretty dates all in a row Dianne Rhodes For my reports, which I usually run on Monday, I want to find last Friday’s date. The Week interval starts with Sunday, so Friday is week.6. ReportDate= intnx(‘week.6’, today(),0) The Start Date of the period will be the Saturday of the week before StartDate = intnx(‘week.7’, ReportDate, 0) http://www2.sas.com/proceedings/sugi30/055-30.pdf*/ /* INTNX('interval', start,from , increment, <,alignment>) INTCK('interval',from_date, to_date)*/ data _null_; TodayDate=date(); /*Reads system clock*/ TodayToday=today(); /*Reads system clock*/ This_Day_Time=DateTime(); /*Reads system clock*/ A_date_part=DatePart(This_Day_Time); A_time_part=TimePart(This_Day_Time); ThisTime=time(); put TodayDate= TodayToday= ; put This_Day_Time= A_date_part= A_time_part=; put ThisTime= ; break=repeat("*",40); put / break /; put"The DAY function produces an integer from 1 to 31 that represents the day of the month."; Bday='05may97'd; DOM_BDay=day(Bday); TodayDate=today(); DOM_TodayDate=day(TodayDate); put Bday= DOM_BDay= TodayDate= DOM_TodayDate= ; break=repeat("*",40); put / break; thisInstant=DateTime(); DayFromDateTime=DatePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put DayFromDateTime= ThisInstant=; TimeFromDateTime=TimePart(ThisInstant); /*argument must be DateTime - NOT DATE*/ put TimeFromDateTime= ThisInstant=; break=repeat("*",15)||" MDY "||repeat("*",15); put / break /; put"The MDY function converts MONTH, DAY, and YEAR values to a SAS date value." ; put "For example, MDY(01,21,2010) returns the SAS date value for 21Jan2010 "; month=01; day=21; year=2010; DateFromNum=MDY(month,day,year); Put DateFromNum= DateFromNum= yymmdd10.; *MDY When month, day, and year are char; Cmonth="01"; Cday ="05"; Cyear ="2010"; DateFromChar=MDY(input(Cmonth,2.),input(Cday,2.),input(Cyear,4.)); Put DateFromChar= DateFromChar= yymmdd10.; break=repeat("*",15)||" INTCK "||repeat("*",15); put / break /; /*intck counts "time periods" between dates AND is tricky - read the documentation nad Bruce Gleason's paper*/ DaysBetween1=intck("day","1JAN00"D,"12JAN00"D); put DaysBetween1=; DaysBetween2=intck("day","12JAN00"D,"1JAN00"D); put DaysBetween2=; WeeksBetween1=intck("week","1JAN00"D,"12JAN00"D); put WeeksBetween1=; WeeksBetween2=intck("week","12JAN00"D,"1JAN00"D); put WeeksBetween2=; WeeksBetween3=intck("week","1JAN00"D,"2JAN00"D); /*ONE DAY!!!*/ put WeeksBetween3= /*for a one day difference*/; break=repeat("*",15)||" INTNX "||repeat("*",15); put / break /; /*INTNX advances a date AND is tricky - read the documentation*/ date1B=intnx('week','01jan95'd,5,'beginning'); put date1B / date1B Weekdate17.; date1M=intnx('week','01jan95'd,5,'middle'); put date1M / date1M Weekdate17.; date1E=intnx('week','01jan95'd,5,'end'); put date1E / date1E Weekdate17.; date1S=intnx('week','01jan95'd,5,'sameday'); put date1S / date1S Weekdate17.; date2=intnx('month','01jan95'd,5,'middle'); put date2 / date2 date7.; date3=intnx('month','01jan95'd,5,'end'); put date3 / date3 date7.; date4=intnx('month','01jan95'd,5,'sameday'); put date4 / date4 date7.; string="Aligning a date to prev or following Friday"; DASH = REPEAT("-",length(string) - 1); PUT /DASH/ STRING / DASH; *Align to friday of previous week; TheDate=today(); PrevFriday= intnx('week.6', today(),0); put TheDate= EURDFWKX21. PrevFriday= EURDFWKX21.; *what if the date IS a friday and we want to align to that date; AFriday=20692; put /"What if the date IS already a friday?"; AlignedFriday= intnx('week.6', AFriday,0); put AFriday= EURDFWKX21. AlignedFriday= EURDFWKX21.; *align to next friday; TheDate=today(); NextFriday= intnx('week.6', today(),+1); put /TheDate= EURDFWKX21. NextFriday= EURDFWKX21.; run; 137 1 B252 3 translate( 1 332 1 66 translate( string , toChars1 , fromChars1< , toChars2 , fromChars2<...>> ) Replaces SPECIFIC characters in a character string. TRANSTRN(source,target,replacement) Replaces or removes all occurrences of a substring in a character string. The Basics The TRANSTRN function replaces or removes all occurrences of a given substring within a character string. The TRANSTRN function does not remove trailing blanks in the target string and the replacement string. To remove all occurrences of target, specify replacement as TRIMN(""). tranWrd( string , fromString , toString ) Replaces all occurrences of a substring in a character string. data _null_; x=tranSLATE('XYZW','AB','VW'); put x=; name1=tranWRD(name, "Mrs.", "Ms."); put name1; name2=tranWRD(name, "Miss", "Ms."); put name2; run; data list; input salelist $; length target $10 replacement $3; target='FISH'; replacement='NIP'; salelist=tranWRD(salelist,target,replacement); put salelist; datalines; CATFISH ; proc print data=list; run; /*transtrn Example 1: Replacing All Occurrences of a Word */ /*These statements and these values produce these results: */ data _null_; name1="Mrs. Joan Smith"; name1TRN=transtrn(name1, "Mrs.", "Ms."); put name1= name1TRN=; name2="Miss Alice Cooper"; name2TRN=transtrn(name2, "Miss", "Ms."); put name2= name2TRN=; run; /*Example 2: Removing Blanks from the Search String */ /*In this example, the TRANSTRN function does not replace the source string because */ /* the target string contains blanks. */ data list; input salelist $; length target $10 replacement $3; target='FISH'; replacement='NIP'; salelist=transtrn(salelist,target,replacement); put salelist; datalines; CATFISH ; /*The LENGTH statement pads target with blanks to the length of 10, */ /* which causes the TRANSTRN function to search for the character string 'FISH ' in SALELIST. */ /*Because the search fails, this line is written to the SAS log: */ 113 1 C252 3 transtrn( 1 332 1 67 translate( string , toChars1 , fromChars1< , toChars2 , fromChars2<...>> ) Replaces SPECIFIC characters in a character string. TRANSTRN(source,target,replacement) Replaces or removes all occurrences of a substring in a character string. The Basics The TRANSTRN function replaces or removes all occurrences of a given substring within a character string. The TRANSTRN function does not remove trailing blanks in the target string and the replacement string. To remove all occurrences of target, specify replacement as TRIMN(""). tranWrd( string , fromString , toString ) Replaces all occurrences of a substring in a character string. data _null_; x=tranSLATE('XYZW','AB','VW'); put x=; name1=tranWRD(name, "Mrs.", "Ms."); put name1; name2=tranWRD(name, "Miss", "Ms."); put name2; run; data list; input salelist $; length target $10 replacement $3; target='FISH'; replacement='NIP'; salelist=tranWRD(salelist,target,replacement); put salelist; datalines; CATFISH ; proc print data=list; run; /*transtrn Example 1: Replacing All Occurrences of a Word */ /*These statements and these values produce these results: */ data _null_; name1="Mrs. Joan Smith"; name1TRN=transtrn(name1, "Mrs.", "Ms."); put name1= name1TRN=; name2="Miss Alice Cooper"; name2TRN=transtrn(name2, "Miss", "Ms."); put name2= name2TRN=; run; /*Example 2: Removing Blanks from the Search String */ /*In this example, the TRANSTRN function does not replace the source string because */ /* the target string contains blanks. */ data list; input salelist $; length target $10 replacement $3; target='FISH'; replacement='NIP'; salelist=transtrn(salelist,target,replacement); put salelist; datalines; CATFISH ; /*The LENGTH statement pads target with blanks to the length of 10, */ /* which causes the TRANSTRN function to search for the character string 'FISH ' in SALELIST. */ /*Because the search fails, this line is written to the SAS log: */ 235 1 E252 3 trantab( 1 332 1 1 tranTab( string , translationTable ) 114 1 B252 3 tranwrd( 1 332 1 67 translate( string , toChars1 , fromChars1< , toChars2 , fromChars2<...>> ) Replaces SPECIFIC characters in a character string. TRANSTRN(source,target,replacement) Replaces or removes all occurrences of a substring in a character string. The Basics The TRANSTRN function replaces or removes all occurrences of a given substring within a character string. The TRANSTRN function does not remove trailing blanks in the target string and the replacement string. To remove all occurrences of target, specify replacement as TRIMN(""). tranWrd( string , fromString , toString ) Replaces all occurrences of a substring in a character string. data _null_; x=tranSLATE('XYZW','AB','VW'); put x=; name1=tranWRD(name, "Mrs.", "Ms."); put name1; name2=tranWRD(name, "Miss", "Ms."); put name2; run; data list; input salelist $; length target $10 replacement $3; target='FISH'; replacement='NIP'; salelist=tranWRD(salelist,target,replacement); put salelist; datalines; CATFISH ; proc print data=list; run; /*transtrn Example 1: Replacing All Occurrences of a Word */ /*These statements and these values produce these results: */ data _null_; name1="Mrs. Joan Smith"; name1TRN=transtrn(name1, "Mrs.", "Ms."); put name1= name1TRN=; name2="Miss Alice Cooper"; name2TRN=transtrn(name2, "Miss", "Ms."); put name2= name2TRN=; run; /*Example 2: Removing Blanks from the Search String */ /*In this example, the TRANSTRN function does not replace the source string because */ /* the target string contains blanks. */ data list; input salelist $; length target $10 replacement $3; target='FISH'; replacement='NIP'; salelist=transtrn(salelist,target,replacement); put salelist; datalines; CATFISH ; /*The LENGTH statement pads target with blanks to the length of 10, */ /* which causes the TRANSTRN function to search for the character string 'FISH ' in SALELIST. */ /*Because the search fails, this line is written to the SAS log: */ 115 1 2252 3 trigamma( 1 332 1 1 triGamma(number) 240 1 r252 3 trim( 1 332 1 49 trim(string) Removes trailing blanks from a character string, and returns one blank if the string is missing. TRIMN(argument) Removes trailing blanks from character expressions, and returns a string with a length of zero if the expression is missing. The TRIM and TRIMN functions are similar. TRIM returns one blank for a blank string. TRIMN returns a string with a length of zero for a blank string. Example 1: Removing Trailing Blanks These statements and this data line produce these results: data test; input part1 $ 1-10 part2 $ 11-20; hasblank=part1||part2; noblank=trim(part1)||part2; put hasblank=; put noblank=; datalines; apple sauce apple sauce ; run; Example 2: Concatenating a Blank Character Expression SAS Statements Results data test; put "************Trim********************"; x="A"||trim(" ")||"B"; Put x=; x=" "; y=">"||trim(x)||"<"; put y=; put "************TrimN********************"; x="A"||trimN(" ")||"B"; Put x=; x=" "; y=">"||trim(x)||"<"; put y=; run; 116 1 s252 3 trimn( 1 332 1 49 trim(string) Removes trailing blanks from a character string, and returns one blank if the string is missing. TRIMN(argument) Removes trailing blanks from character expressions, and returns a string with a length of zero if the expression is missing. The TRIM and TRIMN functions are similar. TRIM returns one blank for a blank string. TRIMN returns a string with a length of zero for a blank string. Example 1: Removing Trailing Blanks These statements and this data line produce these results: data test; input part1 $ 1-10 part2 $ 11-20; hasblank=part1||part2; noblank=trim(part1)||part2; put hasblank=; put noblank=; datalines; apple sauce apple sauce ; run; Example 2: Concatenating a Blank Character Expression SAS Statements Results data test; put "************Trim********************"; x="A"||trim(" ")||"B"; Put x=; x=" "; y=">"||trim(x)||"<"; put y=; put "************TrimN********************"; x="A"||trimN(" ")||"B"; Put x=; x=" "; y=">"||trim(x)||"<"; put y=; run; 117 1 7252 3 trunc( 1 332 1 1 trunc( number , length ) 325 1 .252 3 uniform( 1 332 1 1 uniform(seed) 289 1 252 3 upcase( 1 332 1 8 /*UpCase( LCase( */ data _null_; x="this IS 1 instance"; Y=upcase(X); z=LCase(X); put x= y= z=; run; 118 1 <252 3 uss( 1 332 1 1 uss( number1< , number2<...>> ) 190 1 <252 3 var( 1 332 1 1 var( number1< , number2<...>> ) 191 1 ,252 3 varray( 1 332 1 1 vArray(name) 330 1 4252 3 varrayx( 1 332 1 1 vArrayX(expression) 331 1 H252 3 vartranscode( 1 332 1 1 varTranscode( datasetId , varNum ) 332 1 F252 3 verify( 1 332 1 14 /*Verify*/ /*Might be better to use one of the find functions (find findc findw) findfunctions seem to be more powerful*/ data _testing_; set sashelp.class; ObsNo=_n_; If Mod(_N_,4)=0 then Sex="X"; DataQC=Verify(sex,"MmFf"); if dataQC NE 0 then do; put _all_; end; run; 119 1 @252 3 vformat( 1 332 1 1 vFormat(varName|arrayReference) 333 1 B252 3 vformatd( 1 332 1 1 vFormatD(varName|arrayReference) 334 1 8252 3 vformatdx( 1 332 1 1 vFormatDX(expression) 335 1 B252 3 vformatn( 1 332 1 1 vFormatN(varName|arrayReference) 336 1 8252 3 vformatnx( 1 332 1 1 vFormatNX(expression) 337 1 B252 3 vformatw( 1 332 1 1 vFormatW(varName|arrayReference) 338 1 8252 3 vformatwx( 1 332 1 1 vFormatWX(expression) 339 1 6252 3 vformatx( 1 332 1 1 vFormatX(expression) 340 1 B252 3 vinarray( 1 332 1 1 vInArray(varName|arrayReference) 341 1 8252 3 vinarrayx( 1 332 1 1 vInArrayX(expression) 342 1 D252 3 vinformat( 1 332 1 1 vInformat(varName|arrayReference) 343 1 F252 3 vinformatd( 1 332 1 1 vInformatD(varName|arrayReference) 344 1 <252 3 vinformatdx( 1 332 1 1 vInformatDX(expression) 345 1 F252 3 vinformatn( 1 332 1 1 vInformatN(varName|arrayReference) 346 1 <252 3 vinformatnx( 1 332 1 1 vInformatNX(expression) 347 1 F252 3 vinformatw( 1 332 1 1 vInformatW(varName|arrayReference) 348 1 <252 3 vinformatwx( 1 332 1 1 vInformatWX(expression) 349 1 :252 3 vinformatx( 1 332 1 1 vInformatX(expression) 350 1 >252 3 vlabel( 1 332 1 1 vLabel(varName|arrayReference) 351 1 4252 3 vlabelx( 1 332 1 1 vLabelX(expression) 352 1 @252 3 vlength( 1 332 1 1 vLength(varName|arrayReference) 353 1 6252 3 vlengthx( 1 332 1 1 vLengthX(expression) 354 1 4252 3 vname( 1 332 1 1 vName(arrayReference) 355 1 2252 3 vnamex( 1 332 1 1 vNameX(expression) 356 1 F252 3 vtranscode( 1 332 1 1 vTranscode(varName|arrayReference) 357 1 <252 3 vtranscodex( 1 332 1 1 vTranscodeX(expression) 358 1 <252 3 vtype( 1 332 1 1 vType(varName|arrayReference) 359 1 2252 3 vtypex( 1 332 1 1 vTypeX(expression) 360 1 >252 3 vvalue( 1 332 1 1 vValue(varName|arrayReference) 361 1 4252 3 vvaluex( 1 332 1 1 vValueX(expression) 362 1 ;252 3 week( 1 332 1 1 week( < , > ) 138 1 S252 3 weekday( 1 332 1 12 weekday(sasDate) retuns the day of the week as a number. Saturday is day 1 data check; TwoDaysAgo=today()-2; yesterday=today()-1; today=today(); tomorrow=today+1; Nmbr4Today=weekday(today()); format TwoDaysAgo yesterday today tomorrow weekdate17.; ; run; proc print data=check; run; 139 1 +252 3 year( 1 332 1 1 year(sasDate) 140 1 l252 3 yrdif( 1 332 1 1 yrDif( startSasDate , endSasDate< , '30/360'|'ACT/ACT'|'ACT/360'|'ACT/365'> ) 141 1 9252 3 yyq( 1 332 1 1 yyQ( numericYear , 1|2|3|4 ) 142 1 4252 3 zipcity( 1 332 1 1 zipCity(postalCode) 303 1 4252 3 zipfips( 1 332 1 1 zipFips(postalCode) 304 1 4252 3 zipname( 1 332 1 1 zipName(postalCode) 305 1 6252 3 zipnamel( 1 332 1 1 zipNameL(postalCode) 306 1 6252 3 zipstate( 1 332 1 1 zipState(postalCode) 307 1