Thursday, November 19, 2015

SAS Notepad++ Language Pack


<UserLang name="SAS3" ext="sas SAS">
<Settings>
<Global caseIgnored="yes"/>
<TreatAsSymbol comment="yes" commentLine="no"/>
<Prefix words1="no" words2="no" words3="yes" words4="yes"/>
</Settings>
<KeywordLists>
<Keywords name="Delimiters">"'0"'0</Keywords>
<Keywords name="Folder+">proc data</Keywords>
<Keywords name="Folder-">run RUN</Keywords>
<Keywords name="Operators">' - ! " & ( ) , . : ; ? @ [ \ ] ^ ` { | } ~ + < ></Keywords>
<Keywords name="Comment">1/* 2*/ 0</Keywords>
<Keywords name="Words1">
append bmdp calendar catalog chart cimport compare contents convert copy corr cport datasets format forms freq glm gplot logistic means npar1way options pds plot pmenu print printto rank release sort source spell sql standard summary tabulate tapecopy tapelabel timeplot transpose ttest univariate v5tov6
</Keywords>
<Keywords name="Words2">
$include _all_ _character_ _cmd_ _error_ _freq_ _i_ _infile_ _last_ _msg_ _n_ _null_ _numeric_ _temporary_ _type_ abort addr adjrsq alpha alter altlog altprint array attrib authserver autoexec awscontrol awsdef awsmenu awsmenumerge awstitle backward base blocksize bufno bufsize by byerr byline call cards cards4 catcache cbufno center change chisq class cleanup cntllev codegen col collin column comamid comaux1 comaux2 comdef config continue cpuid create datalines datalines4 dbcslang dbcstype ddm delete delimiter descending device dflang display distinct dkricond dkrocond dlm do drop dsnferr echo else emaildlg emailid emailpw emailserver emailsys encrypt end endsas engine eof eov error errorcheck errors feedback file fileclose filefmt filevar first first. firstobs fmterr fmtsearch font fontalias footnote footnote1 footnote2 footnote3 footnote4 footnote5 footnote6 footnote7 footnote8 footnote9 force formatted formchar formdelim formdlim forward from go goto group gwindow hbar helpenv helploc honorappearance hostprint hpct html hvar ibr id if infile informat initcmd initstmt inr into invaliddata is join keep kentb label last last. leave lib library line linesize link list lostcard lrecl ls macro macrogen maps mautosource maxdec maxr measures median memtype merge merror missing missover mlogic mode model modify mprint mrecall msglevel msymtabmax mvarsize myy new news no nobatch nobs nocol nocaps nocardimage nocenter nocharcode nocmdmac nocum nodate nodbcs nodetails nodmr nodms nodmsbatch nodup nodupkey noduplicates noechoauto noequals noerrorabend noexitwindows nofullstimer noicon noimplmac noint nolist noloadlist nomiss nomlogic nomprint nomrecall nomsgcase nomstored nomultenvappl nonotes nonumber noobs noovp nopad noprint noprintinit norow norsasuser nosetinit nosource2 nosplash nosymbolgen notes notitle notitles notsorted noverbose noxsync noxwait number numkeys nummousekeys nway obs ods option order otherwise out outp= output over ovp pad pad2 page pageno pagesize paired parm parmcards path pathdll pfkey position printer probsig procleave prt ps pw pwreq quit r ranks read recfm reg register regr remote remove rename replace retain return reuse rsquare rtf rtrace rtraceloc s s2 samploc sasautos sascontrol sasfrscr sashelp sasmsg sasmstore sasscript sasuser select selection separated seq serror set setcomm simple siteinfo skip sle sls sortedby sortpgm sortseq sortsize source2 splashlocation split spool start stdin stimer stop stopover sumwgt symbol symbolgen sysin sysleave sysparm sysprint sysprintfont t table tables tapeclose tbufsize terminal test then title title1 title2 title3 title4 title5 title6 title7 title8 title9 to tol tooldef trantab truncover type unformatted union until update user usericon validate value var varray varrayx vformat vformatd vformatdx vformatn vformatnx vformatw vformatwx vformatx vinarray vinarrayx vinformat vinformatd vinformatdx vinformatn vinformatnx vinformatw vinformatwx vinformatx vlabel vlabelx vlength vlengthx vname vnamex vnferr vtype vtypex weight when where while wincharset window work workinit workterm write x xsync xwait yearcutoff yes abs airy arcos arsin atan attrc attrn band betainv blshift bnot bor brshift bxor byte cdf ceil cexist cinv close cnonct collate compbl compound compress cos cosh css curobs cv daccdb daccdbsl daccsl daccsyd dacctab dairy date datejul datepart datetime day dclose depdb depdbsl depsl depsyd deptab dequote dhms dif digamma dim dinfo dnum dopen doptname doptnum dread dropnote dsname erf erfc exist exp fappend fclose fcol fdelete fetch fetchobs fexist fget fileexist filename fileref finfo finv fipname fipnamel fipstate floor fnonct fnote fopen foptname foptnum fpoint fpos fput fread frewind frlen fsep fuzz fwrite gaminv gamma getoption getvarc getvarn hbound hms hosthelp hour ibessel index indexc indexw input inputc inputn int intck intnx intrr irr jbessel juldate kurtosis lag lbound left length lgamma libname libref log log10 log2 logpdf logpmf logsdf lowcase max mdy mean min minute mod month mopen mort n netpv nmiss normal note npv open ordinal pathname pdf peek peekc pmf point poisson poke probbeta probbnml probchi probf probgam probhypr probit probnegb probnorm probt put putc putn qtr quote ranbin rancau ranexp rangam range rannor ranpoi rantbl rantri ranuni repeat resolve reverse rewind right round saving scan sdf second sign sin sinh skewness soundex spedis sqrt std stderr stfips stname stnamel substr sum symget symput sysget sysmsg sysprod sysrc system tan tanh time timepart tinv tnonct today translate tranwrd trigamma trim trimn trunc uniform upcase uss varfmt varinfmt varlabel varlen varname varnum vartype verify weekday year yyq zipfips zipname zipnamel zipstate crosstab descript design= levels nest setot subgroup subpopn totper wsum
</Keywords>
<Keywords name="Words3">
%bquote %do %else %end %eval %global %goto %if %inc %include %index %input %length %let %list %local %macro %mend %nrbquote %nrquote %nrstr %put %qscan %qsysfunc %quote %run %substr %syscall %sysevalf %sysexec %sysfunc %sysrc %then %to %until %while %window $1 $2 $3 $4 $5 $6 $7 $8 $9 $ascii $binary $cb $char $charzb $ebcdic $hex $kanji $kanjix $msgcase $octal $phex $quote $reverj $revers $upcase $varying best binary bits bz cb char comma commax dateampm ddmmyy dollar dollarx downame eurdfdd eurdfde eurdfdn eurdfdt eurdfdwn eurdfmn eurdfmy eurdfwdx eurdfwkx float fract hex hhmm ib ieee julday julian minguo mmddyy mmss mmyy monname monyy msec negparen nengo numx octal pd pdjulg pdjuli pdtime percent pib pk punch pvalue qtrr rb rmfdur rmfstamp roman row s370ff s370fib s370fibu s370fpd s370fpdu s370fpib s370frb s370fzd s370fzdl s370fzds s370fzdt s370fzdu smfstamp timeampm tod tu vaxrb weekdate weekdatx worddate worddatx wordf words yen yymm yymmdd yymon yyqr z zd zdb zdv
</Keywords>
<Keywords name="Words4">data=</Keywords>
</KeywordLists>
<Styles>
<WordsStyle name="DEFAULT" styleID="11" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0"/>
<WordsStyle name="FOLDEROPEN" styleID="12" fgColor="000080" bgColor="FFFFFF" fontName="" fontStyle="1"/>
<WordsStyle name="FOLDERCLOSE" styleID="13" fgColor="000080" bgColor="FFFFFF" fontName="" fontStyle="1"/>
<WordsStyle name="KEYWORD1" styleID="5" fgColor="000080" bgColor="FFFFFF" fontName="" fontStyle="1"/>
<WordsStyle name="KEYWORD2" styleID="6" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0"/>
<WordsStyle name="KEYWORD3" styleID="7" fgColor="008080" bgColor="FFFFFF" fontName="" fontStyle="0"/>
<WordsStyle name="KEYWORD4" styleID="8" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0"/>
<WordsStyle name="COMMENT" styleID="1" fgColor="8000FF" bgColor="FFFFFF" fontName="Courier New" fontStyle="2" fontSize="10"/>
<WordsStyle name="COMMENT LINE" styleID="2" fgColor="008000" bgColor="FFFFFF" fontName="Courier New" fontStyle="2"/>
<WordsStyle name="NUMBER" styleID="4" fgColor="008080" bgColor="FFFFFF" fontName="" fontStyle="1"/>
<WordsStyle name="OPERATOR" styleID="10" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0"/>
<WordsStyle name="DELIMINER1" styleID="14" fgColor="800080" bgColor="FFFFFF" fontName="" fontStyle="0"/>
<WordsStyle name="DELIMINER2" styleID="15" fgColor="800080" bgColor="FFFFFF" fontName="" fontStyle="0"/>
<WordsStyle name="DELIMINER3" styleID="16" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0"/>
</Styles>
</UserLang>

