楼主: playmore
1414 0

[SAS] SAS基础宏之16:GetStatsForTable [推广有奖]

学科带头人

2%

还不是VIP/贵宾

-

TA的文库  其他...

R相关

经济学相关

金融工程

威望
1
论坛币
16309 个
通用积分
7.1997
学术水平
372 点
热心指数
394 点
信用等级
341 点
经验
15297 点
帖子
1194
精华
1
在线时间
1331 小时
注册时间
2007-1-11
最后登录
2023-12-15

初级学术勋章 初级热心勋章 中级热心勋章

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
宏作用



这个宏主要是用proc means求一系列统计量的

后来又加了些我自己做的统计量计算,如半方量、几何平均值和连乘积等

用这类宏的好处就是方便调用,因为SAS各个过程的可自定义的东西比较多,经常忘

我现在能比较熟练使用的过程就proc sql了


  1. %macro GetStatsForTable(SourceTable,TargetTable,ByFactors,InputVar,InputVarType,OutputVarType,Weight,Statistic);

  2. /**********************************************************************/
  3. /* 此宏计算所选变量的统计指标。其中SourceTable是含有所选变量的原始表 */
  4. /* 格;TargetTable是结果表格;ByFactors是对统计量进行分组研究的分组变 */
  5. /* 量,没有分组变量时可设置为空;InputVar是进行统计的目标变量,若需要 */
  6. /* 统计全部变量、全部数值变量和全部字符变量,可分别设为_ALL_、 */
  7. /* _NUMERIC_和_CHARACTER_;InputVarType是目标变量的类型,当Statistic= */
  8. /* GMEAN时必须设置,=P表示价格变量,=R表示收益率变量;OutputVarType是 */
  9. /* 输出变量的类型,=Origin表示不作处理,即输出变量名称等于目标变量的 */
  10. /* 名称,并用_STAT_变量区分不同的统计量,=Suffix表示输出变量用不同的 */
  11. /* 统计量作为后缀;Weight是权重变量;Statistic是指定的统计量,=All时 */
  12. /* 同时计算N|MIN|MAX|MEAN|STD,也可以单独设置,可以设置的统计量如下所 */
  13. /* 示: */
  14. /* */
  15. /* - Descriptive statistics keyword */
  16. /* CSS RANGE CV SKEW KURT STD LCLM STDERR MAX SUM MEAN GMEAN(Geo- */
  17. /* metric Mean) GSUM(Continued Product) SUMWGT MIN */
  18. /* UCLM MODE USS N VAR SVAR(Semi-Variance) NMISS */
  19. /* - Quantile statistics keyword */
  20. /* MEDIAN P1 P5 P10 P25 P50 P75 P90 P95 P99 Q1 Q3 QRANGE */
  21. /* - Hypothesis testing keyword */
  22. /* PRT T */
  23. /* */
  24. /* 最终得到的是含有统计结果的结果表格&TargetTable。 */
  25. /* */
  26. /* Created on 2012.12.25 */
  27. /* Modified on 2013.4.28 */
  28. /**********************************************************************/

  29. /* 检查TargetTable的存在性,若不存在则设为&SourceTable */
  30. %if &TargetTable EQ %STR() %then %let TargetTable=&SourceTable;

  31. /* 检查ByFactors的存在性 */
  32. %if &ByFactors NE %STR() %then %do;
  33. %ChkVar(SourceTable=&SourceTable,InputVar=&ByFactors,FlagVarExists=GSFT_FlagVarExists1);

  34. %if %SYSFUNC(FIND(&GSFT_FlagVarExists1,0)) NE 0 %then %do;
  35. %put ERROR: The ByFactors "%SCAN(&ByFactors,%SYSFUNC(FIND(&GSFT_FlagVarExists1,0)))" does not exist in SourceTable, please check it again.;
  36. %goto exit;
  37. %end;

  38. /* 逗号分隔的ByFactors_Comma用于SQL语句 */
  39. %local ByFactors_Comma;

  40. %if %SYSFUNC(FIND(&ByFactors,%STR( ))) NE 0 %then %do;
  41. %let ByFactors_Comma=%SYSFUNC(TRANWRD(%SYSFUNC(COMPBL(&ByFactors)),%STR( ),%STR(,)));
  42. %end;
  43. %else %do;
  44. %let ByFactors_Comma=&ByFactors;
  45. %end;
  46. %end;


  47. /* 检查InputVar的存在性 */
  48. %if %SYSFUNC(FIND(&InputVar,%STR(:))) NE 0 %then %do;
  49. %GetVarListForTable(SourceTable=&SourceTable,
  50. TargetTable=,
  51. OutputVar=GSFT_InputVar,
  52. VarType=&InputVar);

  53. %let InputVar=&GSFT_InputVar;
  54. %end;

  55. %if %UPCASE(&InputVar) NE _ALL_ AND %UPCASE(&InputVar) NE _NUMERIC_ AND %UPCASE(&InputVar) NE _CHARACTER_ %then %do;
  56. %ChkVar(SourceTable=&SourceTable,InputVar=&InputVar,FlagVarExists=GSFT_FlagVarExists2);

  57. %if %SYSFUNC(FIND(&GSFT_FlagVarExists2,0)) NE 0 %then %do;
  58. %put ERROR: The InputVar %SCAN(&InputVar,%SYSFUNC(FIND(&GSFT_FlagVarExists2,0))) does not exist in SourceTable, please check it again.;
  59. %goto exit;
  60. %end;
  61. %end;

  62. /* 检查InputVarType的合法性 */
  63. %if %UPCASE(&Statistic) EQ GMEAN %then %do;
  64. %if (%UPCASE(&InputVarType) NE P) AND (%UPCASE(&InputVarType) NE R) %then %do;
  65. %put ERROR: The InputVarType should be P or R, case insensitive and without quotes.;
  66. %goto exit;
  67. %end;
  68. %end;

  69. /* 拆分InputVar */
  70. %SeparateString(InputString=&InputVar,OutputString=GSFT_InputVar);

  71. /* 检查OutputVarType的合法性 */
  72. %if &OutputVarType EQ %STR() %then %let OutputVarType=Origin;

  73. %if (%UPCASE(&OutputVarType) NE ORIGIN) AND (%UPCASE(&OutputVarType) NE SUFFIX) %then %do;
  74. %put ERROR: The OutputVarType should be Origin or Suffix, case insensitive and without quotes.;
  75. %goto exit;
  76. %end;

  77. /* 检查Weight的唯一性和存在性 */
  78. %if %SYSFUNC(FIND(&Weight,%STR( ))) NE 0 %then %do;
  79. %put ERROR: There should be only one Weight, please check it again.;
  80. %goto exit;
  81. %end;

  82. %if &Weight NE %STR() %then %do;
  83. %ChkVar(SourceTable=&SourceTable,InputVar=&Weight,FlagVarExists=GSFT_FlagVarExists3);

  84. %if %SYSFUNC(FIND(&GSFT_FlagVarExists3,0)) NE 0 %then %do;
  85. %put ERROR: The Weight "&Weight" does not exist in SourceTable, please check it again.;
  86. %goto exit;
  87. %end;
  88. %end;

  89. /* 检查Statistic的唯一性 */
  90. %if %SYSFUNC(FIND(&Statistic,%STR( ))) NE 0 %then %do;
  91. %put ERROR: There should be only one Statistic, please check it again.;
  92. %goto exit;
  93. %end;

  94. /* 确认指定的统计量,N|MIN|MAX|MEAN|STD为StatGroup1,其他非特殊统计量为StatGroup2,SVAR为Group3,GMEAN为Group4 */
  95. %let Statistic=%UPCASE(&Statistic);
  96. %let GSFT_StatGroup1=%PrxMatch(InputString=&Statistic,PrxString=/((?<!\w)N(?!\w))|(MIN)|(MAX)|((?<!\w)MEAN(?!\w))|(STD)|(ALL)/);
  97. /* 将正则表达式GSFT_StatGroup2分拆成两段,以免报错 */
  98. %let GSFT_StatGroup2a=%PrxMatch(InputString=&Statistic,PrxString=/(CSS)|(RANGE)|(CV)|(SKEW)|(KURT)|(LCLM)|(STDERR)|((?<!\w)SUM(?!\w))|(SUMWGT)|(UCLM)|(MODE)|(USS)|((?<!\w)VAR(?!\w))|(NMISS)|(MEDIAN)/);
  99. %let GSFT_StatGroup2b=%PrxMatch(InputString=&Statistic,PrxString=/(Q1)|(Q3)|(P1(?!0))|(P5)|(P10)|(P25)|(P50)|(P75)|(P90)|(P95)|(P99)|(QRANGE)|(PRT)|((?<!\w)T(?!\w))/);
  100. %let GSFT_StatGroup3=%PrxMatch(InputString=&Statistic,PrxString=/(SVAR)/);
  101. %let GSFT_StatGroup4=%PrxMatch(InputString=&Statistic,PrxString=/(GMEAN|GSUM)/);

  102. %if &GSFT_StatGroup1 EQ 0 AND &GSFT_StatGroup2a EQ 0 AND &GSFT_StatGroup2b EQ 0 AND &GSFT_StatGroup3 EQ 0 AND &GSFT_StatGroup4 EQ 0 %then %do;
  103. %put ERROR: The Statistic should be assigned properly, please check it again.;
  104. %goto exit;
  105. %end;

  106. /* 开始进行计算 */
  107. /* 第一步:得到统计量 */
  108. /* 情形一:计算第一组统计量 */
  109. %if &GSFT_StatGroup1 NE 0 %then %do;
  110. %if &ByFactors NE %STR() %then %do;
  111. proc sort data=&SourceTable;
  112. by &ByFactors;
  113. run;

  114. proc means data=&SourceTable noprint;
  115. by &ByFactors;
  116. var &InputVar;
  117. weight &Weight;
  118. output out=GSFT_temp;
  119. run;
  120. %end;
  121. %else %do;
  122. proc means data=&SourceTable noprint;
  123. var &InputVar;
  124. weight &Weight;
  125. output out=GSFT_temp;
  126. run;
  127. %end;

  128. data &TargetTable;
  129. set GSFT_temp;
  130. %if &Statistic NE ALL %then %do;
  131. if _stat_="&Statistic." then output &TargetTable;
  132. %end;
  133. run;
  134. %end;
  135. /* 情形二:计算第二组统计量 */
  136. %else %if &GSFT_StatGroup2a NE 0 OR &GSFT_StatGroup2b NE 0 %then %do;
  137. %if &ByFactors NE %STR() %then %do;
  138. proc sort data=&SourceTable;
  139. by &ByFactors;
  140. run;

  141. proc means data=&SourceTable noprint;
  142. by &ByFactors;
  143. var &InputVar;
  144. weight &Weight;
  145. output out=GSFT_temp &Statistic.=;
  146. run;

  147. data &TargetTable;
  148. retain &ByFactors _TYPE_ _FREQ_ _STAT_ &InputVar;
  149. set GSFT_temp;
  150. _STAT_="&Statistic.";
  151. run;
  152. %end;
  153. %else %do;
  154. proc means data=&SourceTable noprint;
  155. var &InputVar;
  156. weight &Weight;
  157. output out=GSFT_temp &Statistic.=;
  158. run;

  159. data &TargetTable;
  160. retain &ByFactors _TYPE_ _FREQ_ _STAT_ &InputVar;
  161. set GSFT_temp;
  162. _STAT_="&Statistic.";
  163. run;
  164. %end;
  165. %end;
  166. /* 情形三:计算第三组统计量,SVAR,即半方差 */
  167. %else %if &GSFT_StatGroup3 NE 0 %then %do;
  168. /* 逗号分隔的ByFactors_Comma用于SQL语句 */
  169. %if %SYSFUNC(FIND(&ByFactors,%STR( ))) NE 0 %then %do;
  170. %let ByFactors_Comma=%SYSFUNC(TRANWRD(%SYSFUNC(COMPBL(&ByFactors)),%STR( ),%STR(,)));
  171. %end;
  172. %else %let ByFactors_Comma=&ByFactors;

  173. /* 第一步:计算分组均值 */
  174. proc sql noprint;
  175. create table GSFT_Mean as
  176. select *,Count(*) as _FREQ_,
  177. %do GSFT_i=1 %to &GSFT_InputVar_Num;
  178. (mean(&&GSFT_InputVar_Var&GSFT_i.)) as &&GSFT_InputVar_Var&GSFT_i.._Mean
  179. %if &GSFT_i NE &GSFT_InputVar_Num %then %do;
  180. ,
  181. %end;
  182. %end;
  183. from &SourceTable
  184. %if &ByFactors NE %STR() %then %do;
  185. group by &ByFactors_Comma
  186. %end;
  187. ;
  188. quit;

  189. /* 第二步:计算分组半离差平方 */
  190. data GSFT_SqrDev;
  191. set GSFT_Mean;
  192. %do GSFT_j=1 %to &GSFT_InputVar_Num;
  193. if &&GSFT_InputVar_Var&GSFT_j LT &&GSFT_InputVar_Var&GSFT_j.._Mean then &&GSFT_InputVar_Var&GSFT_j.._SqrDev=(&&GSFT_InputVar_Var&GSFT_j..-&&GSFT_InputVar_Var&GSFT_j.._Mean)**2;
  194. else &&GSFT_InputVar_Var&GSFT_j.._SqrDev=0;
  195. %end;
  196. run;

  197. /* 第三步:计算分组半方差 */
  198. proc sql noprint;
  199. create table &TargetTable as
  200. select distinct
  201. %if &ByFactors NE %STR() %then %do;
  202. &ByFactors_Comma,
  203. %end;
  204. _FREQ_,
  205. %do GSFT_k=1 %to &GSFT_InputVar_Num;
  206. sum(&&GSFT_InputVar_Var&GSFT_k.._SqrDev)/_FREQ_ as &&GSFT_InputVar_Var&GSFT_k
  207. %if &GSFT_k NE &GSFT_InputVar_Num %then %do;
  208. ,
  209. %end;
  210. %end;
  211. from GSFT_SqrDev
  212. %if &ByFactors NE %STR() %then %do;
  213. group by &ByFactors_Comma
  214. %end;
  215. ;
  216. quit;

  217. data &TargetTable;
  218. retain &ByFactors _TYPE_ _FREQ_ _STAT_ &InputVar;
  219. set &TargetTable;
  220. _TYPE_=0;
  221. _STAT_='SVAR';
  222. run;
  223. %end;
  224. /* 情形四:计算第四组统计量,GMEAN(几何平均值)和GSUM(连乘积) */
  225. %else %if &GSFT_StatGroup4 NE 0 %then %do;
  226. %if %UPCASE(%SUBSTR(&InputVarType,1,1)) EQ P %then %do; /* 仅对InputVarType的首字母进行判断,P可代表Price/PNL */
  227. proc sql noprint;
  228. create table &TargetTable as
  229. select distinct
  230. %if &ByFactors NE %STR() %then %do;
  231. &ByFactors_Comma,
  232. %end;
  233. %if %UPCASE(&Statistic) EQ GMEAN %then %do;
  234. %do GSFT_i=1 %to &GSFT_InputVar_Num;
  235. (exp(sum(log(&&GSFT_InputVar_Var&GSFT_i))))**(1/COUNT(*)) as &&GSFT_InputVar_Var&GSFT_i
  236. %if &GSFT_i NE &GSFT_InputVar_Num %then %do;
  237. ,
  238. %end;
  239. %end;
  240. %end;
  241. %else %if %UPCASE(&Statistic) EQ GSUM %then %do;
  242. %do GSFT_j=1 %to &GSFT_InputVar_Num;
  243. (exp(sum(log(&&GSFT_InputVar_Var&GSFT_j)))) as &&GSFT_InputVar_Var&GSFT_j
  244. %if &GSFT_j NE &GSFT_InputVar_Num %then %do;
  245. ,
  246. %end;
  247. %end;
  248. %end;
  249. from &SourceTable
  250. %if &ByFactors NE %STR() %then %do;
  251. group by &ByFactors_Comma
  252. %end;
  253. ;
  254. quit;
  255. %end;
  256. %else %if %UPCASE(%SUBSTR(&InputVarType,1,1)) EQ R %then %do;
  257. proc sql noprint;
  258. create table &TargetTable as
  259. select distinct
  260. %if &ByFactors NE %STR() %then %do;
  261. &ByFactors_Comma,
  262. %end;
  263. %if %UPCASE(&Statistic) EQ GMEAN %then %do;
  264. %do GSFT_i=1 %to &GSFT_InputVar_Num;
  265. (exp(sum(log(1+&&GSFT_InputVar_Var&GSFT_i))))**(1/COUNT(*))-1 as &&GSFT_InputVar_Var&GSFT_i
  266. %if &GSFT_i NE &GSFT_InputVar_Num %then %do;
  267. ,
  268. %end;
  269. %end;
  270. %end;
  271. %else %if %UPCASE(&Statistic) EQ GSUM %then %do;
  272. %do GSFT_j=1 %to &GSFT_InputVar_Num;
  273. exp(sum(log(1+&&GSFT_InputVar_Var&GSFT_j)))-1 as &&GSFT_InputVar_Var&GSFT_j
  274. %if &GSFT_j NE &GSFT_InputVar_Num %then %do;
  275. ,
  276. %end;
  277. %end;
  278. %end;
  279. from &SourceTable
  280. %if &ByFactors NE %STR() %then %do;
  281. group by &ByFactors_Comma
  282. %end;
  283. ;
  284. quit;
  285. %end;
  286. %else %do;
  287. %put ERROR: The parameter InputVarType should be P or R, case insensitive and without quotes.;
  288. %goto exit;
  289. %end;

  290. data &TargetTable;
  291. retain &ByFactors _TYPE_ _FREQ_ _STAT_ &InputVar;
  292. set &TargetTable;
  293. _TYPE_=0;
  294. %if %UPCASE(&Statistic) EQ GMEAN %then %do;
  295. _STAT_='GMEAN';
  296. %end;
  297. %if %UPCASE(&Statistic) EQ GSUM %then %do;
  298. _STAT_='GSUM';
  299. %end;
  300. run;
  301. %end;

  302. /* 第二步:按要求输出表格 */
  303. %if %UPCASE(&OutputVarType) EQ SUFFIX %then %do;
  304. proc sql noprint;
  305. select distinct _STAT_ into :GSFT_StatString separated by ' '
  306. from &TargetTable;
  307. quit;

  308. %SeparateString(InputString=&GSFT_StatString,OutputString=GSFT_StatString);

  309. data %do GSFT_m=1 %to &GSFT_StatString_Num;
  310. GSFT_Output_&&GSFT_StatString_Var&GSFT_m(rename=(
  311. %do GSFT_n=1 %to &GSFT_InputVar_Num;
  312. &&GSFT_InputVar_Var&GSFT_n..=&&GSFT_InputVar_Var&GSFT_n.._&&GSFT_StatString_Var&GSFT_m
  313. %end;
  314. ))
  315. %end;
  316. ;
  317. set &TargetTable;
  318. %do GSFT_o=1 %to &GSFT_StatString_Num;
  319. if _STAT_ EQ "&&GSFT_StatString_Var&GSFT_o" then output GSFT_Output_&&GSFT_StatString_Var&GSFT_o;
  320. %end;
  321. run;

  322. data &TargetTable(drop=_STAT_);
  323. merge %do GSFT_p=1 %to &GSFT_StatString_Num;
  324. GSFT_Output_&&GSFT_StatString_Var&GSFT_p
  325. %end;
  326. ;
  327. by &ByFactors;
  328. run;
  329. %end;

  330. /* 删除不必要的表格 */
  331. proc datasets lib=work nolist;
  332. delete GSFT_:;
  333. quit;

  334. %exit:
  335. %mend;


  336. %macro Demo();

  337. %let SourceTable=NavOfFund;
  338. %let TargetTable=NavOfFund_GMean;
  339. %let ByFactors=Fund_Code; /* 可设置为多个,用空格分隔 */
  340. %let InputVar=Adj_NAV Unit_NAV;
  341. %let InputVarType=; /* 当Statistic=GMEAN时必须设置,=P表示价格变量,=R表示收益率变量 */
  342. %let OutputVarType=Suffix; /* 输出变量的类型,=Origin表示不作处理,=Suffix表示输出变量用不同的统计量作为后缀 */
  343. %let Weight=; /* 仅为一个变量 */
  344. %let Statistic=All; /* 仅为一个统计量 */
  345. %GetStatsForTable(&SourceTable,&TargetTable,&ByFactors,&InputVar,&InputVarType,&OutputVarType,&Weight,&Statistic);

  346. /* 计算几何平均收益率的例子,且InputVar变量为价格变量 */
  347. %let SourceTable=ReturnOfFund_Dy;
  348. %let TargetTable=ReturnOfFund_GMean;
  349. %let ByFactors=Fund_Code; /* 可设置为多个,用空格分隔 */
  350. %let InputVar=Adj_NAV;
  351. %let InputVarType=P; /* 当Statistic=GMEAN时必须设置,=P表示价格变量,=R表示收益率变量 */
  352. %let OutputVarType=; /* 输出变量的类型,=Origin表示不作处理,=Suffix表示输出变量用不同的统计量作为后缀 */
  353. %let Weight=; /* 仅为一个变量 */
  354. %let Statistic=GMEAN; /* 仅为一个统计量 */
  355. %GetStatsForTable(&SourceTable,&TargetTable,&ByFactors,&InputVar,&InputVarType,&OutputVarType,&Weight,&Statistic);

  356. /* 计算几何连乘积的例子,且InputVar变量为收益率变量 */
  357. %let SourceTable=GARFP_AbnRetOfPort;
  358. %let TargetTable=GARFP_AbnRetOfPort_GSUM;
  359. %let ByFactors=Port_Code End_Yr End_Mt; /* 可设置为多个,用空格分隔 */
  360. %let InputVar=Ret_Dy Ret_Bm AbnRet_Dy AbnRetRatio_Dy;
  361. %let InputVarType=R; /* 当Statistic=GMEAN时必须设置,=P表示价格变量,=R表示收益率变量 */
  362. %let OutputVarType=; /* 输出变量的类型,=Origin表示不作处理,=Suffix表示输出变量用不同的统计量作为后缀 */
  363. %let Weight=; /* 仅为一个变量 */
  364. %let Statistic=GSUM; /* 仅为一个统计量 */
  365. %GetStatsForTable(&SourceTable,&TargetTable,&ByFactors,&InputVar,&InputVarType,&OutputVarType,&Weight,&Statistic);

  366. %mend;
复制代码


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:stats Table sas基础 ABLE gets GetStatsForTable SAS 基础宏

已有 1 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
niuniuyiwan + 60 + 60 + 1 + 1 + 1 精彩帖子

总评分: 经验 + 60  论坛币 + 60  学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

playmore邀请您访问ChinaTeX论坛!!!进入ChinaTeX论坛
您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注jltj
拉您入交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-5-4 20:15