美文网首页SAS学习笔记
SAS函数:试用scan、%scan和%qscan

SAS函数:试用scan、%scan和%qscan

作者: RSP小白之路 | 来源:发表于2023-02-08 15:12 被阅读0次

为了弄清楚scan、%scan和%qscan使用,分情况试一试。通过试错进行学习。

在data步中使用scan、%scan和%qscan分别会出现什么情况。

/*课后活动信息*/
proc delete data = work._ALL_; quit;
/*case 1:data步*/
data _test;
    length group $200.;
    group="课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋";
    proc print;
run;
test数据集打印结果
  1. 试试第一种子情况。
    如果想获得球类运动相关数据。

/*subcase1 分隔符为字符串,将scan分别替换为%scan、%qscan*/
data _test0;    
    set _test;
    group1 = scan(scan(group, 2,"|"), 3,"\");        
    proc print;
run;

data _test1;   
    set _test;
    group1 = %scan(%scan(group, 2,"|"), 3,"\");    
    proc print;
run;

data _test2;    
    set _test;
    group1 = %qscan(%qscan(group, 2,"|"), 3,"\");          
    proc print;
run;
  • 日志信息:
使用%scan日志 使用%qscan日志
  • 输出结果:
    使用scan有数据集输出;其他无正常输出。
  • print结果:
    只有使用scan会有结果输出。


    _test0
  1. 试试第二种子情况。
/*subcase2: 分隔符去掉引号,将scan分别替换为%scan、%qscan */
proc delete data = work._ALL_; quit;
dm ' log; clear;  odsresult;clear;  output; clear; ';
data _test;
    length group $200.;
    group="课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋";
    proc print;
run;

data _test1_;    
    set _test;
    group1 = %scan(%scan(group, 2,|), 3,\);            
    proc print;
run;

data _test2_;    
    set _test;
    group1 = %qscan(%qscan(group, 2,|), 3,\);          
    proc print;
run;
  • 日志信息:
    scan第三个参数不加引号肯定报错,不予考虑;其他两种和1类子情况一样的报错
  • 输出信息:
    错误。
  • print结果:
    无。
  1. 试试第三种子情况。
/*subcase3:赋值宏变量,将scan分别替换为%scan、%qscan */
proc delete data = work._ALL_; quit;
dm ' log; clear;  odsresult;clear;  output; clear; ';
data _test;
    length group $200.;
    group="课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋";
    proc print;
run;

%let  pos2 = 2 ;
%let  pos3 = 3 ; ;
%let hor = |;
%let slash = \;
%let group=课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋;

data _test0_;  
    set _test;
    group1 = scan(scan(&group., %eval(&pos2.),&hor.),%eval(&pos3.),&slash.);           
    proc print;
run;

data _test1_;  
    set _test;
    group1 = %scan(%scan(&group., %eval(&pos2.),&hor.), %eval(&pos3.),&slash.);        
    proc print;
run;

data _test2_;   
    set _test;
    group1 = %qscan(%qscan(&group., %eval(&pos2.),&hor.), %eval(&pos3.) ,&slash.);        
    proc print;
run;
  • 日志信息:
3种相同错误信息
  • 输出信息:
    错误

  • print结果:
    错误

  • 原因分析

A Little SAS书籍截图

宏变量赋值时使用scan、%scan和%qscan

  1. 试试第一种子情况。
/*subcase1 分隔符为字符串,将scan分别替换为%scan、%qscan*/
%let group1 = scan(scan("课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋", 2,'|' ), 3,'\');
%put &group1;

%let group2 = %scan(%scan("课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋", 2,'|' ), 3,'\');
%put &group2;

%let group3 = %qscan(%qscan("课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋", 2,'|' ), 3,'\');
%put &group3;
  • 日志信息
日志错误信息

2.1 情况:分隔符去掉引号。

/*subcase2.1  分隔符去掉引号,将scan分别替换为%scan、%qscan*/
%let group1 = scan(scan("课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋", 2,|), 3,\);
%put &group1;

%let group2 = %scan(%scan("课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋",2,|), 3,\);
%put &group2;

%let group3 = %qscan(%qscan("课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋", 2,|), 3,\);
%put &group3;
  • 日志信息
日志错误信息

2.2 情况:第一个参数引号移除

/*subcase2.1  引号都去掉,将scan分别替换为%scan、%qscan*/
%let group9 = scan(scan(课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋, 2,|), 3,\);
%put &group9;

%let group8 = %scan(%scan(课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋,2,|), 3,\);
%put &group8;

%let group7 = %qscan(%qscan(课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋, 2,|), 3,\);
%put &group7;
  • 日志
日志信息
  • 说明
    scan:scan作为字符保留,而没有作为函数进行编译运行,这个等号后内容作为整体赋值;
    %scan和%qscan作为宏函数发挥了作用,编译和运行,将所需要的值赋给了目标宏变量。
  1. 试试第三种子情况。
/*subcase3:赋值宏变量,将scan分别替换为%scan、%qscan */
%let  pos2 = 2 ;
%let  pos3 = 3 ; ;
%let hor = |;
%let slash = \;
%let group=课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋;


%let group1 = scan(scan(&group., %eval(&pos2.),&hor.),%eval(&pos3.),&slash.);     
%put &group1;
 
%let group2 = %scan(%scan(&group., %eval(&pos2.),&hor.), %eval(&pos3.),&slash.);    
%put &group2;
 
%let group3 = %qscan(%qscan(&group., %eval(&pos2.),&hor.), %eval(&pos3.) ,&slash.);        
%put &group3;
  • 日志信息
日志信息
  • 说明
    scan:提前赋值的宏变量进行了解析替换,但是scan作为字符保留,而没有作为函数进行编译运行;
    %scan和%qscan均正确进行了替换,编译和运行,将所需要的值赋给了目标宏变量。

在宏中使用scan、%scan和%qscan

此处只讨论在宏里面的data步中的情况,主要看看宏中的data步中%scan和%qscan的情况。至于赋值问题,基础代码和宏代码中情况应该是一致的。

*取出球类运动相关数据;
data _test;
    length group $200.;
    group="课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋";
    proc print;
run;
/*subcase1 分隔符为字符串,将scan分别替换为%scan、%qscan*/
data _test0;    
    set _test;
    group1 = scan(scan(group, 2,"|"), 3,"\");        
    proc print;
run;

data _test1;   
    set _test;
    group1 = %scan(%scan(group, 2,"|"), 3,"\");         
    proc print;
run;

data _test2;    
    set _test;
    group1 = %qscan(%qscan(group, 2,"|"), 3,"\");         
    proc print;
run;
  • 日志
错误信息
  • 说明
    scan有正确的输出结果。

  • 去掉第三个参数的引号

dm ' log; clear;  odsresult;clear;  output; clear; ';
%macro test();
    *取出球类运动相关数据;
data _test;
    length group $200.;
    group="课外活动|书法绘画@硬笔书法@软笔书法@中国画@素描@油画\音乐@吉他@钢琴@竖笛@古筝@口琴\球类运动@乒乓球@羽毛球@篮球@足球@排球\棋类运动@围棋@中国象棋@国际象棋";
    proc print;
run;

/*subcase1 引号去掉,将scan分别替换为%scan、%qscan*/
data _test0;    
    set _test;
    group1 = scan(scan(group, 2,|), 3,\);        
    proc print;
run;

data _test1;   
    set _test;
    group1 = %scan(%scan(group, 2,|), 3,\);         
    proc print;
run;

data _test2;    
    set _test;
    group1 = %qscan(%qscan(group, 2,|), 3,\);         
    proc print;
run;
%mend;

%test();
  • 日志
日志报错信息

可见此种情况下,data步中scan适用,但是%scan和%qscan依然有报错并且和基础代码中报错一样。

总结

在data步中scan适用,在宏变量赋值时如果需要进行scan功能的函数运算,需要使用%scan和%qscan。

相关文章

网友评论

    本文标题:SAS函数:试用scan、%scan和%qscan

    本文链接:https://www.haomeiwen.com/subject/cqarcdtx.html