楼主: 3qsir
3013 16

How do Use Proc SQL to Extract Rolling Column files more efficiency ? [推广有奖]

11
yongyitian 发表于 2014-3-10 10:38:10
3qsir 发表于 2014-3-9 12:24
I delete All "t1" string , but still error in the code:
------------------------------------------- ...
ERROR: The following columns were not found in the contributing tables: '&yf&mf.'n.

Sas considered '&yf&mf.'n  as a column (variable) name, not the expected '201103'n, '201104'n, ...
Reason: Macro variable reference can not be resolved inside single quotation mark.

Try the following code, instead of creating sql code using macro statements.
  1. %macro mm(smonth=);
  2.    proc sql noprint;
  3.      select name, count(*)  into :mvar separated by ' ', :n
  4.         from dictionary.columns
  5.         where libname='WORK' and memname = 'MONTHLY'
  6.         order by name;
  7.    quit;

  8.    data _null_;
  9.       length keepvar $300 var $10;;
  10.         do i = 1 to &n;
  11.            if  "&smonth" = scan("&mvar", i) then start=i;
  12.         end;
  13.         do i = start to start+23;
  14.            var = cats("'", scan("&mvar", i), "'", "n");
  15.            keepvar = catx(' ', keepvar, var);
  16.         end;
  17.       call symput('keepvar', keepvar);
  18.    run;

  19.    data H&smonth;
  20.      set monthly;
  21.      keep ind &keepvar;
  22.    run;
  23. %mend mm;
  24. %mm(smonth=201103);
复制代码

12
nomad5 发表于 2014-3-10 18:50:01
  1. /*这个宏只考虑了从输入的&v.之后连续性的24个月,另外你在调用的时候出错了。整体的思路是对年和月进行循环。12月的时候年加1。其实是有函数可以实现的。*/
  2. /*另外为什么一定要用SQL呢,DATA步应该有更简单的过程*/

  3. %macro m(v);
  4. %let y=%substr(&v.,1,4);
  5. %let m=%substr(&v.,5,2);
  6. %do i=1 %to 24;
  7.     %let mf=%sysfunc(putn(%eval(&m.+&i.-1),z2.));
  8.     %if &mf.>24 %then %do;
  9.         %let mf=%sysfunc(putn(%eval(&mf.-24),z2.));
  10.         %let yf=%eval(&y.+2);
  11.     %end;
  12.     %else %if &mf.>12 %then %do;
  13.         %let mf=%sysfunc(putn(%eval(&mf.-12),z2.));
  14.         %let yf=%eval(&y.+1);
  15.     %end;
  16.     %else %let yf=&y.;

  17.     ,t1."&yf.&mf."n as K&i.
  18.     /*这里原来多一个分号,是我写错了*/

  19. %end;
  20. %mend m;
  21. /*%m(201103);*/


  22. proc sql noprint;
  23.     create table test as
  24.     select t1.IND
  25.     /*这个t1.ind是需要加的,因为我在宏里面输出的是 ,t1~ 如果不加这个会出错,因为SQL的逻辑是两个变量之间用逗号分隔,第一个变量前不加逗号。宏里面可以处理但是我嫌麻烦没写*/
  26.     %m(201103)
  27.     from work.monthly t1
  28.     ;
  29. quit;
复制代码
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
3qsir + 5 + 5 + 5 热心帮助其他会员

总评分: 学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

13
nomad5 发表于 2014-3-10 18:54:06
intheangel 发表于 2014-3-9 09:52
你的table 名到低叫啥啊?t1还是monthly t1 不可能有monthly t1这个table的吧
t1的意思是对monthly进行一个缩写的命名。对于这个程序来说其实没用。如果在SQL中存在两个数据集,例如monthly1  and monthly2,那么我们在select里面需要写monthly1.ind and monthly2.ind, 如果使用的缩写,那么就是t1.ind and t2.ind。简化程序用的。

14
3qsir 发表于 2014-3-10 20:50:55
nomad5 发表于 2014-3-4 14:33
I don't know why you use PROC SQL, and I don't see the raw data.
I only use a macro to instead of y ...
親愛nomad5楼主 : 谢谢您详细的指导
You matbe forget to rename the old variable "201103..." ------->the new variable "K1 K2...K24" like below:
H201103 SASoutcomes:
    IND            K1             K2  .....................K23                   K24
