应用循环迭代重新编码基于宏变量的变量(调用symput / symget)

时间:2017-08-26 19:12:01

标签: loops macros sas recode

我有一个看起来像这样的数据集,我将其称为data1:

data1

当dv = 0时,我想将ss,out1和out2变量的值重新编码为dv = 0时每个“var”组中的值。我想要的结果数据集看起来像这样,我们称之为data2:

data2

我能够使用以下代码获得结果:

data _null_; 
    set data1;
     if dv=0 then do;
  if var=0 then call symput("out1_0",out1);
  if var=0 then call symput("out2_0",out2);
  if var=0 then call symput("ss_0",ss);

  if var=1 then call symput("out1_1",out1);
  if var=1 then call symput("out2_1",out2);
  if var=1 then call symput("ss_1",ss);

  if var=2 then call symput("out1_2",out1);
  if var=2 then call symput("out2_2",out2);
  if var=2 then call symput("ss_2",ss);

  if var=3 then call symput("out1_3",out1);
  if var=3 then call symput("out2_3",out2);
  if var=3 then call symput("ss_3",ss);

  if var=4 then call symput("out1_4",out1);
  if var=4 then call symput("out2_4",out2);
  if var=4 then call symput("ss_4",ss);
     end;
run;

data data2; set data1;
    if dv=1 then do;
  if var=0 then out1=symget("out1_0");
  if var=0 then out2=symget("out1_0");
  if var=0 then ss=symget("ss_0");

  if var=1 then out1=symget("out1_1");
  if var=1 then out2=symget("out2_1");
  if var=1 then ss=symget("ss_1");

  if var=2 then out1=symget("out1_2");
  if var=2 then out2=symget("out2_2");
  if var=2 then ss=symget("ss_2");

  if var=3 then out1=symget("out1_3");
  if var=3 then out2=symget("out2_3");
  if var=3 then ss=symget("ss_3");

  if var=4 then out1=symget("out1_4");
  if var=4 then out2=symget("out2_4");
  if var=4 then ss=symget("ss_4");
    end;
 run;

我想知道是否有更有效的方法来做到这一点?例如,如果“var”变量的值在0到20之间,而不是在这个例子中从0到4,那么我想根据“var”的级别数使用循环来重新编码。

非常感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

你根本不应该使用宏变量。您可以将数据与自身连接,并根据DV的值选择适当的值。

case class User(name: String, address: String)

class UserService {
  def callExternalService(user: User): Result = ???
}

val testUser = User("somebody", "somewhere")
val mockService = mock[UserService]
when(mockService.callExternalService(testUser)).thenReturn(...)

如果你确实想要生成很多宏变量,你可以通过从VAR的值动态生成宏变量名来节省大量的重复编码。

proc sql ;
  create table data2 as 
    select a.var
         , a.dv
         , case when (a.dv=1) then b.out1 else a.out1 end as out1
         , case when (a.dv=1) then b.out2 else a.out2 end as out2
         , case when (a.dv=1) then b.ss else a.ss end as ss
    from data1 a 
    left join (select * from data1 where dv=0) b
    on a.var = b.var 
  ;
quit;