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

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

问题描述

您好,我正在尝试使用 do 循环和 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,.

我的原始代码如下所示:

My original code, which works, looks like this:

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 循环在宏中迭代空格分隔的列表,其上限是列表中单词"的 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 提交系统的源代码.更抽象或工具箱时的宏编码编码过程有时称为codegen.

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_typetype_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.

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

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