sz1_bm1       0.69          7.47 ....................5.76                  -1.64
sz1_bm2       1.35           7.32 ....................5.77                 -2.35
sz1_bm3       0.81            7.07.................... 5.68                -1.99
sz1_bm4       2.02            6.44.................... 6.87                -1.44
sz1_bm5        0.8             6.42.....................10.22               -2.61
sz2_bm1        1.35            7.53..................... 4.5                  1.2
sz2_bm2         2.39           6.78..................... 5.84              -0.19
--------------------------------------------
t1.'201103'n AS K1,
t1.'201104'n AS K2,
t1.'201105'n AS K3,
t1.'201106'n AS K4,
t1.'201107'n AS K5,
t1.'201108'n AS K6,
t1.'201109'n AS K7,
t1.'201110'n AS K8,
t1.'201111'n AS K9,
t1.'201112'n AS K10,
t1.'201201'n AS K11,
t1.'201202'n AS K12,
t1.'201203'n AS K13,
t1.'201204'n AS K14,
t1.'201205'n AS K15,
t1.'201206'n AS K16,
t1.'201207'n AS K17,
t1.'201208'n AS K18,
t1.'201209'n AS K19,
t1.'201210'n AS K20,
t1.'201211'n AS K21,
t1.'201212'n AS K22,
t1.'201301'n AS K23,
t1.'201302'n AS K24

15
3qsir 发表于 2014-3-10 21:11:18
NO! ,NO! code not run
I try many times ,even no log file and break , Dialuage boxa ppear "[ERROR]Failed to transcode data from utf-16le to ms-950 encoding because it contained characters which are not suppirted bby you sAS session ecoding...."
/*这个宏只考虑了从输入的&v.之后连续性的24个月,另外你在调用的时候出错了。整体的思路是对年和月进行循环。12月的时候年加1。其实是有函数可以实现的。*/

/*另外为什么一定要用SQL呢,DATA步应该有更简单的过程*/


%macro m(v);

%let y=%substr(&v.,1,4);

%let m=%substr(&v.,5,2);

%do i=1 %to 24;

    %let mf=%sysfunc(putn(%eval(&m.+&i.-1),z2.));

    %if &mf.>24 %then %do;

        %let mf=%sysfunc(putn(%eval(&mf.-24),z2.));

        %let yf=%eval(&y.+2);

    %end;

    %else %if &mf.>12 %then %do;

        %let mf=%sysfunc(putn(%eval(&mf.-12),z2.));

        %let yf=%eval(&y.+1);

    %end;

    %else %let yf=&y.;


    ,t1."&yf.&mf."n as K&i.

    /*这里原来多一个分号,是我写错了*/


%end;

%mend m;

/*%m(201103);*/



proc sql noprint;

    create table test as
    select t1.IND
    /*这个t1.ind是需要加的,因为我在宏里面输出的是 ,t1~ 如果不加这个会出错,因为SQL的逻辑是两个变量之间用逗号分隔,第一个变量前不加逗号。宏里面可以处理但是我嫌麻烦没写*/

    %m(201103)

    from work.monthly t1

    ;

quit;

16
3qsir 发表于 2014-3-10 21:28:06
The code also Error (No select and cancel "; "at line 51)
See line 51 : ERROR message
----------------------------------------------
14         GOPTIONS ACCESSIBLE;
15         %macro m(v);
16         
17         %let y=%substr(&v.,1,4);
18         
19         %let m=%substr(&v.,5,2);
20         
21         %do i=1 %to 24;
22         
23             %let mf=%sysfunc(putn(%eval(&m.+&i.-1),z2.));
24         
25             %if &mf.>24 %then %do;
26         
27                 %let mf=%sysfunc(putn(%eval(&mf.-24),z2.));
28         
29                 %let yf=%eval(&y.+2);
30         
31             %end;
32         
33             %else %if &mf.>12 %then %do;
34         
35                 %let mf=%sysfunc(putn(%eval(&mf.-12),z2.));
36         
37                 %let yf=%eval(&y.+1);
38         
39             %end;
40         
41             %else %let yf=&y.;
42         
43         
44             ,t1."&yf.&mf."n as K&i.
45         
46         
47         %end;
48         
49         %mend m;
50         
51         %m(201103);
NOTE: Line generated by the invoked macro "M".
51            ,t1."&yf.&mf."n as K&i.
              _
              180
ERROR 180-322: Statement is not valid or it is used out of proper order.
52         
53         GOPTIONS NOACCESSIBLE;
54         %LET _CLIENTTASKLABEL=;
55         %LET _CLIENTPROJECTPATH=;
56         %LET _CLIENTPROJECTNAME=;
57         %LET _SASPROGRAMFILE=;
58         
59         ;*';*";*/;quit;run;
60         ODS _ALL_ CLOSE;
61         
62         
63         QUIT; RUN;
-------------------------------------------

17
3qsir 发表于 2014-3-13 18:53:55
  
  



亲爱的楼主:因为题目的解答,转贴又臭又长我将您的最后一版(Final SAS code)重发一份问帖起问...因为您给我最后一版的code还是有ERROR先将他close掉 THANKS !



您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群
GMT+8, 2025-12-31 17:30