Tuesday, November 17, 2015

Master of statistics pre-courses

MAT 137Y (Calculus)
MAT 235Y/237Y (Multivariable Calculus)
MAT 223H/240H (Linear Algebra I)
MAT 224H/247H (Linear Algebra II)
MAT 337H (Introduction to Real Analysis)
STA 257H (Introductory Probability and Statistics I)
STA 261H (Introductory Probability and Statistics II)
STA 347H (Probability Theory)
STA 452H / 453H  ( Introduction to Mathematical Statistics I & II )
STA 302H (Applied Regression Analysis) [same as STA 1001H]
STA 322H (Sample Survey Theory and its Application) [same as STA 1003H]
STA 332H (Introduction to Experimental Design) [same as STA 1004H]

STA 437H (Applied Multivariate Analysis) [same as STA 2005H]


Methods of Applied Statistics I
Methods of Applied Statistics II
Graduate Probability I
Graduate Probability II
Mathematical Statistics I
Mathematical Statistics II
Advanced Theory of Statistics

project grow法

和人合作走小精尖专利之路创新,能够handle大公司的一个环节即可

要做到IT-DA的平稳切换,SQL/EXCEL, SQL BI, EXCEL BI 是桥梁

做一项事业: IT和软件上扩展一步,倒项目、项目管理、构建项目利益链,合包、承包劳务、分包、二包,做SubContractor

大事靠分析, 小事靠直觉 , Financial industry

善战者,立于不败之地而后战
在生意的轨道上拙进稳赚经营


和自己专业和自己工作结合,最容易成功, 从做好自己本职工作出发

在自己手脚可及的产业(技术,难题,问题)上做文章, 可以保住饭碗,升职,跳槽, 走向远方而非瞄着远方

