楼主: gafciausa
9237 6

call symput和call symputn,call symputx的区别 [推广有奖]

  • 1关注
  • 0粉丝

博士生

79%

还不是VIP/贵宾

-

威望
0
论坛币
1 个
通用积分
8.0000
学术水平
1 点
热心指数
1 点
信用等级
1 点
经验
5854 点
帖子
211
精华
0
在线时间
164 小时
注册时间
2014-1-27
最后登录
2023-10-21

相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
请教大神,这三者的区别?
1) 存储形式
2) 字符类型的区别

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:symput call putn put

沙发
realtemper 发表于 2015-6-21 08:00:53 |只看作者 |坛友微信交流群
簡單來說,call symput 與 call symputx 都可以在 data step 當中,將資料寫入 macro variable (宏變量)。語法如下:

  1. call symput(macvar, dsvar);
  2.    
  3. call symputx(macvar, dsvar, "G/L/F");
复制代码


其中 macvar 是想要儲存資料的宏變量名稱。內容可以是 (1) 一個字串(用引號包裹),該字串必須是一個合法的宏變量名稱,或者 (2) 一個字串變量的名稱(不用引號包裹),取該字串變量的「內容」作為宏變量的名稱。

dsvar 是想要存入宏變量的內容。同上理,它也可以是一個引號包裹的字串,或者一個字串變量的名稱。

至於 call symputx 的 "G", "L", "F" 代表宏變量的 scope(如后解釋)。引號為必須。
   "G": global
   "L": local
   "F": the most local macro varialbe(亦即,只要 local 的 macvar 存在,則將 dsvar 之值存到 local macvar 中,global macvar 則不受影響。若不存在,則存入 global 的 macvar。)

這兩者的共同點是:

1.都必須在 data step 之中呼叫(含 data _null_;)
2.都是將字串內容寫入 macro variable,數字則視同字串。
3.都不會自動清除首尾的空白字符。

兩者最大的區別,在於宏變量儲存的 scope。所謂 scope ,就是「變量存在的有效範圍」。宏變量可以依據其 scope 大致分成兩類:一類是 global (全域) 變量,它們會一直存在直到整個 SAS 系統結束運行,因此可以被任意程序在任意位置所使用;另一種是 local (局域) 變量,通常由 macro 當中的 %local 關鍵字所定義(參看後面範例)。它們僅能夠在該 macro 當中使用。一旦 macro 結束運行,其他程序便無從知曉它們的存在。

根據 SAS 9.4 官方文件, call symput 會自動把宏變量儲存在「"most local" "nonempty" symbol table」(最內層的非空符號表)裡頭。所謂 symbol table ,可以想像成是 SAS 用來儲存宏變量的一紙清單,並且不同的 scope 有不同的變量清單。當然,對於那些並不使用 local macro variable 的程式來說,這張「最內層的非空符號表」其實就是指 global symbol table,因此在這種條件下, call symput(macvar, dsvar) 就會等同於 call symputx(macvar, dsvar, "G")。

但是,如果您需要把程式碼封裝成 macro,就應該特別注意 scope 的問題。如果您在一個 macro 裡頭,使用了 call symput,而這個 macro 又剛好使用了 local macro variable,造成 local symbol table 不是空的,那麼您就一定要使用 call symputx(macvar, dsvar, "G") 來創建 global macro variable。否則,如果誤用了 call symput(),就會存成 local macro variable,macro 外面的程式碼是讀不到的。如下範例程序碼所示(註解都寫在裡面了,相信可以望文生義)。

  1. /* the test dataset */
  2. data a;
  3.     input ID $ x;
  4.     datalines;
  5.     A 1
  6.     B 2
  7. ;run;

  8. %macro mac_scope();

  9.     /* make the local symbol table non-empty */
  10.     %local x;
  11.     %let x=1;  /* create a local macro variable x=1 */

  12.     /* assign macro variables using symput() and symputx() */
  13.     data _null_;
  14.         set a;
  15.         call symput('mac', ID);
  16.         call symputx('macx_local', ID, 'L');
  17.         call symputx('macx_global', ID, 'G');
  18.         stop;  /* read the first obs */
  19.     run;

  20.     /* test macvar existence in the local symbol table */
  21.     data _null_;

  22.         if symexist('mac') then put "mac exists locally";
  23.         else put "mac does NOT exist locally";

  24.         if symexist('macx_local') then put "macx_local exists locally";
  25.         else put "macx_local does NOT exist locally";

  26.         if symexist('macx_global') then put "macx_global exists locally";
  27.         else put "macx_global does NOT exist locally";

  28.     run;

  29. %mend mac_scope;

  30. /* macro execution */
  31. %symdel mac macx_local macx_global;  * clear previous results;
  32. %mac_scope();

  33. /* test macvar existence in the global symbol table */
  34. data _null_;

  35.     if symexist('mac') then put "mac exists globally";
  36.     else put "mac does NOT exist globally";

  37.     if symexist('macx_local') then put "macx_local exists globally";
  38.     else put "macx_local does NOT exist globally";

  39.     if symexist('macx_global') then put "macx_global exists globally";
  40.     else put "macx_global does NOT exist globally";

  41. run;
