SAS基础宏之9:FillMissWithNonMiss-经管之家官网!

人大经济论坛-经管之家 收藏本站
您当前的位置> 软件培训>>

SAS软件培训

>>

SAS基础宏之9:FillMissWithNonMiss

SAS基础宏之9:FillMissWithNonMiss

发布:playmore | 分类:SAS软件培训

关于本站

人大经济论坛-经管之家:分享大学、考研、论文、会计、留学、数据、经济学、金融学、管理学、统计学、博弈论、统计年鉴、行业分析包括等相关资源。
经管之家是国内活跃的在线教育咨询平台!

获取电子版《CDA一级教材》

完整电子版已上线CDA网校,累计已有10万+在读~ 教材严格按考试大纲编写,适合CDA考生备考,也适合业务及数据分析岗位的从业者提升自我。

完整电子版已上线CDA网校,累计已有10万+在读~ 教材严格按考试大纲编写,适合CDA考生备考,也适合业务及数据分析岗位的从业者提升自我。

这个宏就是用来填补缺失值的可以用上一个或下一个非缺失值填补缺失值支持数值变量也支持字符变量%macroFillMissWithNonMiss(SourceTable,TargetTable,ByFactors,MissingVar,OrderVar,Type);/*********************** ...
免费学术公开课,扫码加入


这个宏就是用来填补缺失值的
可以用上一个或下一个非缺失值填补缺失值
支持数值变量也支持字符变量
  1. %macro FillMissWithNonMiss(SourceTable,TargetTable,ByFactors,MissingVar,OrderVar,Type);
  2. /**********************************************************************/
  3. /* 此宏对原表中含有缺失值的变量进行填补,其方法是将缺失值用上一个或下 */
  4. /* 一个非缺失值来填补。其中SourceTable是原始表格;TargetTable是结果表 */
  5. /* 格;ByFactors是分组变量;MissingVar是可能含有缺失值的变量, */
  6. /* =_Numeric_表示选择全部数值型变量,=_Character_表示选择全部字符型变 */
  7. /* 量,=_All_表示选择全部变量,也可以选择多个变量,用空格分隔;Order_ */
  8. /* Var是排列变量,可设置为多个,用空格分隔,默认按升序排列,若要降序*/
  9. /* 排列,可在相应的变量后加DESCENDING;Type是缺失值的选取方式, */
  10. /* =Previous表示缺失值选取前一个非缺失值,=Next表示缺失值选取后一个非 */
  11. /* 缺失值,=Mix表示用线性插值的方法填补缺失值(该方法只适用于数值型变 */
  12. /* 量,对字符型变量若设为Mix,则自动用Previous的方法插值)。 */
  13. /* */
  14. /* 最终结果表格中指定的含有缺失值的变量的缺失值被填补。 */
  15. /* */
  16. /* Created on 2011.9.28 */
  17. /* Modified on 2013.3.22 */
  18. /**********************************************************************/

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

  21. /* 若SourceTable与TargetTable相同,则设FMWNM_res为&SourceTable */
  22. %if %UPCASE(&SourceTable) EQ %UPCASE(&TargetTable) %then %let FMWNM_res=&SourceTable;
  23. %else %let FMWNM_res=FMWNM_res;

  24. data &FMWNM_res;
  25. set &SourceTable;
  26. run;

  27. /* 检查ByFactors的存在性 */
  28. %if &ByFactors EQ %STR() %then %do;
  29. %let ByFactors=FMWNM_ByFactors;

  30. data &FMWNM_res;
  31. set &FMWNM_res;
  32. FMWNM_ByFactors=1;
  33. run;
  34. %end;

  35. %ChkVar(SourceTable=&FMWNM_res,InputVar=&ByFactors,FlagVarExists=FMWNM_FlagVarExists1);

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

  40. %local LastByFactors;
  41. %let LastByFactors=%SYSFUNC(SCAN(&ByFactors,-1,' '));

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

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

  48. /* 检查MissingVar的存在性 */
  49. %if (%UPCASE(&MissingVar) NE _NUMERIC_) AND (%UPCASE(&MissingVar) NE _CHARACTER_) AND (%UPCASE(&MissingVar) NE _ALL_) %then %do;
  50. %ChkVar(SourceTable=&FMWNM_res,InputVar=&MissingVar,FlagVarExists=FMWNM_FlagVarExists2);

  51. %if %SYSFUNC(FIND(&FMWNM_FlagVarExists2,0)) NE 0 %then %do;
  52. %put ERROR: The MissingVar %SCAN(&ByFactors,%SYSFUNC(FIND(&FMWNM_FlagVarExists2,0))) does not exist in SourceTable, please check it again.;
  53. %goto exit;
  54. %end;
  55. %end;

  56. /* 检查OrderVar的存在性 */
  57. %if &OrderVar EQ %STR() %then %do;
  58. %let OrderVar=FMWNM_OrderVar;

  59. data &FMWNM_res;
  60. set &FMWNM_res;
  61. FMWNM_OrderVar=_N_;
  62. run;
  63. %end;

  64. %ChkVar(SourceTable=&FMWNM_res,InputVar=&OrderVar,FlagVarExists=FMWNM_FlagVarExists3);

  65. %if %SYSFUNC(FIND(&FMWNM_FlagVarExists3,0)) NE 0 %then %do;
  66. %put ERROR: The OrderVar %SCAN(&OrderVar,%SYSFUNC(FIND(&FMWNM_FlagVarExists3,0))) does not exist in SourceTable, please check it again.;
  67. %goto exit;
  68. %end;

  69. /* 逗号分隔的OrderVar_Comma用于SQL语句 */
  70. %local OrderVar_Comma;

  71. %if &OrderVar NE %STR() %then %do;
  72. %if %SYSFUNC(FIND(&OrderVar,%STR( ))) NE 0 %then %do;
  73. %let OrderVar=%SYSFUNC(COMPBL(&OrderVar)); /* 压缩多余空格 */
  74. %let OrderVar_Comma=%PrxChange(InputString=&OrderVar,PrxString=s/ DESCENDING/DESCENDING/); /* 解决DESCENDING的格式问题 */
  75. %let OrderVar_Comma=%SYSFUNC(TRANWRD(&OrderVar_Comma,%STR( ),ANCBS_Space));
  76. %let OrderVar_Comma=%PrxChange(InputString=&OrderVar_Comma,PrxString=s/DESCENDING/ DESCENDING/);
  77. %let OrderVar_Comma=%SYSFUNC(TRANWRD(&OrderVar_Comma,ANCBS_Space,%STR(,)));
  78. %end;
  79. %else %let OrderVar_Comma=&OrderVar;
  80. %end;
  81. %else %let OrderVar_Comma=;

  82. /* 检查Type的存在性和合法性 */
  83. %if &Type EQ %STR() %then %let Type=PREVIOUS;

  84. %if (%UPCASE(&Type) NE PREVIOUS) AND (%UPCASE(&Type) NE NEXT) AND (%UPCASE(&Type) NE MIX) %then %do;
  85. %put ERROR: The Type should be PREVIOUS, NEXT or MIX, case insensitive and without quotes.;
  86. %goto exit;
  87. %end;

  88. /* 开始进行计算 */
  89. /* 首先,根据Type设置对原始表格进行排序 */
  90. %if %UPCASE(&Type) EQ PREVIOUS %then %do;
  91. proc sort data=&FMWNM_res;
  92. by &OrderVar;
  93. run;
  94. %end;
  95. %else %if (%UPCASE(&Type) EQ NEXT) OR (%UPCASE(&Type) EQ MIX) %then %do; /* 将原表按&ByFactors逆序排序 */
  96. proc sort data=&FMWNM_res;
  97. by DESCENDING %SYSFUNC(TRANWRD(&OrderVar,%STR( ),%STR( )DESCENDING%STR( )));
  98. run;
  99. %end;

  100. /* 其次,对含有缺失值的变量进行补足 */
  101. %if %UPCASE(&MissingVar) EQ _NUMERIC_ %then %do;
  102. %GetMissNum(SourceTable=&FMWNM_res,TargetTable=FMWNM_MissNumeric_temp,InputVar=_NUMERIC_);

  103. proc sql noprint;
  104. create table FMWNM_MissNumeric as
  105. select *,monotonic() as _N_ from FMWNM_MissNumeric_temp
  106. where MissNum GT 0;
  107. quit;

  108. proc sql noprint;
  109. select count(*) into :FMWNM_MissVarNum
  110. from FMWNM_MissNumeric;
  111. quit;

  112. %if %UPCASE(&Type) NE MIX %then %do;
  113. %do FMWNM_i=1 %to &FMWNM_MissVarNum;
  114. proc sql noprint;
  115. select VarName into :FMWNM_MissVarName
  116. from FMWNM_MissNumeric
  117. where _N_ EQ &FMWNM_i;
  118. quit;

  119. data &FMWNM_res(drop=var_temp);
  120. set &FMWNM_res;
  121. retain var_temp;
  122. %if %UPCASE(&Type) EQ PREVIOUS %then %do;
  123. by &ByFactors;
  124. %end;
  125. %else %if %UPCASE(&Type) EQ NEXT %then %do;
  126. by DESCENDING %SYSFUNC(TRANWRD(&ByFactors,%STR( ),%STR( )DESCENDING%STR( )));
  127. %end;
  128. if first.&LastByFactors then var_temp=&FMWNM_MissVarName;
  129. if &FMWNM_MissVarName NE . then var_temp=&FMWNM_MissVarName;
  130. else &FMWNM_MissVarName=var_temp;
  131. run;
  132. %end;
  133. %end;
  134. %else %do;
  135. %do FMWNM_i=1 %to &FMWNM_MissVarNum;
  136. proc sql noprint;
  137. select VarName into :FMWNM_MissVarName
  138. from FMWNM_MissNumeric
  139. where _N_ EQ &FMWNM_i;
  140. quit;

  141. %let FMWNM_MissVarName=%SYSFUNC(STRIP(&FMWNM_MissVarName));

  142. proc sort data=&FMWNM_res;
  143. by DESCENDING %SYSFUNC(TRANWRD(&OrderVar,%STR( ),%STR( )DESCENDING%STR( )));
  144. run;

  145. data &FMWNM_res;
  146. set &FMWNM_res;
  147. retain &FMWNM_MissVarName._Diff;
  148. by DESCENDING %SYSFUNC(TRANWRD(&ByFactors,%STR( ),%STR( )DESCENDING%STR( )));
  149. if first.&LastByFactors then &FMWNM_MissVarName._Diff=&FMWNM_MissVarName;
  150. if first.&LastByFactors AND &FMWNM_MissVarName EQ . then &FMWNM_MissVarName._No=1;
  151. else if &FMWNM_MissVarName NE . then do;
  152. &FMWNM_MissVarName._Diff=&FMWNM_MissVarName; /* 得到两个缺失值之间的差 */
  153. &FMWNM_MissVarName._No=0; /* 得到缺失值的序号 */
  154. end;
  155. else if &FMWNM_MissVarName EQ . then do;
  156. &FMWNM_MissVarName._No+1;
  157. end;
  158. run;

  159. proc sort data=&FMWNM_res;
  160. by &OrderVar;
  161. run;

  162. data &FMWNM_res(drop=&FMWNM_MissVarName._Diff &FMWNM_MissVarName._No var_temp);
  163. set &FMWNM_res;
  164. retain var_temp;
  165. by &ByFactors;
  166. if first.&LastByFactors then var_temp=&FMWNM_MissVarName;
  167. if &FMWNM_MissVarName NE . then var_temp=&FMWNM_MissVarName;
  168. else do;
  169. &FMWNM_MissVarName=var_temp+(&FMWNM_MissVarName._Diff-var_temp)/(&FMWNM_MissVarName._No+1); /* 利用两个缺失值之间的差和缺失值的序号得到需要插入的值 */
  170. var_temp=&FMWNM_MissVarName;
  171. end;
  172. run;
  173. %end;
  174. %end;
  175. %end;
  176. %else %if %UPCASE(&MissingVar) EQ _CHARACTER_ %then %do;
  177. %GetMissNum(SourceTable=&FMWNM_res,TargetTable=FMWNM_MissChar_temp,InputVar=_CHARACTER_);

  178. proc sql noprint;
  179. create table FMWNM_MissChar as
  180. select *,monotonic() as _N_ from FMWNM_MissChar_temp
  181. where MissNum GT 0;
  182. quit;

  183. proc sql noprint;
  184. select count(*) into :FMWNM_MissVarNum
  185. from FMWNM_MissChar;
  186. quit;

  187. %do FMWNM_j=1 %to &FMWNM_MissVarNum;
  188. proc sql noprint;
  189. select VarName into :FMWNM_MissVarName
  190. from FMWNM_MissChar
  191. where _N_ EQ &FMWNM_j;
  192. quit;

  193. data &FMWNM_res(drop=var_temp);
  194. set &FMWNM_res;
  195. retain var_temp;
  196. %if (%UPCASE(&Type) EQ PREVIOUS) OR (%UPCASE(&Type) EQ MIX) %then %do;
  197. by &ByFactors;
  198. %end;
  199. %else %if %UPCASE(&Type) EQ NEXT %then %do;
  200. by DESCENDING %SYSFUNC(TRANWRD(&ByFactors,%STR( ),%STR( )DESCENDING%STR( )));
  201. %end;
  202. if first.&LastByFactors then var_temp=&FMWNM_MissVarName;
  203. if &FMWNM_MissVarName NE '' then var_temp=&FMWNM_MissVarName;
  204. else &FMWNM_MissVarName=var_temp;
  205. run;
  206. %end;
  207. %end;
  208. %else %do;
  209. %if %UPCASE(&MissingVar) EQ _ALL_ %then %do;
  210. %GetMissNum(SourceTable=&FMWNM_res,TargetTable=FMWNM_MissAll_temp,InputVar=_ALL_);
  211. %end;
  212. %else %do; /* 若MissingVar为指定变量名称,则仅取指定变量的缺失值数量数据 */
  213. %GetMissNum(SourceTable=&FMWNM_res,TargetTable=FMWNM_MissAll_temp,InputVar=&MissingVar);
  214. %end;

  215. proc sql noprint;
  216. create table FMWNM_MissAll as
  217. select *,monotonic() as _N_ from FMWNM_MissAll_temp
  218. where MissNum GT 0;
  219. quit;

  220. proc sql noprint;
  221. select count(*) into :FMWNM_MissVarNum
  222. from FMWNM_MissAll;
  223. quit;

  224. %do FMWNM_k=1 %to &FMWNM_MissVarNum;
  225. proc sql noprint;
  226. select VarName,VarType into :FMWNM_MissVarName,:FMWNM_MissVarType
  227. from FMWNM_MissAll
  228. where _N_ EQ &FMWNM_k;
  229. quit;

  230. %if %UPCASE(&Type) NE MIX %then %do;
  231. data &FMWNM_res(drop=var_temp);
  232. set &FMWNM_res;
  233. retain var_temp;
  234. %if %UPCASE(&Type) EQ PREVIOUS %then %do;
  235. by &ByFactors;
  236. %end;
  237. %else %if %UPCASE(&Type) EQ NEXT %then %do;
  238. by DESCENDING %SYSFUNC(TRANWRD(&ByFactors,%STR( ),%STR( )DESCENDING%STR( )));
  239. %end;
  240. if first.&LastByFactors then var_temp=&FMWNM_MissVarName;
  241. %if &FMWNM_MissVarType EQ N %then %do;
  242. if &FMWNM_MissVarName NE . then var_temp=&FMWNM_MissVarName;
  243. else &FMWNM_MissVarName=var_temp;
  244. %end;
  245. %else %do;
  246. if &FMWNM_MissVarName NE '' then var_temp=&FMWNM_MissVarName;
  247. else &FMWNM_MissVarName=var_temp;
  248. %end;
  249. run;
  250. %end;
  251. %else %do;
  252. %let FMWNM_MissVarName=%SYSFUNC(STRIP(&FMWNM_MissVarName));
  253. %if &FMWNM_MissVarType EQ N %then %do;
  254. proc sort data=&FMWNM_res;
  255. by DESCENDING %SYSFUNC(TRANWRD(&OrderVar,%STR( ),%STR( )DESCENDING%STR( )));
  256. run;

  257. data &FMWNM_res;
  258. set &FMWNM_res;
  259. retain &FMWNM_MissVarName._Diff;
  260. by DESCENDING %SYSFUNC(TRANWRD(&ByFactors,%STR( ),%STR( )DESCENDING%STR( )));
  261. if first.&LastByFactors then &FMWNM_MissVarName._Diff=&FMWNM_MissVarName;
  262. if first.&LastByFactors AND &FMWNM_MissVarName EQ . then &FMWNM_MissVarName._No=1;
  263. else if &FMWNM_MissVarName NE . then do;
  264. &FMWNM_MissVarName._Diff=&FMWNM_MissVarName; /* 得到两个缺失值之间的差 */
  265. &FMWNM_MissVarName._No=0; /* 得到缺失值的序号 */
  266. end;
  267. else if &FMWNM_MissVarName EQ . then do;
  268. &FMWNM_MissVarName._No+1;
  269. end;
  270. run;

  271. proc sort data=&FMWNM_res;
  272. by &OrderVar;
  273. run;

  274. data &FMWNM_res(drop=&FMWNM_MissVarName._Diff &FMWNM_MissVarName._No var_temp);
  275. set &FMWNM_res;
  276. retain var_temp;
  277. by &ByFactors;
  278. if first.&LastByFactors then var_temp=&FMWNM_MissVarName;
  279. if &FMWNM_MissVarName NE . then var_temp=&FMWNM_MissVarName;
  280. else do;
  281. &FMWNM_MissVarName=var_temp+(&FMWNM_MissVarName._Diff-var_temp)/(&FMWNM_MissVarName._No+1); /* 利用两个缺失值之间的差和缺失值的序号得到需要插入的值 */
  282. var_temp=&FMWNM_MissVarName;
  283. end;
  284. run;
  285. %end;
  286. %else %do;
  287. data &FMWNM_res(drop=var_temp);
  288. set &FMWNM_res;
  289. retain var_temp;
  290. by &ByFactors;
  291. if first.&LastByFactors then var_temp=&FMWNM_MissVarName;
  292. if &FMWNM_MissVarName NE '' then var_temp=&FMWNM_MissVarName;
  293. else &FMWNM_MissVarName=var_temp;
  294. run;
  295. %end;
  296. %end;
  297. %end;
  298. %end;

  299. %if %UPCASE(&FMWNM_res) EQ %UPCASE(&TargetTable) %then %do;
  300. proc sort data=&TargetTable;
  301. by &OrderVar;
  302. run;
  303. %end;
  304. %else %do;
  305. proc sql noprint;
  306. create table &TargetTable as
  307. select * from &FMWNM_res
  308. order by &OrderVar_Comma;
  309. quit;
  310. %end;

  311. /* 删除临时生成的ByFactors和OrderVar */
  312. %if %UPCASE(&ByFactors) EQ FMWNM_BYFACTORS %then %do;
  313. data &TargetTable;
  314. set &TargetTable;
  315. drop FMWNM_ByFactors;
  316. run;
  317. %end;

  318. %if %UPCASE(&OrderVar) EQ FMWNM_ORDERVAR %then %do;
  319. data &TargetTable;
  320. set &TargetTable;
  321. drop FMWNM_OrderVar;
  322. run;
  323. %end;

  324. /* 删除不必要的表格 */
  325. proc datasets lib=work nolist;
  326. delete FMWNM_:;
  327. quit;

  328. %exit:
  329. %mend;


  330. %macro Demo();

  331. %let SourceTable=a;
  332. %let TargetTable=b;
  333. %let ByFactors=;
  334. %let MissingVar=_All_; /* =_Numeric_表示选择全部数值型变量,=_Character表示选择全部字符型变量,=_All_表示选择全部变量,也可以选择多个变量,用空格分隔 */
  335. %let OrderVar=;
  336. %let Type=MIX; /* 对缺失值进行处理的方法,=Previous、Next或MIX */
  337. %FillMissWithNonMiss(&SourceTable,&TargetTable,&ByFactors,&MissingVar,&OrderVar,&Type);

  338. %mend;
复制代码
「经管之家」APP:经管人学习、答疑、交友,就上经管之家!
免流量费下载资料----在经管之家app可以下载论坛上的所有资源,并且不额外收取下载高峰期的论坛币。
涵盖所有经管领域的优秀内容----覆盖经济、管理、金融投资、计量统计、数据分析、国贸、财会等专业的学习宝库,各类资料应有尽有。
来自五湖四海的经管达人----已经有上千万的经管人来到这里,你可以找到任何学科方向、有共同话题的朋友。
经管之家(原人大经济论坛),跨越高校的围墙,带你走进经管知识的新世界。
扫描下方二维码下载并注册APP
本文关键词:

本文论坛网址:https://bbs.pinggu.org/thread-2349981-1-1.html

人气文章

1.凡人大经济论坛-经管之家转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
数据分析师 人大经济论坛 大学 专业 手机版
联系客服
值班时间:工作日(9:00--18:00)