行行出状元的道理: 不管做什么技术,只要做精了,都能有出息,选行要知天命,不要举棋不定耽误时间
要在自己能出状元的地方争当状元,当第一名。


勇往直前、 步步推进、层层破解;做出精密的计划,计划出高效(70-80%事情计划在内,在实践中寻优)

高效分解问题(直到可以handle难度或者可以解决子问题)Firm的解决问题

做事之前Strategy thinking, analysis/break down 然后做,三思后行;

大事靠分析小事靠直觉;必须有自己的黄金工作时间、且顺应加拿大特点;最重要的事情往前排;不断优化行动(宏观、微观)

收入较高的两种职位:金融投资分析人员 (Financial Analyst)和个人金融理财人员(Financial Advisor)


金融工程。在加拿大,这个专业的人不是太多,每个银行大约有一二十人是真正搞金融工程的,主要是搞Model的。服务对象是Risk ManagementTrading Room,大多是数学、物理、金融博士,也有一些是UTWaterlooYorkMath Finance硕士,数学能力一般都很强。


将自己的事业集成于本地产业集群中,获得区位优势;

和新技术结合-获得新增优势-3D打印、移动网络、大数据、机器人

避免和大企业竞争,要和大企业合作配套,加入大企业的产业链

避免“被外包”的行业:软件,视觉元器件生产

分析方法: 类似于视觉研究报告

打工到开公司策略的推理:待遇高,工作好找,工作环境好,稳定  开公司干事业: 利润高,稳定,工作强度低,业务容易开展,有潜力和前景

你进入任何圈子,只要你能找到对方需要的,而且你能找到解决他需要的方法,那么你都能获得机会、财富和幸福
一个人一生精力是有限的,是不可能什么都会的,因此你如果什么都学,那么你什么都学不会。你用30年研究透了一门技术,或者学会了一门艺术,人家用二十年读懂了销售,你不可能在人家的领域里超过人家,时间精力都不允许。最好的方法是合作。何况更多的人啥都不是,什么领域都是普通人。因此最重要的就是多交往那些优秀的人,进入优秀人的圈子。或者进入有价值人的圈子

生意的基本原理:寻找客户需求、产品力和客户数量的最大平衡值

曹操冠带辉煌,高唱:“世人害奸,我笑世人偏。为人少机变,富贵怎双全

能够在加拿大成功扎根、营运多年的华裔移民企业家,大多数人的成长过程都有惊人相似的轨迹:从底层开始,慢慢地熟悉所进入的行业、锻炼语言、明白顾客思维习惯、掌握市场营销模式、学习应对各种事物,知道加拿大政府的扶植政策,坚强不屈服



对中加两条腿走路的认识
1)机会:走入社会去变戏法、找机会
2)从赚钱角度看
要赚小钱:在CA认真工作足矣
要赚大钱:还是要把欧美先进的东西倒腾到欠发达国家


对赚钱的认识
1)抓项目就是抓经济建设:塑胶花生产、销售
2)好钢用在刀刃上,智慧用在赚钱上;直接操练赚钱的技术
3)挣钱要有好的工具和渠道
4)入对行、选好行

刘少奇;要做好工作,应该情况明,决心大,办法对
1)渠道建设:干活要有工具,挣钱要有工具、手段、渠道

发展选题: 加拿大-市场中某方面问题的专家或者专业化公司

职业的选择

- 总的来说,无非就是销售、市场、客服、物流、行政、人事、财务、技术、管理几个大类,有个有趣的现象就是,500强的CEO当中最多的是销售出身,第二多的人是财务出身
这两者加起来大概超过95%。现代IT行业也有技术出身成为老板的,但实际上,后来他们还是从事了很多销售和市场的工作,并且表现出色,公司才获得了成功,完全靠技术能力成为公司老板的,几乎没有。
- 这是有原因的,因为销售就是一门跟人打交道的学问,而管理其实也是跟人打交道的学问,这两者之中有很多相通的东西,他们的共同目标就是“让别人去做某件特定的事情。”而财务则是从数字的层面了解生意的本质,从宏观上看待生意的本质,对于一个生意是否挣钱,是否可以正常运作有着最深刻的认识


SAS, Financial modeling Excel Hot Skills - Part 1

Hot Skills:
   • Enterprise Guide – GUI point-and-click front-end application
   • Hash Programming Techniques – “Fast” table lookups, sorts, merges, and joins
   • Create RTF, PDF, HTML, XML, and Excel Spreadsheets with Output Delivery System (ODS)
   • Queries, Tables, Views, Case Expression Logic, inner and outer Joins – PROC SQL
   • Detail and Summary Reporting – PROC REPORT
   • Construct Reusable Code and Tools – Macro Language
   • Access SAS Environment – Dictionary Tables and SASHELP Views
   • Business Intelligence

SAS Model Developers 
  • SAS Modelling and development 
  • Able to create reusable objects and job templates Schedule, compile, and run SAS jobs efficiently
  • skills in database and data warehouse design principles - SQL Coding and querying skills
  • skills of UNIX
  • Data mapping experience Creates clear and concise documentation, produces source to target maps, understands and validates metrics
  • work well with cross border technical team members.
  • Must also be able to interface strongly with the business.
  • Risk, fraud, market campaign background knowledge
    Experience/people/networking
Advanced statistical analysis
regression modeling, conjoint analysis, audience segmentation, and cluster analysis; also must show experience with behavioral tracking data; multiple linear regression, hierarchical linear modeling, psychometrics (including item response theory)

Multivariate modeling experience such as linear and nonlinear regression models, limited dependent variable models, cluster analysis

