R程序调试
目录
一、 调试方法介绍
a) 作为一种编程语言,掌握 R 的调试方法是一项必备的能力。我今天讨论一下调试 R 程序的一些简单方法,有问题请拍砖。
b) 一般来讲,对于一段有 Bug 的程序,可以表现为执行逻辑和作者的思路不相一致,如果我是作者,我希望的运行方式肯定与程序的运行方式不同,才造成最终结果不是我想要的。通过调试可以找到一些线索,对我的想法加以证实,最终实现我想要的程序。
c) R 中比较简单的调试工具包括 debug() 和 browser() 。
二、 调试函数
a) debug() 主要是用来调试某个函数,主要包括 debug 、 debugonce 、 undebug 、 isdebugged 。当使用 debug(f) 时,会为 f 函数设置 debug 状态,这样每次调用函数 f 时,都会自动进入 browser 提示符环境。
b) browser() 主要用来激活 R 的调试窗口。当函数体中包含 browser 时,执行会暂停在 browser() 所处的表达式,并允许用户访问 R 解释器解释自定义表达式。在 browser 提示符环境下,用户可以输入命令或者 R 变量,如 c 或 cont 表示 continue , f 表示 finish , help 输出支持命令列表, n 表示 next , s 表示 step , where 会打印当前函数调用栈信息, Q 会退出 browser 提示符环境。
c) debug() 函数启动的调试窗口和 browser() 的调试窗口一样。在 browser 提示符环境下,会出现“ Browse[d]> ”提示符,其中, d 表示调用链的深度,即调用堆栈深度。另外,要注意的是,上一段描述的作为命令的关键字,不要用来作为普通变量名,因为不会被覆盖。
三、 调试举例
现在我们来讲一个例子:
找出给定的数字串中,长度为给定值的 1 的子串的起始位置,比如有一串数字为( 1 , 0 , 0 , 1 , 1 , 1 , 0 , 1 , 1 ),这个数字串中长度为 2 的 1 的子串的起始位置为 4 、 5 、 8 。我们可以使用如下代码
图 1 正确的代码
按照题意, findruns(c(1,0,0,1,1,1,0,1,1),2) 的结果应该是 (4,5,8) 。
如果我们修改了第 4 行,变成如下代码
图 2 错误的代码
这时, findruns(c(1,0,0,1,1,1,0,1,1),2) 得到的结果就是 (4,5) 。
显然,这是有错误的,我们通过 debug(findruns) 来设置 findruns() 的 debug 状态,然后调用 findruns(c(1,0,0,1,1,1,0,1,1),2) 来激活 browser 提示符环境,即可进行调试并验证,确定第 4 行的错误后, undebug(findruns) 即可。