proc sort data=sashelp.class out=class;
by age;
run;
data _null_ ;
declare hash h (multidata:"Y",
ordered: "a",
dataset:"class(obs=0)") ;
h.definekey('name') ;
h.definedata(all:'Y');
h.definedone() ;
do i = 1 by 1 until (last.age);
set class;
by age;
h.add();
end ;
h.output(dataset: cats("age_", age));
run;
Tuesday, June 7, 2022
Hash way to split SAS Table
In traditional SAS way, it will leverage SAS macro to split the SAS dataset. If you are bored with that, you may like the hash way below. Enjoy!
Monday, June 6, 2022
Summary aggregate using Hash
Below are the key statements to understand hash "Maintaining Key Summaries". It is powerful technique when you understand how it works. However, avoid using SUMINC with MULTIDATA/DO_OVER as they are affecting the sum value and I can not find any explanation in SAS doc.
quote:
The summary value of a hash key is initialized to the value of the SUMINC variable whenever the ADD or REPLACE method is used.
The summary value of a hash key is incremented by the value of the SUMINC variable whenever the FIND, CHECK, or REF method is used.
Note that the SUMINC variable can be negative, positive, or zero valued. The variable does not need to be an integer.The SUMINC value for a key is zero by default.
unquote:
quote:
The summary value of a hash key is initialized to the value of the SUMINC variable whenever the ADD or REPLACE method is used.
The summary value of a hash key is incremented by the value of the SUMINC variable whenever the FIND, CHECK, or REF method is used.
Note that the SUMINC variable can be negative, positive, or zero valued. The variable does not need to be an integer.The SUMINC value for a key is zero by default.
unquote:
data sample;
do key = 1,2,3;
value = key*2;
output; output;
end;
run;
data _null_ ;
if _n_ = 1 then do ;
declare hash h (suminc:"value", dataset:"sample") ;
h.defineKey("key") ;
h.defineDone();
do until (eof) ;
set sample end=eof ;
h.check();
end;
end ;
file print ;
set sample;
by key;
if first.key then do ;
h.sum(sum:Total);
put key @10 Total;
end;
run;
Friday, November 29, 2019
How to loop character A-Z in SAS?
To loop characters A-Z elegantly, we can have two ways as follows:
data _null_;
put "First method:";
string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; * string from A to Z;
do i=1 to length(string);
char = substrn(string, i, 1);
put char=;
end;
put "Second method (using RANK and BYTE):";
do i=rank('A') to rank('Z');
char = byte(i);
put char=;
end;
run;
If you can find any way better, please let me know.
Tuesday, March 26, 2019
How to find hidden macro in batch run
By default, it does not give out any information for macro compilation when the macro definition are %include. It is OK for most time. However, it may be helpful when you want to locate the macro when multiple versions exist. With system option MCOMPILENOTE, we can easily address this problem.
Similarly, we can use MEXECNOTE to get more details on macro execution.
Programmatically, we can add version information in macro description. See blow:
Similarly, we can use MEXECNOTE to get more details on macro execution.
Programmatically, we can add version information in macro description. See blow:
%macro test / des = 'Version 1.0'; %mend; proc catalog; contents cat=work.sasmacr; /* list macro description */ quit;
Tuesday, June 12, 2018
Identify trailing string using $revers.
In SAS, it is easy to identify leading string using ":" operator modifier, e.g. "a =: b". However, there was no easy way to identify trailing ones. Traditionally we could use combination of substr/reverse/length/strip functions. Personally I prefer format $revers as it combines the functionality of substr and left-align. Note that the width should be the length of the character variable.
data _null_;
a = 'abc efg ';
if put(a, $revers10.) =: 'gfe' then put "a has trailing string efg";
run;
/*
Output:
a has trailing string efg
*/
Result:
Friday, March 23, 2018
LUA - it is safe to drive SAS
PROC LUA can create safe environment to drive SAS because you don't worry about changing any existing library, fileref, macros and global options outside LUA session. Furthermore, you can also setup new library, fileref, macros and global options in LUA session. It will maintain all of them inside LUA session until it terminates or restarts.
Below are the sample code to demonstrate the concepts:
Below are the sample code to demonstrate the concepts:
filename test temp;
libname test "c:\";
%macro test;
%put outside;
%mend;
proc lua restart;
submit;
sas.submit [[
/* It will fail to delete existing fileref or library */
filename test clear;
libname test clear;
]]
endsubmit;
run;
proc lua restart;
submit;
sas.submit [[
filename test temp;
libname test "c:\temp";
options obs=0;
%macro test;
%put inside;
%mend;
filename test list;
libname test list;
proc options option=obs; run;
%test
]]
endsubmit;
run;
filename test list;
libname test list;
proc options option=obs; run;
%test
Tuesday, March 13, 2018
How to call LUA file?
As we know, LUA is great fit to SAS. Here are some tips on how to integrate LUA file into SAS.
For example, the LUA file is at c:\lua\test.lua
For example, the LUA file is at c:\lua\test.lua
/* #1. using INFILE option of PROC LUA */
FILENAME LUAPATH "c:\lua";
PROC LUA INFILE="test"; RUN;
/* #2. leverage current folder */
X "CD c:\lua";
PROC LUA;
SUBMIT;
dofile("test.lua")
ENDSUBMIT;
RUN;
/* #3. using absolute path */
PROC LUA;
SUBMIT;
dofile(c:\\lua\\test.lua) -- escape backslash character
dofile [[c:\lua\test.lua]] -- or using [[ and ]]
ENDSUBMIT;
RUN;
/* #4. %INCLUDE statement supports both SAS and LUA starting from 9.4 */
%INCLUDE "c:\lua\test.lua";
/* $5. passed by SUBMIT option */
%let luaname=c:\lua\test.lua;
PROC LUA;
SUBMIT "name=[[&luaname]]";
print(name)
dofile(name)
ENDSUBMIT;
RUN;
Subscribe to:
Posts (Atom)