From c255bf9aeb4e20b7520ec372c2e31376d107fae6 Mon Sep 17 00:00:00 2001 From: Bart Jablonski Date: Fri, 1 Dec 2023 12:50:59 +0100 Subject: [PATCH] The macroArray package [ver. 1.2.6] The macroArray package [ver. 1.2.6] Changes: - Minor update in `%mcDictionary()` and `%mcHashTable()` macros. Restrictions for object names check updated. - Documentation updated. SHA256 digest for the latest version macroArray: F*3F3893F1FCD78719543703E4353F4CC19811D247C016F220FF729B283C1AD790 --- README.md | 2 +- hist/1.2.6/macroarray.md | 2286 +++++++++++++++++++++++++++++++++++++ hist/1.2.6/macroarray.zip | Bin 0 -> 53447 bytes macroarray.md | 8 +- macroarray.zip | Bin 53397 -> 53447 bytes 5 files changed, 2291 insertions(+), 5 deletions(-) create mode 100644 hist/1.2.6/macroarray.md create mode 100644 hist/1.2.6/macroarray.zip diff --git a/README.md b/README.md index 8aad985..52e0138 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ The **macroArray** package implements an array, a hash table, and a dictionary c ); ``` -SHA256 digest for the latest version of `macroArray`: F*FFF2C3D854F9B5677F561BA2EB6FAA2CCC652D81F6AF9473ADF0A4CE977E43F0 +SHA256 digest for the latest version of `macroArray`: F*3F3893F1FCD78719543703E4353F4CC19811D247C016F220FF729B283C1AD790 [**Documentation for macroArray**](./macroarray.md "Documentation for macroArray") diff --git a/hist/1.2.6/macroarray.md b/hist/1.2.6/macroarray.md new file mode 100644 index 0000000..58b4192 --- /dev/null +++ b/hist/1.2.6/macroarray.md @@ -0,0 +1,2286 @@ +- [The macroArray package](#macroarray) +- [Content description](#content-description) + * [`%appendArray()` macro](#appendarray-macro) + * [`%appendCell()` macro](#appendcell-macro) + * [`%array()` macro](#array-macro) + * [`%concatArrays()` macro](#concatarrays-macro) + * [`%deleteMacArray()` macro](#deletemacarray-macro) + * [`%do_over()` macro](#do-over-macro) + * [`%do_over2()` macro](#do-over2-macro) + * [`%do_over3()` macro](#do-over3-macro) + * [`%make_do_over()` macro](#make-do-over-macro) + * [`%mcHashTable()` macro](#mchashtable-macro) + * [`%mcDictionary()` macro](#mcdictionary-macro) + * [`%QzipArrays()` macro](#qziparrays-macro) + * [`%zipArrays()` macro](#ziparrays-macro) + * [`%sortMacroArray()` macro](#sortmacroarray-macro) + + * [License](#license) + +--- + +# The macroArray package [ver. 1.2.6] ############################################### + +The **macroArray** package implements a macroarray facility: +- `%array()`, +- `%do_over()`, +- `%make_do_over()`, +- `%deletemacarray()`, +- `%concatarrays()`, +- `%appendcell()`, +- `%mcHashTable()`, +- `%zipArrays()`, +- `%sortMacroArray()`, +- `%mcDictionary()`, +- etc. + +The set of macros, which emulates classic +data-step-array functionality on the macro +programming level, is provided. + +*Note:* +If you are working with BIG macroarrays do not +forget to verify your session setting for macro +memory limits. Run: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + proc options group = macro; + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +to verify the following options: + +| option | description | +|-------------:|:-----------------------------------------------------------------------------------------------| +|`MEXECSIZE=` | specifies the maximum macro size that can be executed in memory. | +|`MSYMTABMAX=` | specifies the maximum amount of memory available to the macro variable symbol table or tables. | +|`MVARSIZE=` | specifies the maximum size for a macro variable that is stored in memory. | + +--- + +Package contains: + 1. macro appendarray + 2. macro appendcell + 3. macro array + 4. macro concatarrays + 5. macro deletemacarray + 6. macro do_over + 7. macro do_over2 + 8. macro do_over3 + 9. macro make_do_over + 10. macro mcdictionary + 11. macro mchashtable + 12. macro qziparrays + 13. macro sortmacroarray + 14. macro ziparrays + +Required SAS Components: + *Base SAS Software* + +*SAS package generated by generatePackage, version 20231123* + +The SHA256 hash digest for package macroArray: +`F*3F3893F1FCD78719543703E4353F4CC19811D247C016F220FF729B283C1AD790` + +--- +# Content description ############################################################################################ + +## >>> `%appendArray()` macro: <<< ############ + +The `%appendArray()` macro is a macrowrapper +which allows to concatenate two macroarrays +created by `%array()` macro. + +By default values of the second macroarray are *not* removed. + +Dimensions of the first macroarray are extended. + +The `%appendArray()` macro executes like a pure macro code. + +### SYNTAX: ##################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%appendArray( + first + ,second +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `first` - *Required*, a name of a macroarray created by the `%array()` macro. + +2. `second` - *Required*, a name of a macroarray created by the `%array()` macro. + + + + +### EXAMPLES AND USECASES: ###################################################### + +**EXAMPLE 1.** Append macroarrays LL and MM. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(ll[2:4] $ 12, + function = quote(put(today() + 10*_I_, yymmdd10.)), + macarray=Y + ) + %array(mm[10:13] $ 1200, + function = quote(repeat("A",12*_I_)), + macarray=Y + ) + %put *%ll(2)*%ll(3)*%ll(4)*; + + %appendArray(ll, mm); + %put *%ll(2)*%ll(3)*%ll(4)*%ll(5)*%ll(6)**%ll(7)*%ll(8)*; + + %put *%mm(10)**%mm(11)*%mm(12)*%mm(13)*; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Error handling. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %appendArray(ll, ) + %appendArray(, mm) + + %appendArray(noExistA, noExistB) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--- + + + +## >>> `%appendCell()` macro: <<< ############## + +The `%appendCell()` macro allows to append +a macrovariable to a macroarray created by the `%array()` macro. + +Dimensions of the macroarray are extended. + +The `%appendCell()` macro executes like a pure macro code. + +### SYNTAX: #################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%appendCell( + first + ,second + ,hilo +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `first` - *Required*, a name of a macroarray created by the `%array()` macro. + +2. `second` - *Required*, a name of a macrovariable to be append to the macroarray. + +3. `hilo` - *Required*, if `H` macrovariable is appended at the end + if `L` macrovariable is appended at the beginning +); + + + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Create two macro wrappers. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %* Macro wrapper to append a macrovariable to the end of a macroarray; + %macro appendHC(array,cell); + %appendCell(&array.,&cell.,H) + %mend appendHC; + + %* macro wrapper to append a macrovariable to the beginning of a macroarray; + %macro appendLC(array,cell); + %appendCell(&array.,&cell.,L) + %mend appendLC; + + + %* create macroarrays X and variables W,Y,Z; + + %array(X[2:4] $ ("AAA", "BBB", "CCC"), macarray=Y) + %let W=1; + %let Y=2; + %let Z=3; + %put *%do_over(X)*&=W*&=Y*&=Z*; + + %put BEFORE *%do_over(X)**&=xLBOUND*&=xHBOUND*&=xN*; + %appendCell(X,Y,H) + %put AFTER1 *%do_over(X)**&=xLBOUND*&=xHBOUND*&=xN*; + + %appendLC(X,W) + %put AFTER2 *%do_over(X)**&=xLBOUND*&=xHBOUND*&=xN*; + + %appendHC(X,Z) + %put AFTER3 *%do_over(X)**&=xLBOUND*&=xHBOUND*&=xN*; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Error handling +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %appendCell(X,Y,blahblah) + + %appendCell(X,,H) + %appendCell(,Y,H) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**EXAMPLE 3.** Adding variable below lower bound. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(zero[0:2] $ ("AAA", "BBB", "CCC"), macarray=Y) + %let belowzero=zzz; + + %put BEFORE *%do_over(zero)**&=zeroLBOUND*&=zeroHBOUND*&=zeroN*; + %appendCell(zero,belowzero,L) + %put AFTER *%do_over(zero)**&=zeroLBOUND*&=zeroHBOUND*&=zeroN*; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--- + + + +## >>> `%array()` macro: <<< ####################### + +The code of a macro was inspired by +*Ted Clay's* and *David Katz's* macro `%array()`. + +The `%array()` macro version provided in the package +is designed to facilitate +the idea of macroarray concept, i.e. *a list of +macrovariables with common prefix and numerical suffixes*. +Usually such construction is then resolved by +double ampersand syntax, e.g. `&&perfix&i` or similar one. + +What is new/extension to the `%array()` macro concept are: + +0. The syntax is closer to the data step one. +1. It is a pure macro code (it can be executed in any place + of 4GL code), this includes generating macroarrays out + of datasets. +2. When a macroarrray is created it allows also to generate + a new macro (named the same as the array name) and replace + the double ampersand syntax with more array looking one, + i.e. for array ABC user can have `%ABC(1)`, `%ABC(2)`, or `%ABC(&i)` + constructions. +3. The array macro allows to use data step functions to generate + array's entries. + +The `%array()` macro executes like a pure macro code. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%array( + array + <,function=> + <,before=> + <,after=> + <,vnames=N> + <,macarray=N> + <,ds=> + <,vars=> + <,q=> +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `array` - *Required*, an array name and a declaration/definition of an array,
+ e.g. `myArr[*] x1-x3 (4:6)`
+ or `myBrr[*] $ y1-y3 ("a" "b" "c")`
+ or `myCrr[3] $ ("d d d" "e,e,e" "f;f;f")`
+ or `myDrr p q r s`.
+ Macrovariables created by the macro are *global*. + If an array name is `_` (single underscore) then attached variables + list names are used, a call of the form: + `%array(_[*] p1 q2 r3 s4 (-1 -2 -3 -4))` + will create macrovariables: `p1`, `q2`, `r3`, and `s4` with respective + values: `-1`, `-2`, `-3`, and `-4`.
+ Three additional *global* macrovariables: + `LBOUND`, `HBOUND`, and `N` + are generated with the macroarray. See examples for more use-cases. + +* `function=` - *Optional*, a function or an expression to be applied to all array cells, + `_I_` is as array iterator, e.g. `_I_ + rand("uniform")`. + +* `before=` - *Optional*, a function or an expression to be added before looping through + array, e.g. `call streaminit(123)`. + +* `after=` - *Optional*, a function or an expression to be added after looping through + array, e.g. `call sortn(ABC)`. + +* `vnames=N` - *Optional*, default value `N`, if set to `Y`/`YES` then macroarray is built based + on variables names instead values, e.g. + `%array(myArr[*] x1-x3 (4:6), vnames=Y)` + will use `x1`, `x2`, and `x3` as values instead `4`, `5`, and `6`. + +* `macarray=N` - *Optional*, default value `N`, if set to `Y`/`YES` then a macro, named with the array + name, is compiled to create convenient envelope for multiple ampersands, e.g. + `%array(myArr[*] x1-x3 (4:6), macarray=Y)` + will create `%myArr(J)` macro which will allow to extract "data" + from macroarray like: + `%let x = %myArr(1);` + or when used with second parameter equal `I` (insert) allow to overwrite macroarrays + value: + `%let %myArr(17,i) = 42;` + If set to `M` then for a given array name the macro symbols table is scanned for + macrovariables with prefix like the array name and numeric suffixes, + then the minimum and the maximum index is determined + and all not existing global macrovariables are created and + a macro is generated in the same way as for the `Y` value. + +* `ds=` - *Optional*, use a dataset as a basis for a macroarray data, + if used by default overwrites use of the `array` parameter, honors `macarray=` + argument, dataset options are allowed, e.g. `sashelp.class(obs=5)` + +* `vars=` - *Optional*, a list of variables used to create macroarrays from a dataset, + the list format can be as follows (`<...>` means optional): + `variable1 <... variableN>` + delimiters are hash(`#`) and pipe(`|`), currently only space + is supported as separator, the meaning of `#` and `|` delimiters + will be explained in the following example: + if the `vars = height#h weight weight|w age|` value is provided + then the following macroarrays will be created:
+ 1) macroarray "H" with ALL(`#`) values of variable "height"
+ 2) macroarray "WEIGHT" with ALL(no separator is equivalent to #) + values of variable "weight"
+ 3) macroarray "W" with UNIQUE(|) values of variable "weight" and
+ 4) macroarray "AGE" with UNIQUE(|) values of variable "age". + +* `q=` - *Optional*, indicates (when set to `1` or '2') if the value should be surrounded by quotes. + It uses `quote(cats(...))` combo under the hood. Default value is `0`. + Value `1` is for apostrophes, value `2` is for double quotes. + Ignored for `macarray=M`. + + +--- + +### EXAMPLES AND USECASES: #################################################### + + +**EXAMPLE 1.** Basic use-case. + Creating macroarray like in the array statement. + Values not variables names are used by default. + Different types of brackets are allowed. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(a[*] x1-x5 (1:5)) + + %array(b{5} (5*17), q=1) + + %* Mind the $ since it is a character array!; + %array(c(3) $ 10 ("a A" "b,B" "c;C")) + + %array(d x1-x5 (5 4 3 2 1)) + %put _user_; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Index ranges. + If range starts < 0 then it is shifted to 0. + In case when range is from `1` to `M` + then macrovariable `N` is set to `M` + In case when range is different + the `N` returns number of + elements in the array `(Hbound - Lbound + 1)`. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(d[-2:2] $ ("a" "b" "c" "d" "e")) + %put &=dLBOUND. &=dHBOUND. &=dN.; + %put &=d0. &=d1. &=d2. &=d3. &=d4.; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 3.** Functions. + It is possible to assign value of a function + or an expression to a cell of the array, + e.g. `array[_I_] = function(...)`. + You can use an iterator in a function. + As in case of usual arrays it is `_I_`. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(e[-3:3] $, function = "A" ) + %put &=eLBOUND. &=eHBOUND. &=eN.; + %put &=e0. &=e1. &=e2. &=e3. &=e4. &=e5. &=e6.; + + %array(f[-3:3], function = (2**_I_) ) + %put &=fLBOUND. &=fHBOUND. &=fN.; + %put &=f0. &=f1. &=f2. &=f3. &=f4. &=f5. &=f6.; + + %array(g[0:2], function = ranuni(123) ) + %put &=gLBOUND. &=gHBOUND. &=gN.; + %put &=g0. &=g1. &=g2.; + + %* Or something more complex; + %array(gg[0:11] $ 11, function = put(intnx("MONTH", '1jun2018'd, _I_, "E"), yymmn.), q=1) + %put &=ggLBOUND. &=ggHBOUND. &=ggN.; + %put &=gg0 &=gg1 &=gg2 ... &=gg11; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 4.** Functions cont. + If there is need for set-up something *before* or *after*: + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(h[10:12] + ,function = rand('Uniform') + ,before = call streaminit(123) + ,after = call sortn(of h[*]) + ) + %put &=h10. &=h11. &=h12.; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 5.** Fibonacci series. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(i[1:10] (10*0) + ,function = ifn(_I_ < 2, 1, sum(i[max(_I_-2,1)], i[max(_I_-1,2)]) ) ) + %put &=i1 &=i2 &=i3 &=i4 &=i5 &=i6 &=i7 &=i8 &=i9 &=i10; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 6a.** Quoted "Uppercas Letters" + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(UL[26] $, function = byte(rank("A")+_I_-1) , q=1) + %put &=UL1 &=UL2 ... &=UL25 &=UL26; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 6b.** "Lowercase Letters" + Extended by `macarray=Y` option and + the input mode support (with `I`). + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(ll[26] $, function = byte(rank("a")+_I_-1), macarray=Y) + %put *%ll(&llLBOUND.)*%ll(3)*%ll(4)*%ll(5)*...*%ll(25)*%ll(&llHBOUND.)*; + + %* The range handling, warning; + %put *%ll(265)*; + + %* The input mode; + %put *before:*%ll(2)*; + %let %ll(2,I) = bbbbb; + %put *after: *%ll(2)*; + + %* The range handling, error; + %let %ll(265,I) = bbb; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 7.** The use of `vnames=Y` + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(R R1978-R1982) + %put &=R1 &=R2 &=R3 &=R4 &=R5; + + %array(R R1978-R1982 (78:82)) + %put &=R1 &=R2 &=R3 &=R4 &=R5; + + %array(R R1978-R1982 (78:82), vnames=Y) + %put &=R1 &=R2 &=R3 &=R4 &=R5; + + %array(R R1978-R1982, vnames=Y) + %put &=R1 &=R2 &=R3 &=R4 &=R5; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 8.** A "no name" array i.e. the `_[*]` array + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(_[*] x1-x5 (1:5)) + %put _user_; + + %array(_[*] p q r s (4*42)) + %put _user_; + + %* If no variables names than use _1 _2 ... _N; + %array(_[4] (-1 -2 -3 -4)) + %put &=_1 &=_2 &=_3 &=_4; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 9.** Pure macro code can be used in a data step. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + data test1; + set sashelp.class; + %array(ds[*] d1-d4 (4*17)) + a1 = &ds1.; + a2 = &ds2.; + a3 = &ds3.; + a4 = &ds4.; + run; + + data test2; + set sashelp.class; + %array(_[*] j k l m (4*17)) + a1 = &j.; + a2 = &k.; + a3 = &l.; + a4 = &m.; + run; + + data test3; + set sashelp.class; + %array(alpha[*] j k l m (101 102 103 104), macarray=Y) + a1 = %alpha(1); + a2 = %alpha(2); + a3 = %alpha(3); + a4 = %alpha(4); + a5 = %alpha(555); + run; + + data test4; + set sashelp.class; + %array(beta[*] j k l m (101 102 103 104), vnames=Y, macarray=Y) + a1 = "%beta(1)"; + a2 = "%beta(2)"; + a3 = "%beta(3)"; + a4 = "%beta(4)"; + a5 = "%beta(555)"; + run; + + data test5; + set sashelp.class; + %array(gamma[4] $ 12 ("101" "102" "103" "104"), macarray=Y) + a1 = "%gamma(1)"; + a2 = "%gamma(2)"; + a3 = "%gamma(3)"; + a4 = "%gamma(4)"; + a5 = "%gamma(555)"; + run; + + data test6; + set sashelp.class; + %array(ds = sashelp.cars, vars = Cylinders|, macarray=Y) + a0 = %Cylinders(0); + a1 = %Cylinders(1); + a2 = %Cylinders(2); + a3 = %Cylinders(3); + a4 = %Cylinders(4); + a5 = %Cylinders(555); + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 10.** Creating an array from a dataset, basic case. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(ds = sashelp.class, vars = height weight age) + %put _user_; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 11. Creating an array from a dataset, advanced. + If: `vars = height#h weight weight|w age|` + then create: + 1. macroarray "h" with ALL(#) values of variable "height" + 2. macroarray "weight" with ALL(no separator is equivalent to #) values of variable "weight" + 3. macroarray "w" with UNIQUE(|) values of variable "weight" + 4. macroarray "age" with UNIQUE(|) values of variable "age" + Currently the only separator in VARS is a space. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(ds = sashelp.class, vars = height#h weight weight|w age|, q=1) + %put _user_; + + %array(ds = sashelp.class, vars = height#hght weight weight|wght age|, macarray=Y, q=1) + %put *%hght(&hghtLBOUND.)**%weight(2)**%wght(&wghtHBOUND.)**%age(3)*; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 12.** Creating an array from a dataset with dataset options + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(ds = sashelp.cars(obs=100 where=(Cylinders=6)), vars = Make| Type| Model, macarray=Y) + %put *%make(&makeLBOUND.)*%Model(2)*%Model(3)*%Model(4)*%type(&typeHBOUND.)*; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 13.** Creating an array and macro from existing list of macrovariables + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %let myTest3 = 13; + %let myTest6 = 16; + %let myTest9 = 19; + + %array(myTest, macarray=M, q=1) + %do_over(myTest, phrase = %nrstr(%put *&_I_.*%myTest(&_I_.)*;)) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- + + + +## >>> `%concatArrays()` macro: <<< ########### + +The `%concatArrays()` macro allows to concatenate +two macroarrays created by the `%array()` macro. + +By default values of the second macroarray are removed. + +Dimensions of the first macroarray are extended. + +The `%concatArrays()` macro executes like a pure macro code. + +### SYNTAX: ##################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%concatArrays( + first + ,second + <,removeSecond=Y> +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `first` - *Required*, a name of a macroarray created by the `%array()` macro. + +2. `second` - *Required*, a name of a macroarray created by the `%array()` macro. + +* `removeSecond=Y` - *Optional*, default value `Y`, if set to `Y` then + the second array is removed. + + + + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Concatenate macroarrays LL and MM. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(ll[2:4] $ 12, + function = quote(put(today() + 10*_I_, yymmdd10.)), + macarray=Y + ) + %array(mm[10:13] $ 12000, + function = quote(repeat("A",123*_I_)), + macarray=Y + ) + %put *%ll(2)*%ll(3)*%ll(4)*; + + %concatArrays(ll, mm); + %put *%ll(2)*%ll(3)*%ll(4)*%ll(5)*%ll(6)**%ll(7)*%ll(8)*; + + %put *%mm(10)**%mm(11)*%mm(12)*%mm(13)*; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Error handling. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %concatArrays(ll, ) + %concatArrays(, mm) + + %concatArrays(noExistA, noExistB) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--- + + + +## >>> `%deleteMacArray()` macro: <<< ####### + +The `%deleteMacArray()` macro allows to delete +macroarrays created by the `%array()` macro. + +The `%deleteMacArray()` macro executes like a pure macro code. + +### SYNTAX: ##################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%deleteMacArray( + arrs + <,macarray=N> +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `arrs` - *Required*, a space separated list of manes + of macroarray created by the `%array()` macro. + +* `macarray=N` - *Optional*, indicator should a macro + associated with macroarray to be deleted? + If `Y` or `YES` then the associated macro is deleted. + + + + +## >>> `%do_over()` macro: <<< ###################### + +The code of the macro was inspired by +*Ted Clay's* and *David Katz's* macro `%do_over()`. + +The `%DO_OVER()` macro allows to iterate over macroarray created with +the `macarray=Y` parameter of the `%ARRAY()` macro. + +The `%do_over()` macro executes like a pure macro code. + +### SYNTAX: ##################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%do_over( + array + <,phrase=%nrstr(%&array(&_I_.))> + <,between=%str( )> + <,which = > +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `array` - *Required*, indicates a macroarray which metadata (Lbound, Hbouns) + are to be used to loop in the `%do_over()` + +* `phrase=` - *Optional*, Default value `%nrstr(%&array(&_I_.))`, + a statement to be called in each iteration + of the internal do_over's loop. Loop iterator is `_I_`, + if you want to use `_I_` or array name + [e.g. `%myArr(&_I_.)`] *enclose it* in the `%NRSTR()` + macro quoting function. + +* `between=` - *Optional*, default value `%str( )` (space), + a statement to be called in between each + iteration of the internal do_over loop. + If macroquoted (e.g. `%str( + )`) then the `%unquote()` + function is automatically applied. + +* `which=` - *Optional*, a _SPACE_ separated list of indexes which + should be used to iterate over selected macroarray. + Possible special characters are `H` and `L` which means + *high* and *low* bound of an array, list could be set with + colons(`:`) in form of `start:end:by` (*no spaces between!*), + if `by` is omitted the default is `1`. If possible use + `1:5` rather `1 2 3 4 5` since the firs works faster. + + + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Simple looping. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(beta[*] j k l m (101 102 103 104), vnames=Y, macarray=Y) + + %put #%do_over(beta)#; + + %put #%do_over(beta, phrase=%nrstr("%beta(&_I_.)"), between=%str(,))#; + + data test1; + %array(beta[*] j k l m (101 102 103 104), vnames=Y, macarray=Y) + %do_over(beta, phrase=%nrstr(a&_I_. = "%beta(&_I_.)";)) + put _all_; + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Multiple arrays looping. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(alpha[*] j k l m n, vnames=Y, macarray=Y) + %array( beta[5] $ , function = "a", macarray=Y) + %array(gamma[4] (101 102 103 104), macarray=Y) + + data test2; + call streaminit(123); + %do_over(beta + , phrase = %nrstr(%beta(&_I_.) = %gamma(&_I_.) * rand('Uniform'); output;) + , between = put _all_; + ); + put _all_; + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 3.** Multiple arrays looping, cont. + Create multiple datasets. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %do_over(beta + , phrase = %nrstr( + data %alpha(&_I_.)2; + call streaminit(123); + %beta(&_I_.)x = %gamma(&_I_.) * rand('Uniform'); + output; + run; + ) + ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 4.** Multiple arrays looping, cont. + Create multiple datasets using a macro. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %macro doit(ds, var=a, val=1); + data &ds.; + call streaminit(123); + &var. = &val. * rand('Uniform'); + output; + run; + %mend doit; + + %do_over(beta + , phrase = %nrstr( + %DOIT(%alpha(&_I_.)1, var = %beta(&_I_.), val = %gamma(&_I_.)) + ) + ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 5.** `%do_over()` inside `%array()` + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(test[*] x1-x12 (1:12), macarray=Y) + + %put **%test(1)**%test(12)**; + + %put #%do_over(test)#; + + %array(abc[*] x1-x12 (%do_over(test,phrase=%nrstr(%eval(100-%test(&_I_.))))), macarray=Y) + + %put **%abc(1)**%abc(12)**; + + %put #%do_over(abc)#; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 6.** Looping over array with *macroquoted* separator. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(alpha[11] (5:15), macarray=Y) + + %let x = %do_over(alpha + , phrase = %NRSTR(%alpha(&_I_.)) + , between= %str( + ) + ); + %put &=x.; + %put %sysevalf(&x.); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 7.** Working with the `WHICH=` optional parameter + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(test[*] x01-x12, vnames= Y, macarray=Y) + + %put #%do_over(test)#; + + %put #%do_over(test, which= 1 3 5)#; + + %put #%do_over(test, which= 1:5)#; + + %put #%do_over(test, which= 1:5:2 7 8)#; + + %put #%do_over(test, which= L:H l:h)#; + + %put #%do_over(test, which= L:3 10:h)#; + + %put #%do_over(test, which= L:H h:l:-1 13 14)#; + + %put #%do_over(test, which= %eval(1+1):%eval(5+1))#; + + %put #%do_over(test, which= L:H h:l:-1 13 14, between=%str(,))#; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--- + + + +## >>> `%do_over2()` macro: <<< #################### + +The code of the macro was inspired by +*Ted Clay's* and *David Katz's* macro `%do_over()`. + +The `%DO_OVER2()` macro allows to iterate over *two* macroarray created with +the `macarray=Y` parameter of the `%ARRAY()` macro. + +The `%do_over2()` macro executes like a pure macro code. + +### SYNTAX: ##################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%do_over2( + arrayI + ,arrayJ + <,phrase=%nrstr(%&arrayI(&_I_.) %&arrayJ(&_J_.))> + <,between=%str( )> +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `arrayI` - Required, indicates the first macroarray which metadata (Lbound, Hbouns) + are to be used in the outer loop in the `%do_over2()` + +2. `arrayJ` - Required, indicates the second macroarray which metadata (Lbound, Hbouns) + are to be used in the inner loop in the `%do_over2()` + +* `phrase=` - *Optional*, default value `%nrstr(%&arrayI(&_I_.) %&arrayJ(&_J_.))`, + a statement to be called in each iteration + of the *inner* loop. The outer loop iterator is `_I_`, + the inner loop iterator is `_J_`, + if you want to use `_I_`, `_J_`, or arrays names + [e.g. `%myArr(&_I_.)`] *enclose them* in the `%NRSTR()` + macro quoting function. + +* `between=` - *Optional*, default value `%str( )` (space), + a statement to be called in between each + iteration of the internal do_over2 loop. + If macroquoted (e.g. `%str( + )`) then the `%unquote()` + function is automatically applied. + + + + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Looping over two arrays. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(alpha[*] j k l m n, vnames=Y, macarray=Y) + %array( beta[4] (101 102 103 104), macarray=Y) + + %put *%do_over2(alpha, beta + , phrase = %NRSTR((%alpha(&_I_.), %beta(&_J_))) + )*; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Looping over two arrays with a separator. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(alpha[11] (5:15), macarray=Y) + %array( beta[ 4] (101 102 103 104), macarray=Y) + + %let x = %do_over2(alpha, beta + , phrase = %NRSTR((%alpha(&_I_.) * %beta(&_J_))) + , between= + + ); + %put &=x.; + %put %sysevalf(&x.); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 3.** Looping over two arrays with *macroquoted* separator. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(alpha[11] (5:15), macarray=Y) + %array( beta[ 4] (101 102 103 104), macarray=Y) + + %let x = %do_over2(alpha, beta + , phrase = %NRSTR((%alpha(&_I_.) * %beta(&_J_))) + , between= %str( + ) + ); + %put &=x.; + %put %sysevalf(&x.); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--- + + + +## >>> `%do_over3()` macro: <<< #################### + +The code of the macro was inspired by +*Ted Clay's* and *David Katz's* macro `%do_over()`. + +The `%DO_OVER3()` macro allows to iterate over *three* macroarray created with +the `macarray=Y` parameter of the `%ARRAY()` macro. + +The `%do_over3()` macro executes like a pure macro code. + +### SYNTAX: ##################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%do_over2( + arrayI + ,arrayJ + ,arrayK + <,phrase=%nrstr(%&arrayI(&_I_.) %&arrayJ(&_J_.) %&arrayK(&_K_.))> + <,between=%str( )> +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `arrayI` - *Required*, indicates the first macroarray which metadata (Lbound, Hbouns) + are to be used in the outer loop in the `%do_over3()` + +2. `arrayJ` - *Required*, indicates the second macroarray which metadata (Lbound, Hbouns) + are to be used in the inner loop in the `%do_over3()` + +3. `arrayK` - *Required*, indicates the third macroarray which metadata (Lbound, Hbouns) + are to be used in the inner loop in the `%do_over3()` + +* `phrase=` - *Optional*, default value `%nrstr(%&arrayI(&_I_.) %&arrayJ(&_J_.) %&arrayK(&_K_.))`, + a statement to be called in each iteration + of the *inner* loop. The *outer* loop iterator is `_I_`, + the *middle* loop iterator is `_J_`, the *inner* loop iterator is `_K_`, + if you want to use `_I_`, `_J_`, `_K_`, or arrays names + [e.g. `%myArr(&_I_.)`] *enclose them* in the `%NRSTR()` + macro quoting function. + +* `between=` - *Optional*, default value `%str( )` (space), + a statement to be called in between each + iteration of the internal do_over2 loop. + If macroquoted (e.g. `%str( + )`) then the `%unquote()` + function is automatically applied. + + + + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Looping over 3 macroarrays. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(a1_[2] (0 1), macarray=Y) + %array(a2_[2] (2 3), macarray=Y) + %array(a3_[2] (4 5), macarray=Y) + + %do_over3(a1_, a2_, a3_ + , phrase = %NRSTR(%put (%a1_(&_I_.), %a2_(&_J_), %a3_(&_K_));) + ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**EXAMPLE 2.** Looping 3 times over a macroarray. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(a[0:2] (0 1 2), macarray=Y) + + %do_over3(a, a, a + , phrase = %NRSTR(%put (%a(&_I_.), %a(&_J_), %a(&_K_));) + ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--- + + + +## >>> `%make_do_over()` macro: <<< ########### + +The code of the macro was inspired by +*Ted Clay's* and *David Katz's* macro `%do_over()`. + +The `%make_do_over()` macro allows to generate +the `%DO_OVER()` macros. It works *only* for *n>3*! + +The `%make_do_over()` macro does *not* executes like a pure macro code. + +### SYNTAX: ##################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%make_do_over( + size +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `size` - *Required*, indicates the number of dimensions + (i.e. inner loops) of the `%DO_OVER()` macro. + + + + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Code of created "4-loop" `%DO_OVER4()` macro + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %macro do_over4( + arrayI1, + arrayI2, + arrayI3, + arrayI4, + phrase=%nrstr( + %&arrayI1(&_I1_.) + %&arrayI2(&_I2_.) + %&arrayI3(&_I3_.) + %&arrayI3(&_I4_.) + ), + between=%str( ) + ); + %local _I1_ _I2_ _I3_ _I4_; + %do _I1_ = &&&arrayI1.LBOUND %to &&&arrayI1.HBOUND; + %do _I2_ = &&&arrayI2.LBOUND %to &&&arrayI2.HBOUND; + %do _I3_ = &&&arrayI3.LBOUND %to &&&arrayI3.HBOUND; + %do _I4_ = &&&arrayI4.LBOUND %to &&&arrayI4.HBOUND; + %if not ( + &_I1_. = &&&arrayI1.LBOUND + AND &_I2_. = &&&arrayI2.LBOUND + AND &_I3_. = &&&arrayI3.LBOUND + AND &_I4_. = &&&arrayI4.LBOUND + ) + %then %do;%unquote(&between.)%end;%unquote(%unquote(&phrase.)) + %end; + %end; + %end; + %end; + %mend do_over4; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Create a "4-loop" `%DO_OVER4()` macro + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %make_do_over(4); + + %array(a1_[2] (0 1), macarray=Y) + + %do_over4(a1_, a1_, a1_, a1_ + , phrase = %NRSTR(%put (%a1_(&_I1_.), %a1_(&_I2_), %a1_(&_I3_), %a1_(&_I4_));) + ) + + %put *%do_over4(a1_, a1_, a1_, a1_ + , between = * + )*; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**EXAMPLE 3.** Create a "5-loop" `%DO_OVER5()` macro + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %make_do_over(5); + + %array(a1_[2] (0 1), macarray=Y) + + %do_over5(a1_, a1_, a1_, a1_, a1_ + , phrase = %NRSTR(%put (%a1_(&_I1_.), %a1_(&_I2_), %a1_(&_I3_), %a1_(&_I4_), %a1_(&_I5_));) + ) + + %put *%do_over5(a1_, a1_, a1_, a1_, a1_ + , between = * + )* + ; + + options nomprint; + data test2; + %do_over5(a1_, a1_, a1_, a1_, a1_ + , phrase = %NRSTR(x1 = %a1_(&_I1_.); x2 = %a1_(&_I2_); x3 = %a1_(&_I3_); x4 = %a1_(&_I4_); x5 = %a1_(&_I5_);) + , between = output; + ) + output; + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 4.** Create all from 6 to 10 "do_overs" + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(loop[6:10] (6:10), macarray=Y) + %do_over(loop + , phrase = %nrstr( + %make_do_over(%loop(&_I_.)) + ) + ); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--- + +## >>> `%mcHashTable()` macro: <<< ####################### + +The `%mcHashTable()` macro provided in the package +is designed to facilitate the idea of a "macro hash table" +concept, i.e. *a list of macrovariables with common prefix +and suffixes generated as a hash digest* which allows +to use values other than integers as indexes. + +The `%mcHashTable()` macro allows to generate other macros +which behaves like hash tables or dictionaries. See examples below. + +The `%mcHashTable()` macro executes like a pure macro code. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%mcHashTable( + H + <,METHOD> + <,HASH=> +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `H` - *Required*, a hash table macro name and a declaration/definition, + e.g. `mcHashTable(HT)`. It names a macro which is generated by + the `%mcHashTable()` macro. Provided name cannot be empty + or an underscore (`_`). No longer than *10* characters. + +2. `METHOD` - *Optional*, if empty (or DECLARE or DCL) then the code of + a macro hash table is compiled. + If `DELETE` then the macro hash table named by `H` and all + macrovariables named like "`&H._`" are deleted. + +* `HASH=` - *Optional*, indicates which hashing algorithms should be used, + available values are `CRC32` or `MD5`, the `CRC32` is the default. + +--- + +### THE CREATED MACRO `%&H.()`: #################################################### + +The created macro imitates behaviour of a hash table or a dictionary. +It is *not* dedicated for "long-ish" lists (above 1000 elements) since +the performance may be poor. + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%&H.( + METHOD + <,KEY=> + <,DATA=> +) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `METHOD` - *Required*, indicate what behaviour should be executed. + Allowed values are: + - `ADD`, adds key and data portion to the macro hash table, + *multiple data portions* are available for one key. + - `FIND`, tests if given key exists in the macro hash table + and, if yes, returns data value associated with the key. + For multiple data portions see the `data=` parameter. + - `DP` (data portion) or `CHECK`, returns the number of data + portions for a given key. + - `CLEAR` removes all data and keys values. + - `KEYIDX`, allows to get data by the key index rather than value. + - `KEYVAL`, returns key value for a given key index. + - `CHECKIDX`, returns the number of data portions for + a given key index. + +* `KEY=` - *Optional*, provides key value for `ADD`, `FIND`,`DP`, `CHECK` + `CHECKIDX`, `KEYIDX`, and `KEYVAL` methods. Leading and trimming + spaces are removed from the value. + The `hashing(CRC32,...)` function or the `MD5(...)` function is + used to generate the hash. + +* `DATA=` - *Optional*, provides data value for the `ADD` method and + for the`FIND` method provides data portion number to be + extracted. Default value is `1` (used by the `FIND` method). + + +When macro is executed and when data are added the following types of +*global* macrovariables are created: +- `&H._########`, +- `&H._########_Xk`, +- `&H._########_Xi`, +- `&H._########_Xi_j`, +- `&H._KEYNUM`, +- and `&H._KEY_i`. + +The `#` represents value generated by the `hashing(CRC32,...)` function +or the `MD5(...)` function for the given key. + +The first type keeps information about possible collision for the key. + +The second type keeps information about value of a given key, +the `X` keeps the track of other colliding keys. + +The third type keeps information about number of data portions +for given key, the `X` keeps the track of other colliding keys. + +The fourth type keeps the data portion, the `j` indicates data portion number. + +The fifth type keeps the number of unique values of the key. + +The sixth type keeps the list of unique values of the key, +the `i` indicates key number. + +See examples below to see use cases. + +--- + +### EXAMPLES AND USECASES: #################################################### + + +**EXAMPLE 1.** Basic use-case. + Creating macro hash table, macro `HT` is generated. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%mcHashTable(HT) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Add elements to the `HT`. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%HT(ADD,key=x,data=17) +%HT(ADD,key=y,data=42) +%HT(ADD,key=z,data=303) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Add some duplicates for the key x. + See macrovariables created. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%HT(ADD,key=x,data=18) +%HT(ADD,key=x,data=19) + +%put _user_; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Check the number od data portions in macrohash + for the key `x` and non existing key `t`. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%put ##%HT(DP,key=x)##; +%put ##%HT(DP,key=t)##; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Check the number od data portions in macrohash + for the key index 1 and 4. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%put ##%HT(CHECKIDX,key=1)##; +%put ##%HT(CHECKIDX,key=4)##; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Prints first data values for various keys. + Key `t` does not exist in the macrohash. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%put #%HT(FIND,key=x)#; +%put #%HT(FIND,key=y)#; +%put #%HT(FIND,key=z)#; +%put #%HT(FIND,key=t)#; + +%put #%HT(FIND,key=x,data=2)#; +%put #%HT(FIND,key=x,data=3)#; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Print first and subsequent data values + for a given KeyIDX. Index `4` does not exist. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%put #%HT(KEYIDX,key=1)#; +%put #%HT(KEYIDX,key=2)#; +%put #%HT(KEYIDX,key=3)#; +%put #%HT(KEYIDX,key=4)#; + +%put #%HT(KEYIDX,key=1,data=2)#; +%put #%HT(KEYIDX,key=1,data=3)#; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Print the key values for a given KeyIDX. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%put #%HT(KEYVAL,key=1)#; +%put #%HT(KEYVAL,key=2)#; +%put #%HT(KEYVAL,key=3)#; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Clear and delete macro hash table `HT`. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%HT(CLEAR) +%mcHashTable(HT,DELETE) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Combine `CHECK` and `FIND` methods + with macros `%array()` and `%do_over()` + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%mcHashTable(H) +%H(ADD,key=x,data=17) +%H(ADD,key=x,data=18) +%H(ADD,key=x,data=19) + +%array(A[%H(CHECK,key=x)]); + +%put %do_over(A, phrase=%nrstr( + %H(FIND,key=x,data=&_i_) +), between = %str(,)); + +%mcHashTable(H,delete) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 3.** Populate macro hash table from a dataset. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%mcHashTable(CLASS) +%let t = %sysfunc(datetime()); +data _null_; + set sashelp.class; + call execute('%CLASS(ADD,key=' !! name !! ',data=' !! age !! ')'); + call execute('%CLASS(ADD,key=' !! name !! ',data=' !! weight !! ')'); + call execute('%CLASS(ADD,key=' !! name !! ',data=' !! height !! ')'); +run; +%put t = %sysevalf(%sysfunc(datetime()) - &t.); +%put _user_; +%CLASS(CLEAR) + + +%mcHashTable(CARS) +%let t = %sysfunc(datetime()); +data _null_; + set sashelp.cars; + call execute('%CARS(ADD,key=' !! catx("|",make,model) !! ',data=' !! MPG_CITY !! ')'); +run; +%put t = %sysevalf(%sysfunc(datetime()) - &t.); +%* %put _user_; +%CARS(CLEAR) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 4.** Data portion may require quoting and un-quoting.. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%mcHashTable(CODE) +%CODE(CLEAR) +%CODE(ADD,key=data, data=%str(data test; x = 42; run;)) +%CODE(ADD,key=proc, data=%str(proc print; run;)) +%CODE(ADD,key=macro,data=%nrstr(%put *****;)) + +%CODE(FIND,key=data) +%CODE(FIND,key=proc) +%unquote(%CODE(FIND,key=macro)) + +%mcHashTable(CODE,DELETE) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 5.** Longer lists. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%let size = 1000; + +%mcHashTable(AAA) +%mcHashTable(BBB) +%mcHashTable(CCC) +%mcHashTable(DDD) + +%let t = %sysfunc(datetime()); +data _null_; + do i = 1 to &size.; + call execute(cats('%AAA(ADD,key=A', i, ',data=', i, ')')); + end; +run; +%put t = %sysevalf(%sysfunc(datetime()) - &t.); +%put &=AAA_KEYSNUM; +%AAA(CLEAR) + +%let t = %sysfunc(datetime()); +data _null_; + do i = 1 to &size.; + call execute(cats('%BBB(ADD,key=B', i, ',data=', i, ')')); + call execute(cats('%BBB(ADD,key=B', i, ',data=', i+1, ')')); + end; +run; +%put t = %sysevalf(%sysfunc(datetime()) - &t.); +%put &=BBB_KEYSNUM; +%BBB(CLEAR) + +%let t = %sysfunc(datetime()); +data _null_; + t= datetime(); + do i = 1 to &size.; + call execute(cats('%CCC(ADD,key=C', i, ',data=', i, ')')); + end; + t = datetime() - t; + put t=; + t= datetime(); + do i = 1 to &size.; + call execute(cats('%CCC(ADD,key=C', i, ',data=', i+1, ')')); + end; + t = datetime() - t; + put t=; +run; +%put t = %sysevalf(%sysfunc(datetime()) - &t.); + +%let t = %sysfunc(datetime()); +data test; + do i = 1 to &size.; + x = resolve(cats('%CCC(FIND,key=C', i, ',data=1)')); + y = resolve(cats('%CCC(FIND,key=C', i, ',data=2)')); + output; + end; +run; +%put t = %sysevalf(%sysfunc(datetime()) - &t.); +%put &=CCC_KEYSNUM; +%CCC(CLEAR) + +%let t = %sysfunc(datetime()); +data _null_; + do i = 1 to &size.; + call execute(cats('%DDD(ADD,key=D,data=', i, ')')); + end; +run; +%put t = %sysevalf(%sysfunc(datetime()) - &t.); +%put &=DDD_KEYSNUM; +%put %DDD(CHECK,key=D); +%DDD(CLEAR) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 6.** Forbidden names. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%mcHashTable() +%mcHashTable(_) + +%mcHashTable(ABCDEFGHIJKLMNOPQ) %* bad; +%mcHashTable(ABCDEFGHIJKLMNOP) %* good; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**EXAMPLE 7.** Hashing algorithms. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%mcHashTable(H1,DCL,HASH=MD5) +%mcHashTable(H2,DECLARE,HASH=CRC32) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- + +## >>> `%mcDictionary()` macro: <<< ####################### + +The `%mcDictionary()` macro provided in the package +is designed to facilitate the idea of a "macro dictionary" +concept, i.e. *a list of macrovariables with common prefix +and suffixes generated as a hash digest* which allows +to use values other than integers as indexes. + +The `%mcDictionary()` macro allows to generate other macros +which behaves like a dictionary. See examples below. + +The `%mcDictionary()` macro executes like a pure macro code. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%mcDictionary( + H + <,METHOD> + <,DS=> + <,K=Key> + <,D=Data> +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `H` - *Required*, a dictionary macro name and a declaration/definition, + e.g. `mcDictionary(HT)`. It names a macro which is generated by + the `%mcDictionary()` macro. Provided name cannot be empty + or an underscore (`_`). No longer than *13* characters. + +2. `METHOD` - *Optional*, if empty (or DECLARE or DCL) then the code of + a macro dictionary is compiled. + If `DELETE` then the macro dictionary named by `H` and all + macrovariables named like "`&H._`" are deleted. + +* `DS=` - *Optional*, if NOT empty then the `&DS.` dataset is used to + populate dictionary with keys from variable `&K.` and data + from variable `&D.` Works only during declaration. + +* `K=` - *Optional*, if the `&DS.` is NOT empty then `&K.` holds a name of + a variable which keeps or an expression which generates keys values. + Default is `Key`. + +* `D=` - *Optional*, if the `&DS.` is NOT empty then `&D.` holds a name of + a variable which keeps or an expression which generates data values. + Default is `Data`. + +--- + +### THE CREATED MACRO `%&H.()`: #################################################### + +The created macro imitates behaviour of a dictionary. + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%&H.( + METHOD + <,KEY=> + <,DATA=> +) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `METHOD` - *Required*, indicate what behaviour should be executed. + Allowed values are: + - `ADD`, adds key and data portion to the macro dictionary, + *multiple data portions* are NOT available for one key. + - `FIND`, tests if given key exists in the macro dictionary + and, if yes, returns data value associated with the key. + For multiple data portions see the `data=` parameter. + - `CHECK`, returns indicator if the key exists in dictionary. + - `DEL`, removes key and data portion from the macro dictionary. + - `LIST`, prints out a dictionary to the log. + - `CLEAR` removes all data and keys values. + +* `KEY=` - *Optional*, provides key value for `ADD`, `FIND`, `CHECK` + and `DEL` methods. + Leading and trimming spaces are removed from the value. + The `MD5(...)` function is used to generate the hash. + Default value is `_`. + +* `DATA=` - *Optional*, provides data value for the `ADD` method. + Default value is blank. + + +When macro is executed and when data are added the following types of +*global* macrovariables are created: +- `&H._########_K`, +- `&H._########_V`, +- `&H._KEYSNUM`. + +The `#` represents value generated by the `MD5(...)` function for the given key. + +The first type keeps information about the key. + +The second type keeps information about the value of a given key + +The third type keeps the number of unique values of the key. + +See examples below to see use cases. + +--- + +### EXAMPLES AND USECASES: #################################################### + + +**EXAMPLE 1.** Basic use-case. + Creating macro dictionary, macro `Dict` is generated. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%mcDictionary(Dict) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Add elements to the `Dict`. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%Dict(ADD,key=x,data=17) +%Dict(ADD,key=y y,data=42) +%Dict(ADD,key=z z z,data=303) + +%put _user_; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Add some duplicates for the key x. + See macrovariables created. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%Dict(ADD,key=x,data=18) + +%put _user_; + +%Dict(ADD,key=x,data=19) + +%put _user_; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Check for the key `x` and non existing key `t`. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%put ##%Dict(CHECK,key=x)##; +%put ##%Dict(CHECK,key=t)##; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Prints data values for various keys. + Key `t` does not exist in the macrodictionary. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%put #%Dict(FIND,key=x)#; +%put #%Dict(FIND,key=y y)#; +%put #%Dict(FIND,key=z z z)#; +%put #%Dict(FIND,key=t)#; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + List dictionary content to the log. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%Dict(LIST); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Delete keys. + Key `t` does not exist in the macrodictionary. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%put #%Dict(DEL,key=z z z)#; +%put _user_; +%put #%Dict(DEL,key=t)#; +%put _user_; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Clear and delete macro dictionary `Dict`. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%Dict(CLEAR) +%put _user_; + +%mcDictionary(Dict,DELETE) +%put _user_; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2A.** Populate macro dictionary from a dataset "by hand". + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%mcDictionary(CLASS) +%let t = %sysfunc(datetime()); +data _null_; + set sashelp.class; + call execute('%CLASS(ADD,key=' !! name !! ',data=' !! age !! ')'); +run; +%put t = %sysevalf(%sysfunc(datetime()) - &t.); +%put &=Class_KEYSNUM.; +%put _user_; +%CLASS(CLEAR) + + +%mcDictionary(CARS) +%let t = %sysfunc(datetime()); +data _null_; + set sashelp.cars(obs=42); + call execute('%CARS(ADD,key=' !! catx("|",make,model,type) !! ',data=' !! put(MPG_CITY*10,dollar10.2) !! ')'); +run; +%put t = %sysevalf(%sysfunc(datetime()) - &t.); +%put &=CARS_KEYSNUM.; +%CARS(LIST); + +%put %CARS(F,key=Audi|TT 3.2 coupe 2dr (convertible)|Sports); + +%CARS(CLEAR) +%put &=CARS_KEYSNUM.; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2B.** Populate macro dictionary from a dataset "automatically". + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%let t = %sysfunc(datetime()); +%mcDictionary(CLASS,DCL,DS=sashelp.class,k=name,d=_N_) +%put t = %sysevalf(%sysfunc(datetime()) - &t.); +%put &=CLASS_KEYSNUM.; +%put _user_; +%CLASS(CLEAR) + + +%let t = %sysfunc(datetime()); +%mcDictionary(CARS,DCL,DS=sashelp.cars(obs=42),k=catx("|",make,model,type),d=put(MPG_CITY*10,dollar10.2)) +%put t = %sysevalf(%sysfunc(datetime()) - &t.); +%put &=CARS_KEYSNUM.; +%CARS(LIST); + +%put %CARS(F,key=Audi|TT 3.2 coupe 2dr (convertible)|Sports); + +%CARS(CLEAR) +%put &=CARS_KEYSNUM.; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 3.** Data portion may require quoting and un-quoting. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%mcDictionary(CODE) +%CODE(CLEAR) +%CODE(ADD,key=data, data=%str(data test; x = 42; run;)) +%CODE(ADD,key=proc, data=%str(proc print; run;)) +%CODE(ADD,key=macro,data=%nrstr(%put *1*2*3*4*;)) + +%CODE(FIND,key=data) +%CODE(FIND,key=proc) +%unquote(%CODE(FIND,key=macro)) + +%CODE(LIST); + +%mcDictionary(CODE,DELETE) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 4.** Longer lists. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%let size = 1000; + +%mcDictionary(AAA) + +%let t = %sysfunc(datetime()); +data _null_; + do i = 1 to &size.; + call execute(cats('%AAA(ADD,key=A', i, ',data=', i, ')')); + end; +run; +%put t = %sysevalf(%sysfunc(datetime()) - &t.); +%put %AAA(F,key=A555) %AAA(CHECK,key=A555); +%put &=AAA_KEYSNUM; +%AAA(CLEAR) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 5.** Forbidden names. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%mcDictionary() +%mcDictionary(_) + +%mcDictionary(ABCDEFGHIJKLMNOPQ) %* bad; +%mcDictionary(ABCDEFGHIJKLMNOP) %* good; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 6.** More fun with datasets. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + +data work.metadata; + input key :$16. data :$128.; +cards; +ID ABC-123-XYZ +path /path/to/study/data +cutoffDT 2023-01-01 +startDT 2020-01-01 +endDT 2024-12-31 +MedDRA v26.0 +; +run; +proc print; +run; + +%mcDictionary(Study,dcl,DS=work.metadata) + +%put _user_; + +%put *%Study(F,key=ID)**%Study(C,key=ID)*; + +title1 "Study %Study(F,key=ID) is located at %Study(F,key=path)"; +title2 "it starts %Study(F,key=startDT) and ends %Study(F,key=endDT)"; +footnote "MedDRA version: %Study(F,key=MedDRA)"; + +proc print data=sashelp.class(obs=7); +run; + +title; +footnote; + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- + +## >>> `%QzipArrays()` macro: <<< ####################### + +The zipArrays() and QzipArrays() macros +allow to use a function on elements of pair of +macroarrays. + +For two macroarrays the corresponding +elements are taken and the macro applies a function, provided by user, +to calculate result of the function on taken elements. + +When one of the arrays is shorter then elements are, by default, +"reused" starting from the beginning. But this behaviour can be altered. +See examples for the details. + +By default newly created macroarray name is concatenation +of first 13 characters of names of arrays used to create the new one, +e.g. if arrays names are `abc` and `def` then the result name is `abcdef`, +if arrays names are `abcd1234567890` and `efgh1234567890` then the result +name is `abcd123456789efgh123456789` + +The `zipArrays()` returns unquoted value [by `%unquote()`]. +The `QzipArrays()` returns quoted value [by `%superq()`]. + +See examples below for the details. + +The `%QzipArrays()` macro executes like a pure macro code. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%QzipArrays( + first + ,second + <,function=> + <,operator=> + <,argBf=> + <,argMd=> + <,argAf=> + <,format=> + <,result=> + <,macarray=> + <,reuse=> +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `first` - *Required*, a space separated list of texts. + +2. `second` - *Required*, a space separated list of texts. + +* `function = cat` - *Optional*, default value is `cat`, + a function which will be applied + to corresponding pairs of elements of + the first and the second list. + +* `operator =` - *Optional*, default value is empty, + arithmetic infix operator used with elements + the first and the second list. The first + list is used on the left side of the operator + the second list is used on the right side + of the operator. + +* `argBf =` - *Optional*, default value is empty, + arguments of the function inserted + *before* elements the first list. + If multiple should be comma separated. + +* `argMd =` - *Optional*, default value is empty, + arguments of the function inserted + *between* elements the first list and + the second list. + If multiple should be comma separated. + +* `argAf =` - *Optional*, default value is empty, + arguments of the function inserted + *after* elements the second list. + If multiple should be comma separated. + +* `format=` - *Optional*, default value is empty, + indicates a format which should be used + to format the result, does not work when + the `operator=` is used. + +* `result=` - *Optional*, default value is empty, + indicates a name of newly created macroarray, + by default created macroarray name is concatenation + of first 13 characters of names of arrays used + to create the new one. + +* `macarray=N` - *Optional*, default value is `N`, + if set to `Y`/`YES` then a macro, named with + the array name, is compiled to create convenient + envelope for multiple ampersands, see the + `%array()` macro for details. + +* `reuse=Y` - *Optional*, default value is `Y`, + when one of the arrays is shorter then elements + are *reused* starting from the beginning. + If `CP` then function is executed on the *Cartesian + product* of arrays elements. Any other value will + cut the process with the end of the shorter array. + See examples for the details. + +### EXAMPLES AND USECASES: #################################################### + +See examples in `%zipArrays()` help for the details. + +--- + +## >>> `%zipArrays()` macro: <<< ####################### + +The zipArrays() and QzipArrays() macros +allow to use a function on elements of pair of +macroarrays. + +For two macroarrays the corresponding +elements are taken and the macro applies a function, provided by user, +to calculate result of the function on taken elements. + +When one of the arrays is shorter then elements are, by default, +"reused" starting from the beginning. But this behaviour can be altered. +See examples for the details. + +By default newly created macroarray name is concatenation +of first 13 characters of names of arrays used to create the new one, +e.g. if arrays names are `abc` and `def` then the result name is `abcdef`, +if arrays names are `abcd1234567890` and `efgh1234567890` then the result +name is `abcd123456789efgh123456789` + +The `zipArrays()` returns unquoted value [by `%unquote()`]. +The `QzipArrays()` returns quoted value [by `%superq()`]. + +See examples below for the details. + +The `%zipArrays()` macro executes like a pure macro code. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%zipArrays( + first + ,second + <,function=> + <,operator=> + <,argBf=> + <,argMd=> + <,argAf=> + <,format=> + <,result=> + <,macarray=> + <,reuse=> +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `first` - *Required*, a space separated list of texts. + +2. `second` - *Required*, a space separated list of texts. + +* `function = cat` - *Optional*, default value is `cat`, + a function which will be applied + to corresponding pairs of elements of + the first and the second list. + +* `operator =` - *Optional*, default value is empty, + arithmetic infix operator used with elements + the first and the second list. The first + list is used on the left side of the operator + the second list is used on the right side + of the operator. + +* `argBf =` - *Optional*, default value is empty, + arguments of the function inserted + *before* elements the first list. + If multiple should be comma separated. + +* `argMd =` - *Optional*, default value is empty, + arguments of the function inserted + *between* elements the first list and + the second list. + If multiple should be comma separated. + +* `argAf =` - *Optional*, default value is empty, + arguments of the function inserted + *after* elements the second list. + If multiple should be comma separated. + +* `format=` - *Optional*, default value is empty, + indicates a format which should be used + to format the result, does not work when + the `operator=` is used. + +* `result=` - *Optional*, default value is empty, + indicates a name of newly created macroarray, + by default created macroarray name is concatenation + of first 13 characters of names of arrays used + to create the new one. + +* `macarray=N` - *Optional*, default value is `N`, + if set to `Y`/`YES` then a macro, named with + the array name, is compiled to create convenient + envelope for multiple ampersands, see the + `%array()` macro for details. + +* `reuse=Y` - *Optional*, default value is `Y`, + when one of the arrays is shorter then elements + are *reused* starting from the beginning. + If `CP` then function is executed on the *Cartesian + product* of arrays elements. Any other value will + cut the process with the end of the shorter array. + See examples for the details. + +### EXAMPLES AND USECASES: #################################################### + +**EXAMPLE 1.** Simple concatenation of elements: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%array(a[*] x1-x3 (1:3)) +%array(b[*] x1-x5 (11:15)) + +%put _user_; + +%zipArrays(a, b); +%put _user_; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Shorter list is "reused": +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%array(a[6] (1:6)) +%array(b[3] (10 20 30)) + +%zipArrays(a, b, result=A_and_B, macarray=Y); +%put %do_over(A_and_B); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 3.** Use of the `operator=`: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%array(c[0:4] (000 100 200 300 400)) +%array(d[2:16] (1002:1016)) + +%zipArrays(c, d, operator=+, result=C_plus_D, macarray=Y); +%put (%do_over(C_plus_D)); + +%put %C_plus_D(1); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 4.** If one of array names is empty or an array does not exist: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%array(a[6] (1:6)) +%array(b[3] (10 20 30)) + +%zipArrays(a, ); +%zipArrays(, b); + +%zipArrays(a, z); +%zipArrays(z, b); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 5.** Use of the `function=`: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%array(one[3] A B C, vnames=Y) +%array(two[5] p q r s t, vnames=Y) + +%zipArrays( + one +,two +,function = catx +,argBf = %str( ) +,format = $quote. +,macarray=Y +) +%put %do_over(onetwo); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 6.** To reuse or not to reuse, or maybe Cartesian product: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%array(e[3] (10 20 30)) +%array(f[2] (5:6)) + +%zipArrays(e, f, reuse=n, operator=+, macarray=Y, result=_noReuse); +%zipArrays(e, f, reuse=y, operator=+, macarray=Y, result=_yesReuse); +%zipArrays(e, f, reuse=cp, operator=+, macarray=Y, result=_cartProdReuse); + +%put %do_over(_noReuse); +%put %do_over(_yesReuse); +%put %do_over(_cartProdReuse); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 7.** Use middle argument: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%array(yr[3] (2018:2020)) +%array(mth[12] (1:12)) + +%zipArrays(mth, yr, argMd=5, function=MDY, format=date11., macarray=Y); +%put %do_over(mthyr); + +%zipArrays(mth, yr, argMd=5, function=MDY, format=date11., macarray=Y, reuse=cp); +%put %do_over(mthyr); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- + +## >>> `%sortMacroArray()` macro: <<< ####################### + +The sortMacroArray() macro +allow to sort elements of a macroarray. + +The **limitation** is that sorted values are limited to 32767 bytes of length. + +See examples below for the details. + +### SYNTAX: ################################################################### + +The basic syntax is the following, the `<...>` means optional parameters: +~~~~~~~~~~~~~~~~~~~~~~~sas +%sortMacroArray( + array + <,valLength=> + <,outSet=> + <,sortseq=> +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `array` - *Required*, name of an array generated by the `%array()` macro. + +* `valLength = 32767` - *Optional*, default value is `32767`, + maximum length of a variable storing macrovariable data. + (the reason of 32767 limitation) + +* `outSet = _NULL_` - *Optional*, default value is `_NULL_`, + an optional output dataset name. + +* `sortseq =` - *Optional*, default value is `LINGUISTIC(NUMERIC_COLLATION = ON)`, + sorting options for use in an internal `Proc SORT`. + +### EXAMPLES AND USECASES: #################################################### + + +**EXAMPLE 1.** Basic use-case. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + +options mprint; +ods html; +ods listing close; + + +%array(hij [4:9] $ 512 ("C33" "B22" "A11" "A01" "A02" "X42"), macarray=Y) + +%put NOTE: %do_over(hij); + +%sortMacroArray(hij, valLength=3, outSet = A_NULL_(compress=char)) + +%put NOTE: %do_over(hij); + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 2.** Basic use-case. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + +options mprint; +ods html; +ods listing close; + + +%array(ds = sashelp.class, vars = name|NNN height|h, macarray=Y) +%array(ds = sashelp.cars, vars = model|, macarray=Y) + +%put NOTE: %do_over(NNN); +%put NOTE: %do_over(H); +%put NOTE: %do_over(model); + +%sortMacroArray(NNN, valLength=30, outSet = A_NULL_(compress=char)) +%sortMacroArray(H, valLength=32) +%sortMacroArray(model, valLength=120) + +%put NOTE: %do_over(NNN); +%put NOTE: %do_over(H); +%put NOTE: %do_over(model); + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- + +## License #################################################################### + +Copyright (c) Bartosz Jablonski, since January 2019 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- diff --git a/hist/1.2.6/macroarray.zip b/hist/1.2.6/macroarray.zip new file mode 100644 index 0000000000000000000000000000000000000000..c42bf1c8ae42b81882faf91b11b1d9af2fc98297 GIT binary patch literal 53447 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 literal 0 HcmV?d00001 diff --git a/macroarray.md b/macroarray.md index e93fc01..58b4192 100644 --- a/macroarray.md +++ b/macroarray.md @@ -19,7 +19,7 @@ --- -# The macroArray package [ver. 1.2.5] ############################################### +# The macroArray package [ver. 1.2.6] ############################################### The **macroArray** package implements a macroarray facility: - `%array()`, @@ -78,7 +78,7 @@ Required SAS Components: *SAS package generated by generatePackage, version 20231123* The SHA256 hash digest for package macroArray: -`F*FFF2C3D854F9B5677F561BA2EB6FAA2CCC652D81F6AF9473ADF0A4CE977E43F0` +`F*3F3893F1FCD78719543703E4353F4CC19811D247C016F220FF729B283C1AD790` --- # Content description ############################################################################################ @@ -1211,7 +1211,7 @@ The basic syntax is the following, the `<...>` means optional parameters: 1. `H` - *Required*, a hash table macro name and a declaration/definition, e.g. `mcHashTable(HT)`. It names a macro which is generated by the `%mcHashTable()` macro. Provided name cannot be empty - or an underscore (`_`). No longer than *16* characters. + or an underscore (`_`). No longer than *10* characters. 2. `METHOD` - *Optional*, if empty (or DECLARE or DCL) then the code of a macro hash table is compiled. @@ -1568,7 +1568,7 @@ The basic syntax is the following, the `<...>` means optional parameters: 1. `H` - *Required*, a dictionary macro name and a declaration/definition, e.g. `mcDictionary(HT)`. It names a macro which is generated by the `%mcDictionary()` macro. Provided name cannot be empty - or an underscore (`_`). No longer than *16* characters. + or an underscore (`_`). No longer than *13* characters. 2. `METHOD` - *Optional*, if empty (or DECLARE or DCL) then the code of a macro dictionary is compiled. diff --git a/macroarray.zip b/macroarray.zip index e7a003247c8e33efe777e1aa19ff7a814acd1506..c42bf1c8ae42b81882faf91b11b1d9af2fc98297 100644 GIT binary patch delta 19179 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%0DZ4$mc~>+>u~MgP9W*%nB-MI8~w_h3jQh! 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 RQ0cu8i0(ZKY3QK6_zQ)(TO|Mh delta 19100 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 h8m|~Klz|HifNod;J}WaO=0gyKdaY4I%