【问题标题】:Get the ith word in a macro variable list获取宏变量列表中的第 i 个单词
【发布时间】:2015-08-01 10:26:40
【问题描述】:
%let TableList = TableA TableH TableB TableG;

&TableList 中的单词以' ' 分隔。

我如何检索某些单词来执行以下操作?

我不知道tablelist 中的单词数,想从列表中获取第n 个单词。

给定i = 4

data &&table&i.; /* &&table&i. will resolve to TableG */
set have;
[..];
run;

【问题讨论】:

  • 你是如何生成 &TableList 的?答案可能在于您如何生成它。
  • 我认为&TableList 只是由%let 声明定义的。
  • 你只是在输入吗?那为什么不输入多个 let 语句(对于 table1 table2 table3 table4)? (另外,如果可以的话,弄清楚如何不输入它 - 从数据中派生出来。数据驱动的编程更容易管理。)

标签: macros sas


【解决方案1】:

如果您这样做是为了从列表中即时选择一个单词,您应该只制作一个宏,而不是尝试设置宏变量。与单行宏相比,制作各种宏变量需要做太多额外的工作。

%let tableList=TableA TableB TableC TableD;

%macro selectTable(k=);
  %scan(&tablelist,&k)
%mend selectTable;

data %selectTable(k=4);
  set sashelp.class;
run;

【讨论】:

    【解决方案2】:

    简短的回答是使用%scan函数:

    %put %scan(&tablelist,4,%str( ));
    

    第三个参数指定%scan 应该只计算空格作为分隔符。否则,它还将默认将以下所有字符视为分隔符:

    . < ( + & ! $ * ) ; ^ - / , % |
    

    鉴于您拥有的列表,您可以使用%do 循环将宏变量添加到列表中:

    /* initialise a counter macro variable */
    %let k = 1;
    
    /* iterate through tablelist until a value is not found */
    %do %until (%scan(&tablelist,&k,%str( )) = );
      %let table&k = %scan(&tablelist,&k,%str( )); 
      %let k = &k + 1;
    %end;
    
    %let i = 4;
    %put &&table&i;
    

    注意此代码仅适用于宏定义(即由%macro%mend 语句分隔的代码块。

    【讨论】:

    • 如果不知道列表中的字数,如何获得最后一个字?
    • 循环结束时,&k的值会比单词数大一。
    【解决方案3】:

    我会做与@mjsqu 相同的%sysfunc(scan) 技巧并回答你剩下的问题 - 因为你不知道列表中的单词数量,所以我能想到的最简单的方法是得到最后一个单词正在使用array,如下所示

    %let all=word1 word2 word3 word4 word5;
    
    %macro test;
    data _NULL_;
    array x[*] &all.;
    Num=dim(x);
    call symput("Num_of_words",num);
    run;
    %mend;
    %test;
    

    现在您知道了单词的总数,因此也可以找出最后一个单词。

    【讨论】:

    • countw 更简单。 %让所有=字1字2字3字4字5; %let num=%sysfunc(countw(&all)); %put &num;
    • 确实如此。把它作为替代品。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-21
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多