Segmentation/classification methods, EM algorithm, hierarchical Bayesian models and MCMC simulation methods; Specific knowledge of latent class models, linear discriminant analysis, conjoint and discrete choice models and etc. in market research is a plus

ANOVA, Regression, Generalized Linear Models and Multivariate Methods

Different types of data mining tasks in relation to various business concerns, including classification, prediction, cluster analysis and segmentation, and association analysis and market basket analysis.  

Critically review and appreciate the strengths and weaknesses of the different data mining techniques, models, and tools. 

Apply appropriate data mining techniques for a given real-world problem. 

Evaluate various models built from a data mining process. 

Undertake a data mining project with clear business focus, in particular, in relation to CRM analysis, RFM modelling, and credit risk scoring

Financial modeling in excel, data mining excel sql Advanced Business Intelligence Solutions Using Microsoft Excel Excel Services

Thursday, November 12, 2015

Run Unix Command in SAS

http://www.pharmasug.org/proceedings/2011/AD/PharmaSUG-2011-AD06.pdf

http://www.ats.ucla.edu/stat/sas/code/exec_command.htm

Wednesday, November 4, 2015

tip1.AutocallMacro

/*
Ref: E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria
\SAS.DS2\SASUniversityEdition\myfolders\DesignPattern
\AUTOCALL MACRO LIBRARIES.pdf

Problem to be solved:
1. save macros in files, save to somewhere in disk
2. load the macros in Autocall Library

Method:
1. define macros, save filename = macro name, in lower case
2. use filename macroName 'fileLocation.sas'
3. add to autocall library:
OPTIONS MAUTOSOURCE SASAUTOS=(freqmeans sumdollar SASAUTOS);

*/
FILENAME freqmeans 'E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\Macro.OOP\Analysis\prjName\macro\freqmeans.sas';
FILENAME sumdollar 'E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\Macro.OOP\Analysis\prjName\macro\sumdollar.sas';
/*
%include 'E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\Macro.OOP\Analysis\prjName\macro\freqmeans.sas';
%include  'E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\Macro.OOP\Analysis\prjName\macro\sumdollar.sas';
*/
OPTIONS MAUTOSOURCE SASAUTOS=(freqmeans sumdollar SASAUTOS);

/*
in main program, or the caller program,
call the macros in Autocall library
*/
%sumDollar;
%freqMeans;

templatePattern4

%macro accessSAS(connectParameters,selectRecordParameters);

%macro connectDB(num,char);
%put SAS ConnectDB;
%mend connectDB;

%macro selectRecords(num,char);
%put SAS Record Selection;
%mend selectRecords;

%macro doQuery;
* doQuery is the same for all macros;
%connectDB&connectparameters.;
%selectRecords&selectRecordParameters.;
%mend doQuery;

%doQuery;
%mend accessSAS;

%macro accessSQLServer(connectParameters,selectRecordParameters);

%macro connectDB(num,char);
%put SQL Server ConnectDB;
%mend connectDB;

%macro selectRecords(num,char);
%put SQL Server Record Selection;
%mend selectRecords;

%macro doQuery;
* doQuery is the same for all macros;
%connectDB&connectparameters.;
%selectRecords&selectRecordParameters.;
%mend doQuery;

%doQuery;
%mend accessSQLServer;

%accessSAS(connectParameters=(num=1,char=SAS),
selectRecordParameters=(num=2,char=SAS));

%accessSQLServer(connectParameters=(num=1,char=SQLServer),
selectRecordParameters=(num=2,char=SQLServer));

strategyPattern2

/*
The strategy pattern allows algorithm variation based on the parameters. In this pattern, one macro implements the
algorithm, and the selection comes to the implementation macro through the macro parameters
*/
data work.taxExample;
length grossAmount totalTax 8;
grossAmount = 34000;
run;

%macro calculateTaxes(dataset,county);

%macro taxStrategy(county);

%macro DeKalb;
totalTax = grossAmount * 0.06;
%mend deKalb;

%macro Fulton;
totalTax = grossAmount * 0.075;
%mend Fulton;

%macro Gwinnett;
totalTax = grossAmount * 0.06;
%mend Gwinnett;

%if &county. = DeKalb or
&county. = Fulton or
&county. = Gwinnett %then
%&county.;
%mend taxStrategy;

data &dataset.;
set &dataset.;

%taxStrategy(&county.);
run;

proc print data=&dataset.;
run;

%mend calculateTaxes;

%calculateTaxes(dataset=work.taxExample, county=Fulton);

strategyPattern1

/*
The strategy pattern allows algorithm variation based on the parameters. In this pattern, one macro implements the
algorithm, and the selection comes to the implementation macro through the macro parameters
*/
data work.taxExample;
length grossAmount totalTax 8;
grossAmount = 34000;
run;

%macro calculateTaxes(dataset,county);

%macro taxStrategy(county);

%macro DeKalb;
totalTax = grossAmount * 0.06;
%mend deKalb;

%macro Fulton;
totalTax = grossAmount * 0.075;
%mend Fulton;

%macro Gwinnett;
totalTax = grossAmount * 0.06;
%mend Gwinnett;

%if &county. = DeKalb or
&county. = Fulton or
&county. = Gwinnett %then
%&county.;
%mend taxStrategy;

data &dataset.;
set &dataset.;

%taxStrategy(&county.);
run;

proc print data=&dataset.;
run;

%mend calculateTaxes;

%calculateTaxes(dataset=work.taxExample, county=Fulton);

pattern5.InheritByIncludeMacro

/*
The %INCLUDE command can be used in the following contexts:
?Lines can be included from an external named text file
?Files can be included from a SAS Catalog
?Previously submitted lines can be included by number (feeling lucky?)
?Lines can be entered interactively (terminated with a %RUN command)
*/

