loops - do循环中的SAS if语句
问题描述
您好我正在尝试使用 do 循环和 if 语句编写宏函数。我想我搞砸了 if-then do 和 do 循环,我无法找出问题所在。我有一张儿童信息表,其中包含年龄、性别、运动、乐器等列。
我的原始代码有效,如下所示:
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;
我有一堆要编辑类型和名称的乐器。我想编写一个循环来自动执行此操作,但我不确定为什么下面的代码不起作用。
%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.
谁能回答我的问题?谢谢!
解决方案
宏变量instrm
实际上是一个包含以空格分隔的变量名称列表的值。您最好从特定的变量使用角色中抽象出来并回退到更通用的参数名称vars
。此外,与其依赖在全局或包含范围内定义的宏变量,不如在调用期间传入列表。你是正确的,一个空格分隔的列表可以在宏中迭代一个%do
循环,其上限是countw
列表中“单词”的数量——你的语法只有一点点。
你不必宏观化一切,运动逻辑的额外宏观化走得很远。请记住,宏调用会发出(或生成)输入 SAS 提交系统的源代码。更抽象或工具箱时的宏编码编码过程有时称为codegen。
您的原始代码可能有问题,因为您评估(在一行中)多个特殊的孩子变量并对相同的 2 个变量(talent_type
和type_name
)执行值分配,因此可能会覆盖先前分配的值。有时,这样的评估和分配是OUTPUT
分开的行。
%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)
总而言之,在开始宏编码之前,请确保您的数据整形和评估处理方法是坚如磐石的。如果你问自己我应该宏这个吗?,保守一点,回答不。对维护者和未来的自己友好,不要让事情变得过于复杂。
推荐阅读
- php - 关闭电子邮件地址的多个 WordPress 菜单项
- openedge - 带有 Web 服务的 PASOE 业务类实体中带有令牌的自定义标头?
- html - 简单的电子邮件 CSS 显示与浏览器中的不同
- python - Python CGI 脚本根本不渲染
- ios - 在 iOS 10 上的 WKWebView 中打开 PDF 文件时启用捏合缩放手势
- gitlab - 我笔记本电脑上的 Gitlab CI 运行程序无法执行 ci,因为它无权访问 CI_XXX 环境变量
- javascript - jQuery:如何获取选定单元格的列和行标题
- python - 使用贝塞尔曲线的平滑 2d 布朗步走
- azure - 创建资源组并部署资源
- laravel - Laravel 计数 > 其他计数