sas宏索引还是其他?

发布于 2024-08-04 14:42:26 字数 1358 浏览 7 评论 0原文

我想为其迭代 169 个城镇的宏。我需要使用城镇名称(而不是城镇代码)保存输出文件。我有一个包含城镇代码和城镇名称的数据集(TOWN)。是否可以将 %let 语句设置为每次迭代的城镇名称(其中 i=town-code)?

我知道我可以使用索引函数列出城镇名称,但我想要一种设置索引函数的方法,以便它将 %let 语句设置为 TOWN.town-name当 i=TOWN.town-code 时。


下面的所有答案似乎都是可能的。我现在使用了 %let = %scan( ,&i) 选项。一个限制是城镇名称可以超过一个单词,因此我用下划线替换了空格,稍后进行更正。

这是我的宏。我输出了 169 个城镇中每个城镇的 proc 报告。我需要将 Excel 文件保存为城镇名称,并让标题包含城镇名称。然后,在 Excel 中,我将所有 169 个工作表合并到一个工作簿中。

%MACRO BY_YEAR;

    %let townname=Andover Ansonia Ashford Avon ... Woodbury Woodstock;

    %do i = 1999 %to 2006;

    %do j = 1 %to 169;

    %let name = %scan(&townname,&j); 

    ods tagsets.msoffice2k file="&ASR.\Town_Annual\&i.\&name..xls" style=minimal;


    proc report data=ASR nofs nowd split='/';
    where YR=&i and TWNRES=&j;
      column CODNUM AGENUM  SEX,(dths_sum asr_sum seasr_sum);
      define CODNUM / group     ;
      define agenum / group     ;
      define sex / across ;
      define dths_sum / analysis ;
      define asr_sum / analysis ;
      define seasr_sum / analysis ;
      break after CODNUM / ul;
      TITLE1 "&name Resident Age-Specific Mortality Rates by Sex, &i";
      TITLE2 "per 100,000 population for selected causes of death";
    run;

    ods html close;

    %end;

    %end;

%MEND;

I have 169 towns for which I want to iterate a macro. I need the output files to be saved using the town-name (rather than a town-code). I have a dataset (TOWN) with town-code and town-name. Is it possible to have a %let statement that is set to the town-name for each iteration where i=town-code?

I know that I can list out the town-names using the index function, but I'd like a way to set the index function so that it sets a %let statement to the TOWN.town-name when i=TOWN.town-code.


All the answers below seem possible. I have used the %let = %scan( ,&i) option for now. A limitation is that the town names can be more than one word, so I've substituted underscores for spaces that I correct later.

This is my macro. I output proc report to excel for each of the 169 towns. I need the excel file to be saved as the name of the town and for the header to include the name of the town. Then, in excel, I merge all 169 worksheets into a single workbook.

%MACRO BY_YEAR;

    %let townname=Andover Ansonia Ashford Avon ... Woodbury Woodstock;

    %do i = 1999 %to 2006;

    %do j = 1 %to 169;

    %let name = %scan(&townname,&j); 

    ods tagsets.msoffice2k file="&ASR.\Town_Annual\&i.\&name..xls" style=minimal;


    proc report data=ASR nofs nowd split='/';
    where YR=&i and TWNRES=&j;
      column CODNUM AGENUM  SEX,(dths_sum asr_sum seasr_sum);
      define CODNUM / group     ;
      define agenum / group     ;
      define sex / across ;
      define dths_sum / analysis ;
      define asr_sum / analysis ;
      define seasr_sum / analysis ;
      break after CODNUM / ul;
      TITLE1 "&name Resident Age-Specific Mortality Rates by Sex, &i";
      TITLE2 "per 100,000 population for selected causes of death";
    run;

    ods html close;

    %end;

    %end;

%MEND;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伪心 2024-08-11 14:42:26

我的猜测是,您想要通过城镇索引查找城镇名称的原因是重复调用每个城镇名称的宏。如果真是这样的话,那你根本就没有必要涉足城镇指数业务。只需用每个城镇名称调用宏即可。有很多方法可以做到这一点。这是使用调用execute()的一种方法。

data towns;
  infile cards dlm=",";
  input town :$char10. @@;
cards;
My Town,Your Town,His Town,Her Town
;
run;

%macro doTown(town=);
  %put Town is &town..;
%mend doTown;

/* call the macro for each town */
data _null_;
  set towns;
  m = catx(town, '%doTown(town=', ')');
  call execute(m);
run;

/* on log
Town is My Town.
Town is Your Town.
Town is His Town.
Town is Her Town.
*/

如果您确实需要进行表查找,那么一种方法是将城镇名称转换为数字格式,并编写一个简单的宏来检索名称(给定索引值)。像这样的东西:

data towns;
  infile cards dlm=",";
  input town :$char10. @@;
cards;
My Town,Your Town,His Town,Her Town
;
run;

/* make a numeric format */
data townfmt;
  set towns end=end;
  start = _n_;
  rename town = label;
  retain fmtname 'townfmt' type 'n';
run;
proc format cntlin=townfmt;
run; 

%macro town(index);
  %trim(%sysfunc(putn(&index,townfmt)))
%mend town;

%*-- check --*;
%put %town(1),%town(2),%town(3),%town(4);
/* on log
My Town,Your Town,His Town,Her Town
*/

My guess is that the reason why you want to look up the town name by town index is to repeatedly call a macro with each town name. If this is the case, then you don't even need to get involved with the town index business at all. Just call the macro with each town name. There are many ways to do this. Here is one way using call execute().

data towns;
  infile cards dlm=",";
  input town :$char10. @@;
cards;
My Town,Your Town,His Town,Her Town
;
run;

%macro doTown(town=);
  %put Town is &town..;
%mend doTown;

/* call the macro for each town */
data _null_;
  set towns;
  m = catx(town, '%doTown(town=', ')');
  call execute(m);
run;

/* on log
Town is My Town.
Town is Your Town.
Town is His Town.
Town is Her Town.
*/

If you do need to do a table lookup, then one way is to convert your town names into a numeric format and write a simple macro to retrieve the name, given an index value. Something like:

data towns;
  infile cards dlm=",";
  input town :$char10. @@;
cards;
My Town,Your Town,His Town,Her Town
;
run;

/* make a numeric format */
data townfmt;
  set towns end=end;
  start = _n_;
  rename town = label;
  retain fmtname 'townfmt' type 'n';
run;
proc format cntlin=townfmt;
run; 

%macro town(index);
  %trim(%sysfunc(putn(&index,townfmt)))
%mend town;

%*-- check --*;
%put %town(1),%town(2),%town(3),%town(4);
/* on log
My Town,Your Town,His Town,Her Town
*/
遗弃M 2024-08-11 14:42:26

或者将代码和名称作为参数传递给宏怎么样?像这样?

%MACRO DOSTUFF(CODE=, NAME=);
DO STUFF...;
PROC EXPORT DATA=XYZ OUTFILE="&NAME."; RUN;
%MEND;

DATA _NULL_;
SET TOWNS;
CALL EXECUTE("%DOSTUFF(CODE=" || STRIP(CODE) || ", NAME=" || STRIP(NAME) || ");");
RUN;

Or how about you just pass both the code and the name to the macro as parameters? Like this?

%MACRO DOSTUFF(CODE=, NAME=);
DO STUFF...;
PROC EXPORT DATA=XYZ OUTFILE="&NAME."; RUN;
%MEND;

DATA _NULL_;
SET TOWNS;
CALL EXECUTE("%DOSTUFF(CODE=" || STRIP(CODE) || ", NAME=" || STRIP(NAME) || ");");
RUN;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文