%include 'E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\Macro.OOP\Analysis\prjName\macro\freqmeans.sas';
%include  'E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\Macro.OOP\Analysis\prjName\macro\sumdollar.sas';

/*then call the macro*/
%freqmeans;
%sumdollar;

pattern4.ConditionalNestedMacro

/*
TIP SIX: CONDITIONALLY DEFINE NESTED SAS MACROS

*/

/*Conditional Nested SAS Macro Example*/

%macro stats1(product,year);
title "Statistics for &product in &year";

%if &year>1929 and &year<1935 %then
%do;
title2 "Some Data Might Be Missing";
%end;

%if &year >= 2001 %then
%do;

%macro analysis(type=);

proc means data=work.products;
where product="&product" and year=&year and type=&type;
run;

proc freq data=work.products;
tables year*type*product/list;
run;

%mend analysis;

%end;
%else
%do;

%macro analysis(type=);

proc means data=work.products;
where product="&product" and year=&year and type=&type;
run;

%mend analysis;

%end;

%do counter = 30 %to 50;
%analysis(&counter);
%end;

title;
%mend stats1;

%stats1(steel,2002)
%stats1(beef,2000)
%stats1(fiberglass,2001)

/*
conditional nested macro
*/
%macro divCardByGapSec(gapSec);
libname sdata "E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\sData";
%macro sqlRec(start,end);
proc sql;
select * from sData.cbillall where monotonic() between &start and &end;
quit;
%mend sqlRec;

%if &gapSec < 300 %then
%sqlRec(1,2);

%else %if &gapSec > 300 %then
%sqlRec(10,20);
%else
%sqlRec(10,200);

%mend divCardByGapSec;

%divCardByGapSec(200);
%divCardByGapSec(600);

pattern3.AutocallMacro

/*
Ref: E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria
\SAS.DS2\SASUniversityEdition\myfolders\DesignPattern
\AUTOCALL MACRO LIBRARIES.pdf

Problem to be solved:
1. save macros in files, save to somewhere in disk
2. load the macros in Autocall Library

Method:
1. define macros, save filename = macro name, in lower case
2. use filename macroName 'fileLocation.sas'
3. add to autocall library:
OPTIONS MAUTOSOURCE SASAUTOS=(freqmeans sumdollar SASAUTOS);

*/
FILENAME freqmeans 'E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\Macro.OOP\Analysis\prjName\macro\freqmeans.sas';
FILENAME sumdollar 'E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\Macro.OOP\Analysis\prjName\macro\sumdollar.sas';


OPTIONS MAUTOSOURCE SASAUTOS=(freqmeans sumdollar SASAUTOS);

/*
in main program, or the caller program,
call the macros in Autocall library
*/
%sumDollar;
%freqMeans;


/*
delete a macro to override it*/
%macro mark1(var=);

data work.&var.;
length year 8;
year=2003;
run;

%mend mark1;


proc catalog cat=work.sasmacr;
delete mark1.macro;
run;

%macro mark1(var=,year=);

data work.&var.;
length year&year. 8;
year&year=&year.;
run;

%mend mark1;

pattern2.POLYMORPHISM

%global age;
%let income=income;
%let yrs_educ=yrs_educ;

data work.mark;
income = 75000;
yrs_educ = 20;
age = 40;
run;

/*
Parse dynamic number of variables to macro
call different functions
*/

%macro plot(yvar= ,xvar= );
%if %length(&xvar) and %length(&yvar) %then
%do;
proc plot data=work.mark;
plot &yvar*&xvar;
run;
%end;
%else %if %length(&yvar) %then
%do;
proc means data=work.mark;
var &yvar;
run;

%end;
%mend plot;

%plot(yvar=&income,xvar=&age)
%plot(yvar=&income,xvar=&yrs_educ)



pattern1.ENCAPSULATION

/*
ENCAPSULATION
Encapsulation describes the ability of the SAS macro to hide the
definition of variables and methods inside a macro
ref:
E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\DesignPattern\DependencyInversion\++++read.Toward Object-Oriented Macros in SAS.pdf

TIP ONE: MAKE SAS MACRO VARIABLES AS LOCAL AS POSSIBLE
TIP TWO: NEST SAS MACROS WHEN LOCAL BINDING MAKES SENSE
Parse dynamic number of variables to macro call different functions
Autocall macros
TIP SIX: CONDITIONALLY DEFINE NESTED SAS MACROS
The %INCLUDE for inherit macro

business layer
db layer
Ui layer

*/

proc sql;
select * from DICTIONARY.MACROS where scope='GLOBAL';
quit;

/*Nested Macro Example*/
%macro stats1(product,year);

%macro title;
title "Statistics for &product in &year";
%if &year>1929 and &year<1935 %then
%do;
title2 "Some Data Might Be Missing";
%end;
%mend title;

proc means data=products;
where product="&product" and year=&year;

%title
run;
%mend stats1;

%stats1(steel,2002)
%stats1(beef,2000)
%stats1(fiberglass,2001)


pattern0_RemoveDependancy

