楼主: dxystata
681 5

[问答] 传递两个macro变量得到一个新的宏变量 [推广有奖]

版主

已卖:302份资源

大师

37%

还不是VIP/贵宾

-

TA的文库  其他...

Software

中英文Ebook

R学习

威望
2
论坛币
183395 个
通用积分
15333.1475
学术水平
208 点
热心指数
271 点
信用等级
174 点
经验
298627 点
帖子
5586
精华
1
在线时间
13632 小时
注册时间
2006-6-21
最后登录
2025-12-22

初级学术勋章 初级热心勋章 中级热心勋章 初级信用勋章

楼主
dxystata 发表于 2023-7-5 15:00:08 |AI写论文
80论坛币
传递两个macro变量
x为1 2 3 4
ctrl为1 或2 或1 2


希望得到新的宏变量




假设参比ctrl为1,剩下为2 3 4,构造出 一个宏变量为:
                           "2 vs 1"  -1 1 0 0,
                           "3 vs 1" -1 0 1 0,
                           "4 vs 1" -1 0 0 1


假设参比ctrl为2,剩下为1 3 4,构造出 一个宏变量为:
                          "1 vs 2"  1 -1 0 0,
                          "3 vs 2"  0 -1 1 0,
                          "4 vs 2"  0- 1  0 1


假设参比ctrl为1 2,剩下为3 4,构成出一个宏变量为:
                          "3 vs 1" -1 0 1 0,
                          "4 vs 1" -1 0 0 1,
                          "3 vs 2"  0 -1 1 0,
                          "4 vs 2" 0- 1  0 1

关键词:Macro acr CRO Mac Ctrl

沙发
whymath 发表于 2023-7-7 13:54:09
可以借助循环与数组完成:
  1. %macro tri_vs_ctrl(total=,ctrl=);
  2. %local tri;
  3. %global _rst_;
  4. %let tri=%cmpres(%sysfunc(compress(&total,%sysfunc(compress(&ctrl)))));

  5. data _null_;
  6.   array _par_[%sysfunc(countw(&total))]_temporary_;

  7.   length text $1024.;
  8.   do i=%sysfunc(tranwrd(&tri,%str( ),%str(,)));
  9.     do j=%sysfunc(tranwrd(&ctrl,%str( ),%str(,)));
  10.       call missing(of _par_[*]);
  11.       _par_[i]=1;
  12.       _par_[j]=-1;
  13.       text=catx(',',text,quote(cat(i,' vs ',j))||''||catx('',of _par_[*]));
  14.     end;
  15.   end;
  16.   call symputx('_rst_',tranwrd(text,'.','0'));
  17. run;
  18. %mend;
复制代码


调用示例如下:
  1. %tri_vs_ctrl(total=1 2 3 4,ctrl=1);
  2. %put &=_rst_;
  3. _RST_="2 vs 1" -1 1 0 0,"3 vs 1" -1 0 1 0,"4 vs 1" -1 0 0 1

  4. %tri_vs_ctrl(total=1 2 3 4,ctrl=2);
  5. %put &=_rst_;
  6. _RST_="1 vs 2" 1 -1 0 0,"3 vs 2" 0 -1 1 0,"4 vs 2" 0 -1 0 1

  7. %tri_vs_ctrl(total=1 2 3 4,ctrl=1 2);
  8. %put &=_rst_;
  9. _RST_="3 vs 1" -1 0 1 0,"3 vs 2" 0 -1 1 0,"4 vs 1" -1 0 0 1,"4 vs 2" 0 -1 0 1
复制代码


你或许可以完全改用宏语句实现,就更为方便了。
已有 1 人评分经验 学术水平 热心指数 收起 理由
dxystata + 100 + 1 + 1 精彩帖子

总评分: 经验 + 100  学术水平 + 1  热心指数 + 1   查看全部评分

藤椅
dxystata 发表于 2023-7-10 19:39:56
假设参比ctrl为1 2,
ctrl为1,2 3 4
ctrl为2,3 4      (注2和1已比过)
构成出一个宏变量为:
                          "2 vs 1" -1 1 0 0,
                          "3 vs 1" -1 0 1 0,
                          "4 vs 1" -1 0 0 1,
                          "3 vs 2"  0 -1 1 0,
                          "4 vs 2" 0- 1  0 1

板凳
dxystata 发表于 2023-7-10 19:43:23
如果是&x为1 2 3 4,&ctrl为1 或2 或1 2。
当ctrl为1时,需得到的宏变量y为1-2!1-3!1-4
当ctrl为2时,需得到的宏变量y为2-1!2-3!2-4
当ctrl为1 2时,需得到的宏变量y为1-2!1-3!1-4!2-3!2-4

报纸
dxystata 发表于 2023-8-3 14:44:14

地板
AngleeZZ 发表于 2023-8-25 21:55:24
参考whymath的code,稍微修改了点code如下,
%macro tri_vs_ctrl(total=,ctrl=);
%local tri;
%global _rst_;
%let tri=&total.;
%let _rst_=;
%do i=1 %to %sysfunc(countw(&ctrl));
  %let num_i = %scan(&ctrl, &i);
  %let tri=%cmpres(%sysfunc(compress(&tri,%sysfunc(compress(&num_i)))));
  %do j=1 %to %sysfunc(countw( &tri ));
    %let num_j = %scan(&tri, &j);
    data _NULL_;
      length text $1024.;
      text=catx('!', "&_rst_.", catx('-', &num_i, &num_j));
      call symputx('_rst_',text);
    run;
  %end;
%end;
%put &=_rst_;
%mend;

结果
%tri_vs_ctrl(total=1 2 3 4,ctrl=1);
output: _RST_=1-2!1-3!1-4

%tri_vs_ctrl(total=1 2 3 4,ctrl=2);
output:_RST_=2-1!2-3!2-4

%tri_vs_ctrl(total=1 2 3 4,ctrl=1 2);
ouptut:_RST_=1-2!1-3!1-4!2-3!2-4

已有 1 人评分经验 热心指数 收起 理由
dxystata + 100 + 1 热心帮助其他会员

总评分: 经验 + 100  热心指数 + 1   查看全部评分

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

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