DATA Step Debugger 全解析
1. 调试与 DATA Step 调试器概述
调试是从程序中消除逻辑错误的过程。与语法错误不同,逻辑错误不会阻止程序运行,但会导致程序产生意外结果。例如,一个用于跟踪库存的 DATA 步骤程序显示库存为零,但仓库实际上满货,这就是程序存在逻辑错误。
调试 DATA 步骤有以下几种方法:
- 将步骤中的几行复制到另一个 DATA 步骤中执行,并打印这些语句的结果。
- 在 DATA 步骤的选定位置插入 PUT 语句,提交步骤并检查 SAS 日志中显示的值。
- 使用 DATA 步骤调试器。
DATA 步骤调试器是 Base SAS 软件的一部分,由窗口和一组命令组成。通过发出命令,可以逐行执行 DATA 步骤语句,并暂停以在窗口中显示结果变量值。通过观察显示的结果,可以确定逻辑错误所在位置。要调用调试器,只需在 DATA 语句中添加 DEBUG 选项并执行程序。
DATA 步骤调试器能实现以下任务:
- 逐行或成组执行语句。
- 绕过一个或多个语句的执行。
- 在选定的语句处暂停执行,可在 DATA 步骤语句的每次迭代中或满足指定条件时暂停,并可根据命令恢复执行。
- 监控选定变量的值,并在值更改时暂停执行。
- 显示变量的值并为其分配新值。
- 显示变量的属性。
- 获取单个调试器命令的帮助。
- 将调试器命令分配给功能键。
- 使用宏工具生成自定义调试器命令。
2. 基本使用方法
2.1 调试会话的工作原理
当提交带有 DEBUG 选项的 DATA 步骤时,SAS 会编译该步骤,显示调试器窗口,并暂停直到输入调试器命令开始执行。例如,使用 GO 命令开始执行,SAS 将执行 DATA 步骤中的每个语句。若要在 DATA 步骤的特定行暂停执行,可使用 BREAK 命令在选定的语句处设置断点,然后发出 GO 命令,GO 命令将启动或恢复执行,直到到达断点。
若要逐行或逐几条语句执行 DATA 步骤,可使用 STEP 命令,默认情况下,STEP 命令映射到 ENTER 键。在调试会话中,DATA 步骤中的语句可以像在调试会话外一样迭代多次。当最后一次迭代完成时,DEBUGGER LOG 窗口会出现一条消息。调试会话结束后,不能重新启动 DATA 步骤的执行,必须在 SAS 会话中重新提交 DATA 步骤,但可以在执行结束后检查变量的最终值。并且一次只能调试一个 DATA 步骤,调试器只能用于 DATA 步骤,不能用于 PROC 步骤。
2.2 使用窗口
DATA 步骤调试器包含两个主要窗口:DEBUGGER LOG 和 DEBUGGER SOURCE 窗口。当执行带有 DEBUG 选项的 DATA 步骤时,这些窗口会出现。
DEBUGGER LOG 窗口记录发出的调试器命令及其结果,最后一行是调试器命令行,用于发出调试器命令,命令行以大于号 (>) 提示符标记。
DEBUGGER SOURCE 窗口包含正在调试的 DATA 步骤的 SAS 语句,该窗口可让你在调试程序时查看在 DATA 步骤中的位置,窗口中的 SAS 语句与 SAS 日志中的行号相同。
可以在窗口命令行输入窗口环境命令,也可以使用功能键执行命令。
2.3 输入命令
在调试器命令行输入 DATA 步骤调试器命令,命令列表和说明可参考“Debugger Commands by Category”。输入命令时需遵循以下规则:
- 命令只能占一行(DO 组除外)。
- DO 组可以跨多行。
- 要输入多个命令,用分号分隔:
examine _all_; set letter='bill'; examine letter
2.4 处理表达式
调试器表达式中所有在“SAS Operators in Expressions”中描述的 SAS 运算符都是有效的,但调试器表达式不能包含函数,且必须在一行内完成,不能跨行。
2.5 将命令分配给功能键
要将调试器命令分配给功能键,打开 Keys 窗口,将光标定位在要分配的功能键的 Definitions 列中,以术语 DSD 开始命令。若要将多个命令分配给一个功能键,需将命令(用分号分隔)括在引号中,并确保保存更改。例如:
-
dsd step3
-
dsd 'examine cost saleprice; go 120;'
3. 高级使用方法:结合宏工具使用调试器
可以使用 SAS 宏工具从 DEBUGGER LOG 命令行调用宏,也可以在调试器命令行定义宏并使用宏程序语句(如 %LET)。
3.1 使用宏作为调试工具
宏可用于存储一系列调试器命令,在 DEBUGGER LOG 命令行执行宏时,会生成整个调试器命令系列。还可以使用带参数的宏根据不同条件构建不同的调试器命令系列。
3.2 使用宏创建自定义调试命令
可以在 DEBUGGER LOG 命令行定义宏来创建自定义调试命令,然后从命令行调用该宏。例如,要检查变量 COST,执行五条语句,然后检查变量 DURATION,可定义如下宏(此例中宏名为 EC):
%macro ec; ex cost; step 5; ex duration; %mend ec;
要发出这些命令,从 DEBUGGER LOG 命令行调用宏 EC:
%ec
需要注意的是,在 DEBUGGER LOG 命令行定义的宏只能在当前调试会话中使用,因为宏不会永久存储。若要创建永久存储的宏,需使用程序编辑器。
3.3 调试由宏生成的 DATA 步骤
使用宏生成 DATA 步骤时,调试可能会比较困难,SAS 日志会显示宏的副本,但不会显示宏生成的 DATA 步骤。若此时使用 DEBUG 选项,宏生成的文本对调试器来说是连续的流,没有执行可以暂停的换行符。
调试由宏生成的 DATA 步骤,可按以下步骤操作:
1. 执行程序时使用 MPRINT 和 MFILE 系统选项。
2. 将文件引用 MPRINT 分配给现有的外部文件,MFILE 会将程序输出路由到外部文件。注意,如果重新运行程序,当前输出会追加到文件中的先前输出之后。
3. 从 SAS 会话中调用宏。
4. 在程序编辑器窗口中,发出 INCLUDE 命令或使用文件菜单打开外部文件。
5. 在 DATA 语句中添加 DEBUG 选项并开始调试会话。
6. 找到逻辑错误后,更正生成该语句的宏部分。
4. 示例
4.1 调试简单的 DATA 步骤
此示例展示了在输出缺失时如何调试 DATA 步骤。
/* first execution */
data tours (drop=type);
input @1 type $ @;
if type='H' then do;
input @3 Tour $20.;
return;
end;
else if type='P' then do;
input @3 Name $10. Age 2. +1 Sex $1.;
output;
end;
datalines;
H Tour 101
P Mary E
21 F
P George S
45 M
P Susan K
3 F
H Tour 102
P Adelle S
79 M
P Walter P
55 M
P Fran I
63 F
;
proc print data=tours;
title 'Tour List';
run;
程序执行时没有错误,但输出不符合预期,输出中不包含变量 Tour 的值。查看 SAS 日志无法帮助调试程序,因为数据有效且日志中没有错误。为了识别逻辑错误,可再次使用 DATA 步骤调试器运行 DATA 步骤。
在 DATA 语句中添加 DEBUG 选项并重新提交 DATA 步骤:
data tours (drop=type) / debug;
执行后会出现两个调试器窗口。在 DEBUGGER LOG 窗口的调试器命令行输入命令。例如,在执行开始前,使用 EXAMINE 命令显示程序数据向量中所有变量的值:
examine _all_
使用 STEP 命令逐行执行 DATA 步骤,在程序的 RETURN 语句在 DEBUGGER SOURCE 窗口中高亮显示时停止。输入 EXAMINE 命令查看第一次迭代中变量 Tour 的值:
examine tour
,结果显示变量 Tour 包含值 Tour 101,说明第一次迭代按预期工作。
使用 BREAK 命令在第 7 行设置断点,暂停执行 ELSE 语句前的执行:
break 7
执行 GO 命令继续执行 DATA 步骤直到到达断点:
go
在第 7 行暂停后,输入 EXAMINE 命令查看所有变量的值:
examine _all_
,发现变量 Tour 没有值,因为程序数据向量在每次迭代开始时会重置为缺失值,所以不会保留 Tour 的值。为解决此逻辑问题,需要在 SAS 程序中包含 RETAIN 语句。
结束调试会话,在调试器命令行发出 QUIT 命令:
quit
更正原始程序,添加 RETAIN 语句,删除 DEBUG 选项并重新提交程序:
/* corrected version */
data tours (drop=type);
retain Tour;
input @1 type $ @;
if type='H' then do;
input @3 Tour $20.;
return;
end;
else if type='P' then do;
input @3 Name $10. Age 2. +1 Sex $1.;
output;
end;
datalines;
H Tour 101
P Mary E
21 F
P George S
45 M
P Susan K
3 F
H Tour 102
P Adelle S
79 M
P Walter P
55 M
P Fran I
63 F
;
run;
proc print;
title 'Tour List';
run;
此时输出中会显示 Tour 的值。
4.2 使用格式时的调试
此示例展示了在使用格式语句格式化日期时如何调试程序。
options yearcutoff=1920;
data tours;
length Country $ 10;
input Country $10. Start : mmddyy. End : mmddyy.;
Duration=end-start;
datalines;
Italy
033000 041300
Brazil
021900 022800
Japan
052200 061500
Venezuela
110300 11800
Australia
122100 011501
;
proc print data=tours;
format start end date9.;
title 'Tour Duration';
run;
程序运行后,委内瑞拉之旅的 Duration 值显示为负数 -290 天。为帮助识别错误,再次使用 DATA 步骤调试器运行 DATA 步骤。
在 DEBUGGER LOG 命令行输入 EXAMINE 命令显示程序数据向量中所有变量的初始值:
examine _all_
按 ENTER 键执行 STEP 命令,SAS 执行 INPUT 语句,赋值语句高亮显示。再次输入 EXAMINE 命令显示当前所有变量的值:
examine _all_
因为委内瑞拉之旅存在问题,在国家名称为委内瑞拉时,在赋值语句前暂停执行,设置断点:
break 6 when country='Venezuela'
执行 GO 命令恢复程序执行:
go
当国家名称为委内瑞拉时,程序停止执行。此时可以检查委内瑞拉之旅的开始和结束日期。因为赋值语句高亮显示(表示 SAS 尚未执行该语句),所以 Duration 没有值。执行 EXAMINE 命令查看执行后变量的值:
examine _all_
若要查看格式化后的 SAS 日期,使用 DATEw. 格式发出 EXAMINE 命令:
examine start date7. end date7.
发现变量 End 存在错误,通过 SET 命令临时将 End 的值设置为 11 月 18 日,使用 DDMMMYYw. 格式发出 SET 命令:
set end='18nov00'd
按 ENTER 键执行 STEP 命令并执行赋值语句,发出 EXAMINE 命令查看旅游日期和 Duration 字段:
examine start date7. end date7. duration
结束调试会话,在 DEBUGGER LOG 命令行发出 QUIT 命令。更正 SAS 程序中的原始数据,删除 DEBUG 选项并重新提交程序:
/* corrected version */
options yearcutoff=1920;
data tours;
length Country $ 10;
input Country $10. Start : mmddyy. End : mmddyy.;
duration=end-start;
datalines;
Italy
033000 041300
Brazil
021900 022800
Japan
052200 061500
Venezuela
110300 111800
Australia
122100 011501
;
run;
proc print data=tours;
format start end date9.;
title 'Tour Duration';
run;
5. 调试器命令
以下是调试器命令的列表及分类:
| 命令 | 作用 |
| ---- | ---- |
| BREAK | 设置断点 |
| CALCULATE | 计算表达式 |
| DELETE | 删除断点 |
| DESCRIBE | 显示变量属性 |
| ENTER | 执行 STEP 命令 |
| EXAMINE | 显示变量值 |
| GO | 开始或恢复执行 |
| HELP | 获取命令帮助 |
| JUMP | 跳转到指定行 |
| LIST | 列出语句 |
| QUIT | 结束调试会话 |
| SET | 设置变量值 |
| STEP | 逐行执行语句 |
| SWAP | 交换变量值 |
| TRACE | 跟踪执行 |
| WATCH | 监控变量值变化 |
通过合理运用这些命令,可以更高效地进行 DATA 步骤的调试工作。在实际调试过程中,根据具体问题灵活选择和组合使用这些命令,能够快速定位并解决逻辑错误和数据错误。同时,结合示例中的调试步骤和方法,不断实践和总结经验,将能更好地掌握 DATA 步骤调试器的使用技巧。
DATA Step Debugger 全解析
6. 调试复杂场景的技巧
在实际应用中,DATA 步骤可能会涉及到复杂的逻辑和数据处理,以下是一些调试复杂场景的技巧。
6.1 嵌套循环的调试
当 DATA 步骤中存在嵌套循环时,调试会变得较为复杂。例如:
data nested_loop;
do i = 1 to 5;
do j = 1 to 3;
value = i * j;
output;
end;
end;
run;
对于这样的嵌套循环,可以使用 BREAK 命令在关键位置设置断点。比如,在内部循环的开始处设置断点:
break 4;
然后使用 GO 命令执行到断点处,再使用 STEP 命令逐行执行内部循环,观察变量的值变化。可以使用 EXAMINE 命令查看变量
i
、
j
和
value
的值:
examine i j value;
通过这样的方式,可以清晰地了解嵌套循环的执行过程,找出可能存在的逻辑错误。
6.2 条件判断的调试
复杂的条件判断语句也可能导致逻辑错误。例如:
data conditional;
input num;
if num > 10 and num < 20 then do;
result = 'In range';
end;
else if num <= 10 then do;
result = 'Below range';
end;
else do;
result = 'Above range';
end;
output;
datalines;
5
15
25
;
run;
可以在每个条件判断语句处设置断点,使用 BREAK 命令:
break 3;
break 6;
break 9;
然后使用 GO 命令执行到断点处,使用 EXAMINE 命令查看变量
num
和
result
的值,判断条件判断是否按预期执行。
7. 调试器的性能优化
在调试大型 DATA 步骤时,调试器的性能可能会受到影响。以下是一些优化调试器性能的方法。
7.1 减少不必要的检查
在调试过程中,避免频繁使用 EXAMINE 命令查看所有变量的值。可以只查看关键变量的值,减少不必要的输出和处理时间。例如,在一个包含大量变量的 DATA 步骤中,只查看与逻辑错误相关的变量:
examine variable1 variable2;
7.2 合理设置断点
避免在 DATA 步骤中设置过多的断点,过多的断点会增加调试器的处理负担。只在关键位置设置断点,例如循环的开始和结束处、条件判断语句处等。
7.3 使用宏进行批量操作
对于一些重复的调试操作,可以使用宏进行批量处理。例如,在每次执行到某个断点后,需要查看多个变量的值,可以定义一个宏:
%macro check_vars;
examine var1 var2 var3;
%mend check_vars;
然后在调试过程中,使用宏来执行这些操作:
%check_vars;
8. 总结与建议
通过前面的介绍,我们了解了 DATA Step Debugger 的基本使用方法、高级使用技巧以及调试复杂场景的方法和性能优化策略。以下是一些总结和建议。
8.1 总结
- DATA Step Debugger 是一个强大的工具,可以帮助我们快速定位和解决 DATA 步骤中的逻辑错误和数据错误。
- 合理使用调试器的命令,如 BREAK、EXAMINE、STEP 等,可以提高调试效率。
- 结合宏工具,可以创建自定义的调试命令,进一步提升调试的灵活性。
8.2 建议
- 在开始调试前,先对程序的逻辑有一个清晰的理解,明确可能存在问题的区域。
- 养成在关键位置设置断点和使用 EXAMINE 命令查看变量值的习惯,这样可以更方便地跟踪程序的执行过程。
- 对于复杂的程序,可以使用流程图来辅助理解程序的逻辑,以下是一个简单的流程图示例:
graph TD;
A[开始] --> B{条件判断};
B -- 条件为真 --> C[执行操作 1];
B -- 条件为假 --> D[执行操作 2];
C --> E[结束];
D --> E;
- 不断实践和总结调试经验,提高自己的调试技能。在遇到问题时,不要急于修改代码,先通过调试器找出问题的根源,再进行针对性的修改。
通过以上的方法和建议,相信你能够更好地掌握 DATA Step Debugger 的使用,提高 DATA 步骤程序的开发和调试效率。
超级会员免费看
29

被折叠的 条评论
为什么被折叠?