/*ref: E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\DesignPattern\DependencyInversion\The Dependency Inversion.Principle.pdf
The Dependency Inversion Principle:
A HIGH LEVEL MODULES SHOULD NOT DEPEND UPON LOW LEVEL MODULES.
BOTH SHOULD DEPEND UPON ABSTRACTIONS - e.g. common data, common param

Traditional Structured Analysis and Design:
tend to create software structures in which high level modules
depend upon low level modules

Consider the implications of high level modules that depend upon low level
modules.
It is the high level modules that contain the important policy decisions
and business models of an application.
when these modules depend upon the lower level modules, then changes to
the lower level modules can have direct effects upon them;
and can force them to change.


High Level Modules Re-use:
Moreover, it is high level modules that we want to be able to reuse. We are already
quite good at reusing low level modules in the form of subroutine libraries. When high
level modules depend upon low level modules, it becomes very difficult to reuse those
high level modules in different contexts. However, when the high level modules are independent
of the low level modules, then the high level modules can be reused quite simply.

This is the principle that is at the very heart of framework design.


The High Level Modules knows nothing of the low Level Modules;
Those details are isolated by interface(or common variable, parameters)
*/

%MACRO callTwice(aString, outputVariant);
%DO i=1 %TO 2;
%&outputVariant(&aString.);
%END;
%MEND callTwice;

%MACRO simplePut(stringToOutput);
%PUT(&stringToOutput.);
%MEND simplePut;
%MACRO upcasePut(stringToOutput);
%PUT(%UPCASE(&stringToOutput.));
%MEND upcasePut;


%callTwice('testString', simplePut);
%callTwice('testString', upcasePut);

Pattern0.RemoveDependancy


%MACRO callTwice(aString, outputVariant);
%DO i=1 %TO 2;
%&outputVariant(&aString.);
%END;
%MEND callTwice;

%MACRO simplePut(stringToOutput);
%PUT(&stringToOutput.);
%MEND simplePut;
%MACRO upcasePut(stringToOutput);
%PUT(%UPCASE(&stringToOutput.));
%MEND upcasePut;



%callTwice('testString', simplePut);
%callTwice('testString', upcasePut);

patter1.ENCAPSULATION

ENCAPSULATION

facadePattern1

/*Design Pattern:
1. The fa鏰de pattern is perhaps one of the most used ideas in the SAS macro language documentation. The idea is to
put complex code inside a macro, and simply present a macro variable interface which only contains certain unique
variables.
*/

/*dynamic reference of data by var name of a dataset */
libname sdata "E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\sData";

proc sql;
select memname from dictionary.tables where libname='SDATA'
;
quit;

proc sql;
select name from dictionary.columns where libname='WORK'
and memname=upcase('smBill');
quit;

proc sql;
select name from dictionary.columns where libname='SDATA'
and memname=upcase('sumDtHrPivot');
quit;

%macro batchBillProc(dataset);

proc freq data=&dataset.;
tables gapSec*dollarAmt/list missing;
run;
proc means data=&dataset.;
var gapSec dollarAmt;
run;

%mend batchBillProc;

%batchBillProc(dataset=sData.sumDtHrPivot);

Dictionary.Catalogs

/*
DICTIONARY.TABLES
--------------------
LIBNAME char(8) label='Library Name',
MEMNAME char(8) label='Member Name',
MEMTYPE char(8) label='Member Type',
MEMLABEL char(40) label='Dataset Label',
TYPEMEM char(8) label='Dataset Type',
CRDATE num format=DATETIME label='Date Created',
MODATE num format=DATETIME label='Date Modified',
NOBS num label='Number of Observations',
OBSLEN num label='Observation Length',
NVAR num label='Number of Variables',
PROTECT char(3) label='Type of Password Protection',
COMPRESS char(8) label='Compression Routine',
REUSE char(3) label='Reuse Space',
BUFSIZE num label='Bufsize',
DELOBS num label='Number of Deleted Observations',
INDXTYPE char(9) label='Type of Indexes'


DICTIONARY.CATALOGS
-----------------------
LIBNAME char(8) label='Library Name',
MEMNAME char(8) label='Member Name',
MEMTYPE char(8) label='Member Type',
OBJNAME char(8) label='Object Name',
OBJTYPE char(8) label='Object Type',
OBJDESC char(40) label='Object Description',
MODIFIED char(8) label='Date Modified',
ALIAS char(8) label='Object Alias'

DICTIONARY.COLUMNS
-------------------
LIBNAME char(8) label='Library Name',
MEMNAME char(8) label='Member Name',
MEMTYPE char(8) label='Member Type',
NAME char(8) label='Column Name',
TYPE char(4) label='Column Type',
LENGTH num label='Column Length',
NPOS num label='Column Position',
VARNUM num label='Column Number in Table',
LABEL char(40) label='Column Label',
FORMAT char(16) label='Column Format',
INFORMAT char(16) label='Column Informat',
IDXUSAGE char(9) label='Column Index Type'


DICTIONARY.EXTFILES
FILEREF char(8) label='Fileref',
XPATH char(80) label='Path Name',
XENGINE char(8) label='Engine Name'


DICTIONARY.INDEXES
LIBNAME char(8) label='Library Name',
MEMNAME char(8) label='Member Name',
MEMTYPE char(8) label='Member Type',
NAME char(8) label='Column Name',
IDXUSAGE char(9) label='Column Index Type',
INDXNAME char(8) label='Index Name',
INDXPOS num label='Pos. of Column in Concatenated Key',
NOMISS char(3) label='Nomiss Option',
UNIQUE char(3) label='Unique Option'

DICTIONARY.MEMBERS
LIBNAME char(8) label='Library Name',
MEMNAME char(8) label='Member Name',
MEMTYPE char(8) label='Member Type',
ENGINE char(8) label='Engine Name',
INDEX char(8) label='Indexes',
PATH char(80) label='Path Name'


DICTIONARY.OPTIONS
OPTNAME char(16) label='Session Option Name',
SETTING char(200) label='Session Option Setting',
OPTDESC char(80) label='Option Description'


DICTIONARY.VIEWS
LIBNAME char(8) label='Library Name',
MEMNAME char(8) label='Member Name',
MEMTYPE char(8) label='Member Type',
ENGINE char(8) label='Engine Name'
DICTIONARY.TITLES
TYPE char(1) label='Title Location',
NUMBER num label='Title Number',
TEXT char(200) label='Title Text'


DICTIONARY.MACROS
SCOPE char(9) label='Macro Scope',
NAME char(8) label='Macro Variable Name',
OFFSET num label='Offset into Macro Variable',
VALUE char(200) label='Macro Variable Value'


*/


