SAS if语句在do循环中 [英] SAS if statement in do loop

查看:321
本文介绍了SAS if语句在do循环中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用do loop和if语句编写宏函数.我想我搞砸了if-then do和do循环,但我无法弄清问题所在.我有一张儿童信息表,其中包含年龄,性别,运动,乐器等列.

Hi I am trying to write a macro function with do loop and if statement. I think I have messed up the if-then do and do loop and I can't figure out the problem. I have a table of kids information, which contains columns like age, gender, sports, instruments etc,.

有效的原始代码如下:

data old;
   set new;
   if sports in ("football","basketball") and age <=7 then type =1;
      else if sports='swimming' then type=2;
   if special_kid=. then do;
     if piano ^=. and piano_1 ^=. then do; talent_type=1; type_name=piano_1; end;
     if violin ^=. and violin_1 ^=. then do; talent_type=1; type_name=violin_1; end;
   end;
 run;

我有一堆要编辑类型和名称的乐器.我想编写一个循环来自动执行此操作,但是我不确定为什么下面的代码不起作用.

I have a bunch of instruments that I want to edit the type and name. I want to write a loop to automatically do it, but I am not sure why the codes below doesn't work.

%let instrm = piano violin;
%macro my_func;
   data old;
   set new;
   %if sports in ("football","basketball") and age <=7 %then type =1;
      %else %if sports='swimming' %then type=2;
   %do %while (special_kid=.);
      %do i % to sysfunc(countw(&instrm));
          %let word = %scan(&name, &i);
          %if &word ^=. and ^word._1 ^=. %then %do;
          talent_type=1; type_name=&word._1;
          %end;
     %end;
  %end;
run;
%mend;

它不断给我错误

 ERROR: An unexpected semicolon occurred in the %DO statement.
 ERROR: A dummy macro will be compiled.

有人可以回答我的问题吗?谢谢!

Can anyone please answer my question? Thanks!

推荐答案

宏变量 instrm 实际上是一个包含空格的变量名列表的值.您最好从特定的变量使用角色抽象而回退到更通用的参数名称 vars .另外,不要依赖全局或包含范围中定义的宏变量,而应在调用过程中将列表传递给它.您是正确的,可以在宏中使用%do 循环迭代以空格分隔的列表,其上限为列表中'words'的 countw 个数--您的语法只有一点点不足.

The macro variable instrm is really a value containing a space separated list of variable names. You might be better off abstracting away from the specific variable use role and fallback to a more generic parameter name vars. Also, rather than relying on a macro variable defined in a global or encompassing scope, pass the list in during invocation. You are correct that a space separated list can be iterated over in macro with a %do loop with a top limit that is the countw number of 'words' in the list--your syntax is only a little off.

您不必全部进行宏化,并且运动逻辑的额外宏观化已到了极致.请记住,宏调用会发出(或生成)源代码,该源代码将馈入SAS提交系统.宏编码的编码过程有时更加抽象或带有工具箱,有时称为代码生成.

You don't have to macro-ize everything, and the extra macroification of the sports logic went to far. Remember, macro invocations emit (or generates) source code that feeds into the SAS submit system. The macro coding coding process when more abstract or toolboxy is sometimes referred to as codegen.

您的原始代码可能有误,因为您(在一行中)评估了多个特殊的孩子变量,并对相同的2个变量( talent_type type_name )执行了赋值操作因此可能会覆盖先前分配的值.有时,这样的评估和分配是 OUTPUT 来分隔行.

Your original code may be faulty because you evaluate (in a single row) multiple special kid variables and perform value assignments to the same 2 variables (talent_type and type_name) and thus may overwrite a value previously assigned. Sometimes, such evaluations and assignments are OUTPUT to separate rows.

%macro my_skill_classifier(data=, out=, special_vars=, special_type=);
   %local i var;

   data &out;
   set &data;

   if sports in ("football","basketball") and age <=7 then type = 1;
   else
   if sports='swimming' then type=2;

   * what happens to football/baskeball > 7yr ?;

   if missing(special_kid) then do;
      %do i = 1 %to sysfunc(countw(&special_vars));
        %let var = %scan(&special_vars, &i);

        * regular data step code with macro resolutions sprinkled in;
        if &var ^=. and var._1 ^=. then do; 
          talent_type = &special_type;
          type_name = &var._1;
          * maybe you really mean type_name = "&var._1";
        end;
      %end; %* end loop over special_vars list;
    end;
  run;
%mend;

%my_skill_classifier(data=new, out=old, special_vars=piano violin, special_type=1)

长期以来,在开始宏编码之前,请确保您的数据成形和评估处理方法牢不可破.如果您问自己我应该宏此吗?,请保守一些,然后回答否".对维护者和未来自我友好,不要过分复杂.

In long, make sure your data shaping and evaluation processing methodology is rock solid before starting your macro coding. If you ask yourself Should I macro this?, be conservative and answer no. Be friendly to maintainers and future-self by not over complicating things.

这篇关于SAS if语句在do循环中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