From 5b9113f1523cdd641f97af6d62e7d8c059e4a8ac Mon Sep 17 00:00:00 2001 From: Bart Jablonski Date: Mon, 26 Jan 2026 17:23:38 +0100 Subject: [PATCH] The macroArray package [ver. 1.3.1] The macroArray package [ver. 1.3.1] Package regenerated with SAS Packages Framework, version 20250126. No functional changes, documentation cleaned up. --- README.md | 2 +- hist/macroarray_1.3.1_.md | 2468 ++++++++++++++++++++++++++++++++++++ hist/macroarray_1.3.1_.zip | Bin 0 -> 56752 bytes macroarray.md | 12 +- macroarray.zip | Bin 56263 -> 56752 bytes 5 files changed, 2475 insertions(+), 7 deletions(-) create mode 100644 hist/macroarray_1.3.1_.md create mode 100644 hist/macroarray_1.3.1_.zip diff --git a/README.md b/README.md index 761ddcf..084163d 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*C6C2B5507B6590365222FC764076E294CCE3AAE99971D9CAA942F8BAEBEFAE24 +SHA256 digest for the latest version of `macroArray`: F*9DA64CA9A745E1DB7176F7AF4459BB014F61F71626473ABF6471A32689E14FF1 [**Documentation for macroArray**](./macroarray.md "Documentation for macroArray") diff --git a/hist/macroarray_1.3.1_.md b/hist/macroarray_1.3.1_.md new file mode 100644 index 0000000..9aff59d --- /dev/null +++ b/hist/macroarray_1.3.1_.md @@ -0,0 +1,2468 @@ +# Documentation for the `macroArray` package. + +---------------------------------------------------------------- + + *Macroarrays for macro codes* + +---------------------------------------------------------------- + +### Version information: + +- Package: macroArray +- Version: 1.3.1 +- Generated: 2026-01-26T15:33:03 +- Author(s): Bartosz Jablonski (yabwon@gmail.com) +- Maintainer(s): Bartosz Jablonski (yabwon@gmail.com) +- License: MIT +- File SHA256: `F*9DA64CA9A745E1DB7176F7AF4459BB014F61F71626473ABF6471A32689E14FF1` for this version +- Content SHA256: `C*15A52658C8CBF9AB36AB1CA847FA628CCC6E9C67F625FFD3A959EB191445F780` for this version + +--- + +# The `macroArray` package, version: `1.3.1`; + +--- + + +The **macroArray** package implements a macroarray facility. + +The set of macros, which emulates classic +data-step-array functionality on the macro +programming level, is provided. + +Some of components are: +- `%array()`, +- `%do_over()`, +- `%make_do_over()`, +- `%deletemacarray()`, +- `%concatarrays()`, +- `%appendcell()`, +- `%mcHashTable()`, +- `%zipArrays()`, +- `%sortMacroArray()`, +- `%mcDictionary()`, +- etc. + +*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. | + +--- + + +--- + + +--- + +Required SAS Components: + - Base SAS Software + +--- + + +--------------------------------------------------------------------- + +*SAS package generated by SAS Package Framework, version `20260126`,* +*under `WIN`(`X64_10PRO`) operating system,* +*using SAS release: `9.04.01M9P06042025`.* + +--------------------------------------------------------------------- + +# The `macroArray` package content +The `macroArray` package consists of the following content: + +1. [`%appendarray()` macro ](#appendarray-macro-1 ) +2. [`%appendcell()` macro ](#appendcell-macro-2 ) +3. [`%array()` macro ](#array-macro-3 ) +4. [`%concatarrays()` macro ](#concatarrays-macro-4 ) +5. [`%deletemacarray()` macro ](#deletemacarray-macro-5 ) +6. [`%do_over()` macro ](#doover-macro-6 ) +7. [`%do_over2()` macro ](#doover2-macro-7 ) +8. [`%do_over3()` macro ](#doover3-macro-8 ) +9. [`%make_do_over()` macro ](#makedoover-macro-9 ) +10. [`%mcdictionary()` macro ](#mcdictionary-macro-10 ) +11. [`%mchashtable()` macro ](#mchashtable-macro-11 ) +12. [`%qziparrays()` macro ](#qziparrays-macro-12 ) +13. [`%sortmacroarray()` macro ](#sortmacroarray-macro-13 ) +14. [`%ziparrays()` macro ](#ziparrays-macro-14 ) + + +15. [License note](#license) + +--- + +## `%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( + arrays + <,phrase = %nrstr(%&array(&_I_.))> + <,between = %str( )> + <,which = > + <,check = 0> + <,rephrase = > + <,trigger = ?> + <,unq = 1> +) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Arguments description**: + +1. `arrays` - *Required*, a space-separated list of macroarrays names. + The first one identifies the macroarray which metadata + (Lbound, Hbouns, and N) are 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. + +* `check=` - *Optional*, indicates should a check for a macro corresponding + to a macroarray be executed. If the macro does not exist warning + is issued and the `do_over` stops. + Default value `0` means: do not execute check. + +* `rephrase=` - *Optional*, this parameter allows for an alternative approach + in providing the phrase to be looped over. The idea is to make + writing the phrase string code more convenient and easy to grasp. + The value is a string containing triggers (symbols) that are + replaced by proper macroarray calls. For example, if a macroarray + `myArr` has 7 values form `varName1` to `varName7` and you want + to use them as arguments in code renaming variables, say + `rename old_varName1=new_varName1 ... ;`, instead typing phrase: + `rename %do_over(myArr,phrase=%nrstr(old_%myArr(&_I_.)=new_%myArr(&_I_.)));` + you can type much easier rephrase: + `rename %do_over(myArr,rephrase=old_?=new_?);`, + and all `?` will be replaced, under the hood, by calls to the macroarray. + For easier debugging the `do_over` macro prints the rephrased string + before and after change. + When the `do_over` loops with multiple array, say `myArrA`, `myArrB`, + and `myArrC`, then those arrays should be referred by `?1?`, `?2?`, + and `?3?` respectively. + See `trigger` parameter definition to learn more. + If both `phrase` and `rephrase` are used, the second takes precedence. + +* `trigger=` - *Optional*, a single byte character (symbol) used for marking + macroarrays in the newly created phrase. + Default value is `?` symbol. + When one macroarray is used, only the symbol should be used in + `rephrase=` string. When multiple macroarrays are used then the + symbol should surround a number identifying array, e.g. `?2?`. + See examples below for details. + +* `unq=` - *Optional*, indicates that the `%unquote()` macro function should + be added around every macroarray call. Because of SAS internal + behavior `unq=1` is needed for certain cases when plain 4GL code + is used in `rephrase=`. For example, let macro array `myArr()` + has 3 values: `A1`, `B2`, and `C3`. When the following code + is run: `%do_over(myArr, rephrase=data ?_test; run;)` without + `unq=1`, SAS will create 4 data sets: `A1`, `B2`, `C3`, + and `_test`, instead 3 data sets: `A1_test`, `B2_test`, and `C3_test`. + Default value `1` means: add the `%unquote()`. + See example below to learn more. + + +### 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 + , 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(,))#; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 8.** Simpler multiple arrays looping with `rephrase=`. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(alpha[*] j k l m n o p, vnames=Y, macarray=Y) + %array( beta[&alphaN.], function = (2**_i_), macarray=Y) + %array(gamma[&alphaN.] (1:&alphaN.), macarray=Y) + + %put >>%do_over(alpha)<<; + %put >>%do_over(beta)<<; + %put >>%do_over(gamma)<<; + + data test8; + call streaminit(123); + + %do_over( alpha beta gamma + , rephrase = ?1? = ?2? + ?3? * rand('Uniform'); output; + , between = put _all_; + ) + put _all_; + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 9.** Simpler multiple arrays looping with `rephrase=`, cont. + Create multiple datasets. Array `alpha`, `beta`, and `gamma` are + from the previous example. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %do_over(alpha beta gamma + , rephrase = + data ?1?_2; + call streaminit(?2?); + ?1?X = ?2? + ?3? * rand('Uniform'); + output; + run; + ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 10.** Simpler multiple arrays looping with `rephrase=`, cont. + Create multiple datasets using a macro. Array `alpha`, `beta`, + and `gamma` are from the previous example. + The `%nrstr()` is required to mask call to the `%doit2()` macro. + Default `?` is replaced with `@`. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %macro doit2(ds, var=a, val1=1, val2=2); + data &ds._3; + call streaminit(&val1.); + &var. = &val1. + &val2. * rand('Uniform'); + output; + run; + %mend doit2; + + %do_over( alpha beta gamma + , rephrase = %nrstr(%doit2(@1@, var = @1@, val1 = @2@, val2 = @3@)) + , trigger = @ + ) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +**EXAMPLE 11.** Simpler multiple arrays looping with `rephrase=`, cont. + Why the `unq=` is needed. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(myArr[3] $ ("A1" "B2" "C3"), macarray=Y) + + %do_over(myArr, rephrase=data ?_testUNQ1; run;, unq=1) + + %do_over(myArr, rephrase=data ?_testUNQ0; run;, unq=0) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + +**EXAMPLE 12.** Simpler multiple arrays looping with `rephrase=`, cont. + Renaming variables is easy now. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %array(V[*] a b c d e f g h, vnames=1, macarray=1) + + data test12; + array x{*} %do_over(V) (1:&VN.); + run; + + proc datasets nolist noprint lib=work; + modify test12; + rename + %do_over(V,rephrase = $=new_$,trigger=$) + ; + run; + quit; + + data _null_; + set test12; + put _ALL_; + run; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + +--- + +--- + +## `%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_.)) + ) + ); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +--- + +--- + +## `%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(ABCDEFGHIJKLMN) %* bad; +%mcDictionary(ABCDEFGHIJKLM) %* 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; + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + +--- + +--- + +## `%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(ABCDEFGHIJK) %* bad; +%mcHashTable(ABCDEFGHIJ) %* good; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**EXAMPLE 7.** Hashing algorithms. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas +%mcHashTable(H1,DCL,HASH=MD5) +%mcHashTable(H2,DECLARE,HASH=CRC32) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- + +--- + +## `%qziparrays()` macro ###### + +The zipArrays() and QzipArrays() macros +allow to use a function on elements of pair of +macro arrays. + +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. + +--- + +--- + +## `%sortmacroarray()` macro ###### + +The sortMacroArray() macro +allow to sort elements of a macro array. + +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); + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- + + +--- + +## `%ziparrays()` macro ###### + +The zipArrays() and QzipArrays() macros +allow to use a function on elements of pair of +macro arrays. + +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); +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +--- + +--- + + +--- + +# License ###### + +Copyright (c) Bartosz Jablonski, 2019 - 2026 + +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/macroarray_1.3.1_.zip b/hist/macroarray_1.3.1_.zip new file mode 100644 index 0000000000000000000000000000000000000000..2bdaf63744fa7f38003c19e9438ccbebef7e9c0f GIT binary patch literal 56752 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 delta 9325 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