/*create macro vars by proc SQL */
proc sql noprint;
select memlabel into :dslabel
from   dictionary.tables
where libname='SASHELP' and memname='RETAIL';
quit;

SAS design pattern - decoratorPattern3

/*The decorator pattern provides a way to add code either
before or after this sumGapSec.*/

/*dynamic reference of data by var name of a dataset */
libname sdata "E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\sData";


%macro sumGapSec(mGapSec);
proc sql;
select sum(&mGapSec) as sumGapSec from sData.smBill;
quit;
%mend sumGapSec;


%macro decoratorBefore(parameters);
%put Before;

%sumGapSec&parameters.;
%mend decoratorBefore;

%macro decoratorBeforeAndAfter(parameters);
%put Before;

%sumGapSec&parameters.;
%put After;
%mend decoratorBeforeAndAfter;

%macro decoratorAfter(parameters);
%sumGapSec&parameters.;
%put After;
%mend decoratorAfter;

%decoratorBeforeAndAfter(parameters=(gapSec));
%decoratorBefore(parameters=(gapSec));
%decoratorAfter(parameters=(gapSec));

AnalysisMatrixPattern5

data work.shippingMatrix;
length freight address tax money dates country $64;
freight = '(a,1,a)';
address = '(b,2,b)';
tax = '(c,3,c)';
money = '(d,4,d)';
dates = '(e,5,e)';
country = 'United States of America';
output;
country = 'Canada';
output;
country = 'Germany';
output;
run;

%macro processingMacro(freight,address,tax,money,dates,country);
%put Processing Macro &freight. &address. &tax. &money. &dates. &country.;
%mend processingMacro;

%macro analysisMatrix(dataset);
%local systemError datasetID returnCode totalObs;
%local matrixFreight matrixAddress matrixTax matrixMoney matrixDates matrixCountry;
%let systemError = 0;
%let datasetID = 0;

%if %sysfunc(exist(&dataset,DATA)) %then
%do;
* Open the dataset by obtaining a numeric datasetID;
%let datasetID = %sysfunc(open(&dataset,i));

%if &datasetID. > 0 %then
%put Dataset Successfully Opened: &datasetID.;
%else
%do;
%put ERROR IN OPENING DATASET &dataset. ?DatasetID = &datasetID.;
%let systemError = 1;
%end;
%end;
%else
%do;
%put Dataset &dataset. does not exist;
%let systemError = 1;
%end;

%if not(&systemError.) %then
%do;
* Obtain the number of dataset observations (rows);
%let totalObs = %sysfunc(ATTRN(&datasetID.,NLOBS));

%if &totalObs. > 0 %then
%put Total Dataset Observations: &totalObs.;
%else
%do;
%put ERROR INSUFFICIENT OBSERVATIONS IN &dataset. -- DatasetID = &datasetID.;
%let systemError = 1;
%end;
%end;

%if not(&systemError.) %then
%do;
%do counter = 1 %to &totalObs.;
%let returnCode = %sysfunc(fetchobs(&datasetID.,&counter.));

%if &returnCode. = 0 %then
%do;
%let matrixFreight = %sysfunc(getvarc(&datasetID.,%sysfunc(varnum(&datasetID.,freight))));
%let matrixAddress = %sysfunc(getvarc(&datasetID.,%sysfunc(varnum(&datasetID.,address))));
%let matrixTax = %sysfunc(getvarc(&datasetID.,%sysfunc(varnum(&datasetID.,tax))));
%let matrixMoney = %sysfunc(getvarc(&datasetID.,%sysfunc(varnum(&datasetID.,money))));
%let matrixDates = %sysfunc(getvarc(&datasetID.,%sysfunc(varnum(&datasetID.,dates))));
%let matrixCountry = %sysfunc(getvarc(&datasetID.,%sysfunc(varnum(&datasetID.,country))));

* After the matrix variables have been populated, then call the processing macro;
%processingMacro(freight=&matrixFreight.,address=&matrixAddress.,tax=&matrixTax.,
money=&matrixMoney.,dates=&matrixDates.,country=&matrixCountry.);
%end;
%end;
%end;

%if &datasetID. > 0 %then
%do;
* Close the dataset;
%let returnCode = %sysfunc(close(&datasetID.));

%if &returnCode. = 0 %then
%do;
%let datasetID = 0;
%put Dataset Successfully Closed;
%end;
%else
%do;
%put ERROR IN CLOSING DATASET &datasetID.;
%let systemError = 1;
%end;
%end;
%mend analysisMatrix;

%analysisMatrix(dataset=work.shippingMatrix);

proc setinit;
quit;

/*
open(dataset,'constant')
%sysfunc(open(&dataset.,constant))
*/

SAS MACRO OOP

/*F3/F8, Ctrl+[, Alt+[*/


data _null_;
call symput('macvar','macro variable value or dataset var');
run;
%put 'macvar=' &macvar;

data callerHour;
input gapSec;
datalines;
234
123
456
;
run;