复制代码



執行完畢後,應該能夠看到這樣子的輸出(tested on SAS 9.4 / win7 x64)。

mac exists locally
macx_local exists locally
macx_global exists locally  /* locally 都沒什麼問題 */

mac does NOT exist globally
macx_local does NOT exist globally
macx_global exists globally  /* 很清楚了:當 local symbol table 非空,就只有 call symputx( , , 'G') 才能建立全域宏變量 */



因此個人建議:最好永遠使用 call symputx() 來明確指定宏變量的 scope,並且小心使用全域宏變量。call symput() 則視為過時語法,避免使用。這是因為 SAS 的程序在封裝成 macro 之後,除蟲變得不易,並且程序一大,變量撞名機率的機率便會升高....因此寧可在撰寫程序的時候,多打一個參數,然後多花個幾秒,想想是否真的需要建立一個全域宏變量。否則除蟲的時候就會感慨,偷雞不著蝕把米啊。

最後!差點忘了 call symputn()。它是 SCL (SAS Component Language) 專用的語法,一般的 data step 是不能用的。當然,顧名思義,它是 call symput 的數字版本,可以直接把一個數字(非數字字串)存入宏變量。但如果沒有機會接觸 SCL,直接當這個語法不存在就是了。

參考資料:SAS 9.4 官方說明文件。





已有 6 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
a914972177 + 1 + 1 + 1 精彩帖子
bitcoin + 1 + 1 观点有启发
苹果叶 + 5 + 1 + 1 + 1 精彩帖子
webgu + 100 + 100 + 3 + 3 + 3 精彩帖子
Tigflanker + 3 + 3 + 3 精彩帖子
何必不淡定。 + 2 精彩帖子

总评分: 经验 + 100  论坛币 + 107  学术水平 + 9  热心指数 + 9  信用等级 + 8   查看全部评分

使用道具

藤椅
gafciausa 发表于 2015-6-29 17:18:33 |只看作者 |坛友微信交流群
realtemper 发表于 2015-6-21 08:00
簡單來說,call symput 與 call symputx 都可以在 data step 當中,將資料寫入 macro variable (宏變量)。語 ...
谢谢特别详细!关于数字型的变量可以用以上的三种方法把它赋值为数值型的宏变量吗?是不是宏变量都是字符型的?

使用道具

板凳
realtemper 发表于 2015-7-1 10:24:11 |只看作者 |坛友微信交流群
宏變量都是字符型的。macro processor 基本上就是一種對文字做 copy-paste 的 preprocessor,作用於 sas statements 被 compile 之前,將 macro variables 跟 macro functions 做適當的文字替換。

你可以參考 SAS online tutor: Introducing Macro Variables,內有清楚圖說,要花些時間,但是值得的。

使用道具

报纸
yongyitian 发表于 2015-7-1 21:24:03 |只看作者 |坛友微信交流群
Call symput 和 call symputx 的一个主要区别是:
Call symput  保留首尾的空格
Call symputx 去掉首尾的空格

symput_symputx.GIF
已有 1 人评分学术水平 热心指数 收起 理由
Tigflanker + 3 + 3 分析的有道理

总评分: 学术水平 + 3  热心指数 + 3   查看全部评分

使用道具

地板
Tigflanker 发表于 2015-7-3 10:13:22 |只看作者 |坛友微信交流群
realtemper 发表于 2015-6-21 08:00
簡單來說,call symput 與 call symputx 都可以在 data step 當中,將資料寫入 macro variable (宏變量)。語 ...
这个回复值得推荐,push~

使用道具

7
不是吧258123 发表于 2015-7-3 17:08:55 |只看作者 |坛友微信交流群
realtemper 发表于 2015-6-21 08:00
簡單來說,call symput 與 call symputx 都可以在 data step 當中,將資料寫入 macro variable (宏變量)。語 ...
相当详细啊

使用道具

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

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-5-11 06:05