Merge pull request #45 from yabwon/main

The BasePlus package [ver. 1.15]
This commit is contained in:
Bart Jablonski
2022-05-08 19:18:26 +02:00
committed by GitHub
5 changed files with 358 additions and 56 deletions

View File

@@ -93,7 +93,7 @@ This is a list of locations where the SAS Packages Framework is used:
If you want to share that you are using the SPF let me know and I'll update the list. If you want to share that you are using the SPF let me know and I'll update the list.
If you find the SPF usefull **share info** about it or **give it a [star](https://github.com/yabwon/SAS_PACKAGES/stargazers)** so more people will know. If you find the SPF useful **share info** about it or **give it a [star](https://github.com/yabwon/SAS_PACKAGES/stargazers)** so more people will know.
--- ---
@@ -146,7 +146,7 @@ SHA256 digest for macroArray: DF63B0E027827A82038F1C8422787A0BC569BA93104BA1778D
[Documentation for macroArray](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/macroarray.md "Documentation for macroArray") [Documentation for macroArray](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/macroarray.md "Documentation for macroArray")
- **BasePlus**\[1.14\] adds a bunch of functionalities I am missing in BASE SAS, such as: - **BasePlus**\[1.15\] adds a bunch of functionalities I am missing in BASE SAS, such as:
```sas ```sas
call arrMissToRight(myArray); call arrMissToRight(myArray);
call arrFillMiss(17, myArray); call arrFillMiss(17, myArray);
@@ -164,7 +164,7 @@ format x bool.;
%zipLibrary(sashelp,libOut=work) %zipLibrary(sashelp,libOut=work)
``` ```
SHA256 digest for BasePlus: 12A9A2155D9C6F969DF0A66E3A18D0938B8194FA3AA9D70EDDE1CB71DEF9691E SHA256 digest for BasePlus: 0331C673052D5221DA98C5CC93295634D8A0BC62C7D2FEF9D0D85B0B2DEDE4E9
[Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus") [Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus")

View File

@@ -90,7 +90,7 @@ SHA256 digest for macroArray: DF63B0E027827A82038F1C8422787A0BC569BA93104BA1778D
--- ---
- **BasePlus**\[1.14\] adds a bunch of functionalities I am missing in BASE SAS, such as: - **BasePlus**\[1.15\] adds a bunch of functionalities I am missing in BASE SAS, such as:
```sas ```sas
call arrMissToRight(myArray); call arrMissToRight(myArray);
call arrFillMiss(17, myArray); call arrFillMiss(17, myArray);
@@ -108,7 +108,7 @@ format x bool.;
%zipLibrary(sashelp,libOut=work) %zipLibrary(sashelp,libOut=work)
``` ```
SHA256 digest for BasePlus: 12A9A2155D9C6F969DF0A66E3A18D0938B8194FA3AA9D70EDDE1CB71DEF9691E SHA256 digest for BasePlus: 0331C673052D5221DA98C5CC93295634D8A0BC62C7D2FEF9D0D85B0B2DEDE4E9
[Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus") [Documentation for BasePlus](https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md "Documentation for BasePlus")

View File

@@ -1,3 +1,6 @@
/* 20220508 */
BasePlus: 0331C673052D5221DA98C5CC93295634D8A0BC62C7D2FEF9D0D85B0B2DEDE4E9
/* 20220420 */ /* 20220420 */
BasePlus: 12A9A2155D9C6F969DF0A66E3A18D0938B8194FA3AA9D70EDDE1CB71DEF9691E BasePlus: 12A9A2155D9C6F969DF0A66E3A18D0938B8194FA3AA9D70EDDE1CB71DEF9691E
DFA: 6B3FB0B06B47A7EF1BB004B483B0F39B8F553F7F16D02A7E24CDE388BBA704EA DFA: 6B3FB0B06B47A7EF1BB004B483B0F39B8F553F7F16D02A7E24CDE388BBA704EA

View File

@@ -45,12 +45,17 @@
* [`%RainCloudPlot()` macro](#raincloudplot-macro) * [`%RainCloudPlot()` macro](#raincloudplot-macro)
* [`%zipLibrary()` macro](#ziplibrary-macro) * [`%zipLibrary()` macro](#ziplibrary-macro)
* [`%unzipLibrary()` macro](#unziplibrary-macro) * [`%unzipLibrary()` macro](#unziplibrary-macro)
* [`%LDSN()` macro](#ldsn-macro)
* [`%LVarNm()` macro](#lvarnm-macro)
* [`%LVarNmLab()` macro](#lvarnmlab-macro)
* [License](#license) * [License](#license)
--- ---
# The BasePlus package [ver. 1.14] <a name="baseplus-package"></a> ############################################### # The BasePlus package [ver. 1.15] <a name="baseplus-package"></a> ###############################################
The **BasePlus** package implements useful The **BasePlus** package implements useful
functions and functionalities I miss in the BASE SAS. functions and functionalities I miss in the BASE SAS.
@@ -67,7 +72,9 @@ Kudos to all who inspired me to generate this package:
*Richard DeVenezia*, *Richard DeVenezia*,
*Christian Graffeuille*, *Christian Graffeuille*,
*Allan Bowe*, *Allan Bowe*,
*Anamaria Calai*. *Anamaria Calai*,
*Michal Ludwicki*,
*Quentin McMullen*.
--- ---
@@ -187,7 +194,6 @@ Kudos to all who inspired me to generate this package:
%rainCloudPlot(sashelp.cars,DriveTrain,Invoice) %rainCloudPlot(sashelp.cars,DriveTrain,Invoice)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
![Rain Cloud Plot](./baseplus_RainCloudPlot_Ex0_9.png)
**Example 10**: Zip SAS library. **Example 10**: Zip SAS library.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
@@ -196,8 +202,20 @@ Kudos to all who inspired me to generate this package:
%unzipLibrary(%sysfunc(pathname(work)), zip=sashelp, mode=S, clean=1) %unzipLibrary(%sysfunc(pathname(work)), zip=sashelp, mode=S, clean=1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Example 11**: Long dataset names.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data %LDSN( work. peanut butter & jelly time with a "Hot-Dog" in [a box], popcorn, and s*t*a*r*s (drop = sex rename=(name=first_name) where = (age in (12,13,14))) );
set sashelp.class;
run;
proc print data = %LDSN( work. peanut butter & jelly with a "Hot-Dog" in [a box], popcorn, and s*t*a*r*s );
run;
data MyNextDataset;
set %LDSN( work. peanut butter & jelly with a "Hot-Dog" in [a box], popcorn, and s*t*a*r*s );
where age > 12;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--- ---
@@ -208,52 +226,53 @@ Package contains:
4. macro deduplistx 4. macro deduplistx
5. macro functionexists 5. macro functionexists
6. macro getvars 6. macro getvars
7. macro qdeduplistx 7. macro ldsn
8. macro qgetvars 8. macro lvarnm
9. macro qzipevalf 9. macro lvarnmlab
10. macro raincloudplot 10. macro qdeduplistx
11. macro symdelglobal 11. macro qgetvars
12. macro unziplibrary 12. macro qzipevalf
13. macro zipevalf 13. macro raincloudplot
14. macro ziplibrary 14. macro symdelglobal
15. format bool 15. macro unziplibrary
16. format boolz 16. macro zipevalf
17. format ceil 17. macro ziplibrary
18. format floor 18. format bool
19. format int 19. format boolz
20. function arrfill 20. format ceil
21. function arrfillc 21. format floor
22. function arrmissfill 22. format int
23. function arrmissfillc 23. functions arrfill
24. function arrmisstoleft 24. functions arrfillc
25. function arrmisstoleftc 25. functions arrmissfill
26. function arrmisstoright 26. functions arrmissfillc
27. function arrmisstorightc 27. functions arrmisstoleft
28. function bracketsc 28. functions arrmisstoleftc
29. function bracketsn 29. functions arrmisstoright
30. function catxfc 30. functions arrmisstorightc
31. function catxfi 31. functions bracketsc
32. function catxfj 32. functions bracketsn
33. function catxfn 33. functions catxfc
34. function deldataset 34. functions catxfi
35. function semicolonc 35. functions catxfj
36. function semicolonn 36. functions catxfn
37. format brackets 37. functions deldataset
38. format semicolon 38. functions semicolonc
39. proto qsortincbyprocproto 39. functions semicolonn
40. function frommissingtonumberbs 40. format brackets
41. function fromnumbertomissing 41. format semicolon
42. function quicksort4notmiss 42. proto qsortincbyprocproto
43. function quicksorthash 43. functions frommissingtonumberbs
44. function quicksorthashsddv 44. functions fromnumbertomissing
45. function quicksortlight 45. functions quicksort4notmiss
46. functions quicksorthash
47. functions quicksorthashsddv
48. functions quicksortlight
*SAS package generated by generatePackage, version 20220420* *SAS package generated by generatePackage, version 20220420*
The SHA256 hash digest for package BasePlus: The SHA256 hash digest for package BasePlus:
`12A9A2155D9C6F969DF0A66E3A18D0938B8194FA3AA9D70EDDE1CB71DEF9691E` `0331C673052D5221DA98C5CC93295634D8A0BC62C7D2FEF9D0D85B0B2DEDE4E9`
--- ---
# Content description ############################################################################################ # Content description ############################################################################################
@@ -3497,6 +3516,286 @@ run;
--- ---
## >>> `%LDSN()` macro: <<< <a name="ldsn-macro"></a> #######################
The LDSN (Long DataSet Names) macro function
allows to use an "arbitrary" text string to name a dataset.
---
The idea for the macro came from the following story:
Good friend of mine, who didn't use SAS for quite some time,
told me that he lost a few hours for debugging because
he forgot that the SAS dataset name limitation is 32 bytes.
I replied that it shouldn't be a problem to do a workaround
for this inconvenience with a macro and the `MD5()` hashing function.
I said: *The macro should take an "arbitrary string" for a dataset
name, convert it, with help of `MD5()`, to a hash digest, and
create a dataset with an "artificial" `hex16.` formated name.*
Starting with something like this:
~~~~~~~~~~~~~~~~~~~~~~~sas
data %LDSN(work. peanut butter & jelly with a hot-dog in [a box] and s*t*a*r*s (drop = sex rename=(name=first_name) where = (age in (12,13,14))) );
set sashelp.class;
run;
~~~~~~~~~~~~~~~~~~~~~~~
the macro would do:
~~~~~~~~~~~~~~~~~~~~~~~sas
%sysfunc(MD5(peanut butter & jelly with a hot-dog in [a box] and s*t*a*r*s), hex16.)
~~~~~~~~~~~~~~~~~~~~~~~
and (under the hood) return and execute the following code:
~~~~~~~~~~~~~~~~~~~~~~~sas
data work.DSN_41D599EF51FBA58_(drop = sex rename=(name=first_name) where = (age in (12,13,14))) ;
set sashelp.class;
run;
~~~~~~~~~~~~~~~~~~~~~~~
Also in the next data step user should be able to do:
~~~~~~~~~~~~~~~~~~~~~~~sas
data my_next_data_step;
set %DSN(work. peanut butter & jelly with a hot-dog in [a box] and s*t*a*r*s);
run;
~~~~~~~~~~~~~~~~~~~~~~~
and work without the "dataset-name-length-limitation" issue.
---
See examples below for the details.
The `%LDSN()` macro executes like a pure macro code.
**Known "Limitations":**
- dataset name _cannot_ contain dots (`.`) since they are used as separators!
- dataset name _cannot_ contain round brackets(`(` and `)`) since they are used as separators
(but `[]` and `{}` are allowed)!
- dataset name _cannot_ contain unpaired quotes (`'` and `"`),
text: `a "hot-dog"` is ok, but `John's dog` is not!
**Behaviour:**
- dataset name text is *converted to upcase*
- dataset name text *leading and trailing spaces are ignored*,
e.g. the following will give the same hash digest:
`%ldsn(work.test)`, `%ldsn( work.test)`, `%ldsn(work.test )`,
`%ldsn(work .test)`, `%ldsn(work. test)`, `%ldsn(work . test)`.
- if the user want to add an extra suffix to the dataset the `%ldsn()` macro
**has** to be wrapped inside the `%unquote()` macro function.
~~~~~~~~~~~~~~~~~~~~~~~sas
data
%unquote(%LDSN(WORK.some strange! DS name))_1
%unquote(%LDSN(WORK.some strange! DS name))_2
;
set sashelp.class;
if SEX="M" then output %unquote(%LDSN(WORK.some strange! DS name))_1;
else output %unquote(%LDSN(WORK.some strange! DS name))_2;
run;
~~~~~~~~~~~~~~~~~~~~~~~
The reason for this is a "bug" like behaviour of SAS tokenizer/macroprocesor.
See the following SAS-L discussion thread:
`https://listserv.uga.edu/scripts/wa-UGA.exe?A2=SAS-L;4b2bcf80.2205A&S=`
- macro calls of the form:
`data %LDSN(); run;`, `data %LDSN( ); run;`, `data %LDSN( . ); run;` or even
`data %LDSN( . (keep=x)); run;` are resolved to empty string, so the result is
equivalent to `data; run;`
### SYNTAX: ###################################################################
The basic syntax is the following, the `<...>` means optional parameters:
~~~~~~~~~~~~~~~~~~~~~~~sas
%LDSN(
arbitrary text string (in line with limitations)
)
~~~~~~~~~~~~~~~~~~~~~~~
### EXAMPLES AND USECASES: ####################################################
**EXAMPLE 1.**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
options nomprint source nomlogic nosymbolgen ls = max ps = max;
data %LDSN( work. peanut butter & jelly with a "Hot-Dog" in [a box], popcorn, and s*t*a*r*s (drop = sex rename=(name=first_name) where = (age in (12,13,14))) );
set sashelp.class;
run;
proc print data = %LDSN( work. peanut butter & jelly with a "Hot-Dog" in [a box], popcorn, and s*t*a*r*s );
run;
data MyNextDataset;
set %LDSN( work. peanut butter & jelly with a "Hot-Dog" in [a box], popcorn, and s*t*a*r*s );
where age > 12;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---
## >>> `%LVarNm()` macro: <<< <a name="lvarnm-macro"></a> #######################
The LVarNm() macro function works like the LDSN() macro function, but for variables.
Supported by LVarNmLab() macro function which allows to remember "user names" in labels.
The motivation for the macro was similar one as for the LDSN() macro.
---
See examples below for the details.
The `%LVarNm()` macro executes like a pure macro code.
**Known "Limitations":**
- variable name _cannot_ contain unpaired quotes (`'` and `"`),
text: `a "hot-dog"` is ok, but `John's dog` is not!
**Behaviour:**
- variable name text is *converted to upcase*
- variable name text *leading and trailing spaces are ignored*,
e.g. the following will give the same hash digest:
`%LVarNm(test)`, `%LVarNm( test)`, `%LVarNm(test )`.
- if the user want to add an extra suffix to the variable,
e.g. to get a numerical suffix, the `%LVarNm()` macro
**has** to be wrapped inside the `%unquote()` macro function.
~~~~~~~~~~~~~~~~~~~~~~~sas
data test4;
array X[*] %unquote(%LVarNm(some strange! name))_0 - %unquote(%LVarNm(some strange! name))_10;
do i = lbound(X) to hbound(X);
X[i] = 2**(i-1);
put X[i]=;
end;
run;
~~~~~~~~~~~~~~~~~~~~~~~
The reason for this is a "bug" like behaviour of SAS tokenizer/macroprocesor.
See the following SAS-L discussion thread:
`https://listserv.uga.edu/scripts/wa-UGA.exe?A2=SAS-L;4b2bcf80.2205A&S=`
### SYNTAX: ###################################################################
The basic syntax is the following, the `<...>` means optional parameters:
~~~~~~~~~~~~~~~~~~~~~~~sas
%LVarNm(
arbitrary text string (in line with limitations)
)
~~~~~~~~~~~~~~~~~~~~~~~
---
### EXAMPLES AND USECASES: ####################################################
**EXAMPLE 1.**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
options ls=max;
data test;
%LVarNmLab( peanut butter & jelly with a "Hot-Dog" in [a box], popcorn, and s*t*a*r*s )
do %LVarNm( peanut butter & jelly with a "Hot-Dog" in [a box], popcorn, and s*t*a*r*s ) = 1 to 10;
y = 5 + %LVarNm( peanut butter & jelly with a "Hot-Dog" in [a box], popcorn, and s*t*a*r*s ) * 17;
output;
end;
run;
data test2;
set test;
where %LVarNm( peanut butter & jelly with a "Hot-Dog" in [a box], popcorn, and s*t*a*r*s ) < 5;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 2.**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data test3;
%LVarNmLab() = 17;
%LVarNm() = 17;
%LVarNm( ) = 42;
%LVarNm( ) = 303;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 3.**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data test3;
%LVarNm(test) = 1;
%LVarNm( test) = 2;
%LVarNm(test ) = 3;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**EXAMPLE 4.**
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data test4;
array X[*] %unquote(%LVarNm(some strange! name))_0 - %unquote(%LVarNm(some strange! name))_10;
do i = lbound(X) to hbound(X);
X[i] = 2**(i-1);
put X[i]=;
end;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## >>> `%LVarNmLab()` macro: <<< <a name="lvarnmlab-macro"></a> #######################
The LVarNmLab() macro function supports LVarNm() and allows to remember "user names" in labels.
The motivation for the macro was similar one as for the LDSN() macro.
---
See examples in LVarNm() documentation for the details.
The `%LVarNmLab()` macro executes like a pure macro code.
**Known "Limitations":**
- variable name _cannot_ contain unpaired quotes (`'` and `"`),
text: `a "hot-dog"` is ok, but `John's dog` is not!
**Behaviour:**
- variable name text is *converted to upcase*
- variable name text *leading and trailing spaces are ignored*,
e.g. the following will give the same hash digest:
`%LVarNmLab(test)`, `%LVarNmLab( test)`, `%LVarNmLab(test )`.
### SYNTAX: ###################################################################
The basic syntax is the following, the `<...>` means optional parameters:
~~~~~~~~~~~~~~~~~~~~~~~sas
%LVarNmLab(
arbitrary text string (in line with limitations)
)
~~~~~~~~~~~~~~~~~~~~~~~
---
## License #################################################################### ## License ####################################################################
Copyright (c) 2020 Bartosz Jablonski Copyright (c) 2020 Bartosz Jablonski

Binary file not shown.