/*create macro vars by data step symput */
/*macro value from a dataset*/
data _null_;
set callerHour;
call symput('gapSecs','gapSec');
%put 'gapSec=' &gapSecs;
run;

data _null_;
call execute('proc print data=callerHour;');
call execute('run;');
run;


/*create macro vars by proc SQL */
proc sql noprint;
select memlabel into :dslabel
from dictionary.tables
where libname='SASHELP' and memname='RETAIL';
quit;

proc sql noprint;
select gapSec into :gaps separated by ','
from   dictionary.tables
where libname='WORK' and memname='CallerHour';
quit;

proc sql ;
select *
from   dictionary.tables
where libname='WORK' and memname='CallerHour' ;
quit;


proc sql noprint;
select gapSec into :mGapSec
from callerHour;
quit;

proc sql noprint;
select gapSec into :m1-:m3
from callerHour;
quit;

proc sql noprint;
select gapSec into :gapList separated by ','
from callerHour;
quit;

%put &gapList;
%put &gapList;

%put 'gapSec=' &mGapSec;
%put 'gapSec=' &m1 ;
%put 'gapSec=' &m2 ;
%put 'gapSec=' &m3 ;
%put &dslabel;

Label var1='Patient #'
var2='Date of Visit'
var3='Date of Birth';

/*dynamic reference of data by var name of a dataset */
libname sdata "E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\sData";
/*
Min,Yr,agent,cDay,cFullTime,card_no,charge,gapSec,region
var
table--> get from dataset, not from input.
sql macro var
output
*/
/*********************************************/
data mVar;
input var $ 1-9 label $ 11-19;
cards;
Mn       Mn1
Yr        Yr1
agent     agent1
cDay      cDay
cFullTime cFullTime
card_no   card_no
charge    charge
gapSec    gapSec
region    region
;
run;

proc sql noprint;
select var into :var1-:var999 from mVar;
select label into :lbl1-:lbl999 from mVar;
select count(*) into :numVar from mVar;
quit;


/*
data smBill;
set sData.smBill;
run;
*/

%macro runit;
proc datasets lib=work;
modify smBill;
label
%do a=1 %to &numVar;
&&var&a ="&&lbl&a."
%end;
;
quit;
%mend runit;

%runit;

proc contents data=smBill;
run;

/*********************************************/

%macro printit;
proc print data=smBill;
var
%do a=1 %to %eval(&numvar);
&&var&a
%end;;
quit;
%mend;

%printit;

%macro printit;
proc print data=smBill;
var
%do a=1 %to &numvar;
&&var&a
%end;;
quit;
%mend;

%printit;

/*Check the varibles in dataset work.smbill*/
proc sql noprint;
select name into :billVar1-:billVar10 from dictionary.columns where
Libname="WORK" and memname=upcase("smbill");
select count(name) into :billVarCount from dictionary.columns where
Libname="WORK" and memname=upcase("smbill");
quit;
%put &billVarCount;
%macro mPrint;
%do a=1 %to %eval(&billVarCount);
%put &&billVar&a;
%end;
%mend;
%mPrint;

/************************************************/

/*CHECKING TO SEE IF A DATA SET EXISTS*/
proc sql noprint;
select left(put(count(*),8.)) into :exist
from dictionary.tables
where libname='WORK' and memname=upcase('smBill');
quit;

%put &exist;

proc sql;
select * from smbill;
quit;
proc contents data=work.smbill;
run;

/*GENERATING SAS CODE, WRITING IT TO AN EXTERNAL FILE,
AND %INCLUDING IT AT A LATER TIME */
data _null_;
file 'E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\Macro.OOP\m.sas';
put @1 'proc datasets lib=work;';
put @4 'modify smBill;';
put @4 'label ';
do until(last);
set mVar end=last;
put @7 var ' =" ' label ' " ';
end;

put @4 ';';
put @1 'quit;';
stop;
run;

%include 'E:\ChenyxFiles\2014.Study.TrainingCertificate\SAS.Victoria\SAS.DS2\SASUniversityEdition\myfolders\Macro.OOP\m.sas';


/*GENERATING AND EXECUTING SAS CODE USING CALL  EXECUTE*/
data _null_;
call execute('proc datasets lib=work;');
call execute('modify smbill;');
call execute('label ');

do until(last);
set mVar end=last;
call execute(var||'="'||label||'"');
end;

call execute(';');
call execute('quit;');
stop;
run;


/*CHECKING TO SEE IF A DATA SET IS EMPTY*/
proc sql noprint;
select left(put(nobs,8.)) into :nobs
from dictionary.tables
where libname='WORK' and
memname=upcase('smbill');
quit;

%put &nobs;

/*pass an array or an object in macro*/
%macro interface(char, num, array, macro);
%local major;
%macro breakarray(m, n, p, q);
data _null_;
call symput('major',&m);
run;
%put &m &n &p &q;
%mend breakarray;
%macro submacro(a, b);
%put &a &b;
%mend submacro;
%put &char &num &array &macro;
* Break up the array;
%breakarray&array.;
%put &major;
* Call the named macro;
%&macro.;
%mend interface;
%interface (char=character, num=2005,
array=(1,2,3,4),
macro=submacro(a=5,b=c));

/*call a method by macro*/
%macro functions(function, array);

%macro subtract(p1,p2,p3);

data _null_;
result = &p1 - &p2 - &p3;
put result=;
run;

%mend subtract;

%macro add(p1,p2,p3);

data _null_;
result = &p1 + &p2 + &p3;
put result=;
run;

%mend add;

%if &function. = subtract or &function. = add %then
%&function.&array.;
%mend functions;

%functions (function=add, array=(p1=45,p2=34,p3=34));